// type ChatLayoutProps = {}

import { useEffect, useMemo, useRef, useState } from "react"

import {
  FlexContainer,
  Spinner,
  Typography,
} from "@/components/shared/components"
import { useMarkdownProcessor } from "@/hooks/useMarkdownProcessor"
import ConsoleIcon from "@/icons/ConsoleIcon"
import MorphoIcon from "@/icons/MorphoIcon"
import { useThemeContext } from "@/providers/themeProvider"

import { ChatMessage, OPEN_DEPOSIT_MODAL_PROMPT } from "../../hooks/useAiChat"
import {
  extractObjectFromAiResponse,
  removeMatchingJSON,
  removeSectionAndJson,
} from "@/utils"
import SlideInAnimationWrapper from "@/components/shared/components/SlideInAnimationWrapper"
import * as S from "./styles"

type MessageProps = ChatMessage

export default function ChatLayout({
  loading,
  messages,
  onChoicePromptClick,
}: {
  messages: MessageProps[]
  loading: boolean
  onChoicePromptClick: (prompt: string) => void
}) {
  const { theme } = useThemeContext()

  const scrollWrapperRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (scrollWrapperRef.current) {
      scrollWrapperRef.current.scrollTop = scrollWrapperRef.current.scrollHeight
    }
  }, [messages.length])

  const messagesToShow = messages
  return (
    <FlexContainer
      style={{ minHeight: "39.2rem", maxHeight: "39.2rem" }}
      bgColor={theme.colors.black}
      borderRadius={0.4}
    >
      <S.ScrollWrapper ref={scrollWrapperRef}>
        {messagesToShow.map((message, index) => (
          <Message
            key={index}
            {...message}
            onChoicePromptClick={onChoicePromptClick}
          />
        ))}
        {loading && (
          <Message
            loading={true}
            role="assistant"
            content="Thinking..."
            onChoicePromptClick={() => ({})}
          />
        )}
      </S.ScrollWrapper>
    </FlexContainer>
  )
}

export function Message({
  loading,
  content,
  role,
  onChoicePromptClick,
}: MessageProps & {
  onChoicePromptClick: (prompt: string) => void
  loading?: boolean
}) {
  const [selectedPrompts, setSelectedPrompts] = useState<string[]>([])
  const { theme } = useThemeContext()

  const choicesPromptJson = extractObjectFromAiResponse(content, [
    "choicePrompts",
  ]) as { choicePrompts: string[] } | null

  const cleanedMessage = useMemo(() => {
    let finalMessage = content
    finalMessage = removeMatchingJSON(finalMessage, ["choicePrompts"])
    finalMessage = removeMatchingJSON(finalMessage, ["preferredVaults"])
    finalMessage = removeSectionAndJson(finalMessage, "### Technical Details:")

    return finalMessage
  }, [content])

  const assistantMessage = useMarkdownProcessor(cleanedMessage)

  return (
    <FlexContainer padding="0.4rem 0.4rem 0.4rem 1.4rem" gap={1.2}>
      {role === "assistant" ? (
        <FlexContainer
          padding="0.5rem 0 0 0"
          flex={false}
          alignItems="flex-start"
        >
          <MorphoIcon height={32} width={32} />
        </FlexContainer>
      ) : (
        <FlexContainer
          padding="0.5rem 0 0 0"
          flex={false}
          alignItems="flex-start"
        >
          <ConsoleIcon height={32} width={32} />
        </FlexContainer>
      )}

      <FlexContainer key={content} opacityInEffect padding="1rem 1rem 1rem 0">
        {loading ? (
          <FlexContainer
            alignItems="center"
            gap={0.8}
            borderRadius={0.4}
            bgColor="#232328"
            borderColor={theme.colors.gray600}
            padding="0.6rem 0.4rem "
            flex={false}
          >
            <Spinner />
            <Typography type="BODY_MEDIUM_S" color={theme.colors.white}>
              Thinking ...
            </Typography>
          </FlexContainer>
        ) : role === "user" ? (
          <FlexContainer>
            <Typography type="BODY_MEDIUM_S" color={theme.colors.white}>
              {content}
            </Typography>
          </FlexContainer>
        ) : (
          <FlexContainer width={100} flexDirection="column" gap={1.6}>
            {content && (
              <FlexContainer flexDirection="column" gap={0.4}>
                {assistantMessage}
              </FlexContainer>
            )}
            <SlideInAnimationWrapper delay={1.5}>
              <FlexContainer gap={1} style={{ flexWrap: "wrap" }}>
                {choicesPromptJson?.choicePrompts.map((prompt) => (
                  <>
                    {selectedPrompts.includes(prompt) ? (
                      <SelectedPrompt prompt={prompt} />
                    ) : (
                      <UnselectedPrompt
                        prompt={prompt}
                        onClick={() => {
                          onChoicePromptClick(prompt)
                          if (prompt === OPEN_DEPOSIT_MODAL_PROMPT) return
                          setSelectedPrompts((prev) => [...prev, prompt])
                        }}
                      />
                    )}
                  </>
                ))}
              </FlexContainer>
            </SlideInAnimationWrapper>
          </FlexContainer>
        )}
      </FlexContainer>
    </FlexContainer>
  )
}

function UnselectedPrompt({
  prompt,
  onClick,
}: {
  prompt: string
  onClick: () => void
}) {
  const { theme } = useThemeContext()
  return (
    <FlexContainer
      onClick={onClick}
      padding="0.4rem 0.8rem"
      key={prompt}
      borderRadius={0.4}
      borderColor={theme.colors.gray600}
      bgColor={theme.colors.gray800}
      cursor="pointer"
      hoverBorderColor={theme.colors.gray500}
      hoverBgColor={theme.colors.gray700}
      flex={false}
    >
      <Typography type="BODY_MEDIUM_S" color={theme.colors.white}>
        {prompt}
      </Typography>
    </FlexContainer>
  )
}

function SelectedPrompt({ prompt }: { prompt: string }) {
  const { theme } = useThemeContext()
  return (
    <FlexContainer
      padding="0.4rem 0.8rem"
      key={prompt}
      borderRadius={0.4}
      borderColor={theme.colors.gray300}
      bgColor={theme.colors.gray100}
      flex={false}
    >
      <Typography type="BODY_MEDIUM_S" color={theme.colors.black}>
        {prompt}
      </Typography>
    </FlexContainer>
  )
}
