import { LegacyRef, useEffect, useRef, useState } from "react"
import classNames from "classnames"
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import { prism } from "react-syntax-highlighter/dist/esm/styles/prism"

import useWindowDimensions from "../../../../../../hooks/window-dimensions.hook"
import { Config } from "../../../../../../utils/config"
import { CreateJournaleType } from "../../../../../../types/journal.type"
import { Button } from "../../../../../../ui-component/button/button.component"
import { useAccountUser } from "../../../../../../hooks/user.hook"
import { Icon } from "../../../../../../ui-component/icon/icon.component"
import { Placeholder } from "../../../../../../ui-component/placeholder/placeholder.component"
import { DashboardInput } from "../../../../dashboard-input/dashboard-input.component"
import { TokenUtils } from "../../../../../../utils/token.utils"

import step2 from "../../../../../../assets/images/step2.png"
import rotate from "../../../../../../assets/images/rotate.png"
import botLogo from "../../../../../../assets/images/bot-logo.svg"

import styles from "./step2.module.css"

export function Step2({
  journal,
  setJournal,
  onClick,
}: {
  journal: CreateJournaleType
  setJournal: React.Dispatch<React.SetStateAction<CreateJournaleType>>
  onClick: () => void
}) {
  // ---------------------------------------------------------------------------
  // variables
  // ---------------------------------------------------------------------------

  const accountUser = useAccountUser()
  const { width: screenWidth } = useWindowDimensions()

  const textareaGptRef = useRef<HTMLTextAreaElement>(null)
  const messagesEndRef = useRef<HTMLDivElement | null>(null)

  const [data, setData] = useState<{
    title: string
    description: string
  }>({
    title: journal.firstEventTitle,
    description: "",
  })
  const [chatHistory, setChatHistory] = useState<
    Array<{ role: "user" | "bot"; content: string }>
  >([])
  const [userInput, setUserInput] = useState("")

  const [isFocus, setIsFocus] = useState(false)
  const [loading, setLoading] = useState(false)

  // ---------------------------------------------------------------------------
  // effects
  // ---------------------------------------------------------------------------

  useEffect(() => {
    calculateGptHeight()
  }, [data.description, screenWidth])

  useEffect(() => {
    if (messagesEndRef.current) {
      messagesEndRef.current.scrollIntoView({ behavior: "instant" })
    }
  }, [chatHistory])

  // ---------------------------------------------------------------------------
  // functions
  // ---------------------------------------------------------------------------

  function calculateGptHeight() {
    if (textareaGptRef.current) {
      textareaGptRef.current.style.height = "auto"
      textareaGptRef.current.style.height = `${Math.min(textareaGptRef.current.scrollHeight, 260)}px`
    }
  }

  async function regenarateText() {
    setLoading(true)

    try {
      const response = await fetch(
        `${Config.url}/api/gptTeacher/regenerateNewspaper`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: "Bearer " + TokenUtils.get(),
          },
          body: JSON.stringify({
            details: `Regenarate this text please: ${data.description}`,
          }),
          credentials: "include",
        },
      )
      const res: { description: string } = await response.json()

      setData({ ...data, description: res.description })
      setLoading(false)
    } catch (error) {
      setLoading(false)
      alert("Network error. Please try again.")
    }
  }

  async function onSend(text: string) {
    if (!text.trim()) return

    const newUserMessage = { role: "user" as const, content: text }
    setChatHistory((prev) => [...prev, newUserMessage])
    setUserInput("")

    const newsPaperData = {
      title: data.title,
      description: text,
    }
    setLoading(true)

    try {
      const response = await fetch(
        `${Config.url}/api/gptTeacher/makeNewspaper`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: "Bearer " + TokenUtils.get(),
          },
          body: JSON.stringify(newsPaperData),
          credentials: "include",
        },
      )

      if (!response.ok) {
        alert("Something went wrong!")
        return
      }
      const result = await response.json()

      const { description } = result
      setData({ title: newsPaperData.title, description })

      const newBotMessage = {
        role: "bot" as const,
        content: description,
      }

      setLoading(false)
      setChatHistory((prev) => [...prev, newBotMessage])
    } catch (error) {
      setLoading(false)
      alert("Network error. Please try again.")
    }
  }

  function renderMessage(
    message: { role: "user" | "bot"; content: string },
    index: number,
  ) {
    const isBot = message.role === "bot"

    return (
      <div
        key={index}
        className={classNames(styles.messageContainer, {
          [styles.botMessage]: isBot,
          [styles.userMessage]: !isBot,
        })}
      >
        {isBot && (
          <div className={styles.botIcon}>
            <img src={botLogo} alt="Bot" />
          </div>
        )}

        <div
          className={styles.messageContent}
          style={{
            paddingTop: isBot ? 0 : "0.5rem",
            paddingBottom: isBot ? 0 : "0.5rem",
            marginRight: isBot ? 0 : "1.5rem",
            marginTop: isBot ? 0 : "0.2rem",
          }}
        >
          <ReactMarkdown
            className={styles.messageText}
            remarkPlugins={[remarkGfm]}
            children={message.content.replace(/\n/g, "  \n")}
            components={{
              code({ node, ref, className, children, ...props }) {
                const match = /language-(\w+)/.exec(className || "")
                return match ? (
                  <SyntaxHighlighter
                    {...props}
                    ref={ref as LegacyRef<SyntaxHighlighter> | undefined}
                    children={String(children).replace(/\n$/, "")}
                    style={prism}
                    language={match[1]}
                    PreTag="div"
                  />
                ) : (
                  <code className={className} {...props}>
                    {children}
                  </code>
                )
              },
            }}
          />
        </div>
        {!isBot && (
          <div className={styles.userIcon}>
            {accountUser && accountUser.photo ? (
              <img
                src={Config.imageUrl + accountUser.photo}
                className={styles.userPhoto}
                loading="lazy"
              />
            ) : (
              <Icon name="fa-solid fa-circle-user" size="2.4" />
            )}
          </div>
        )}
      </div>
    )
  }

  // ---------------------------------------------------------------------------
  return (
    <>
      <div className={styles.container}>
        <div className={styles.leftWrapper}>
          {/* --------------------------------------------------------------------------- */}
          {/* EVENT TITLE */}
          {/* --------------------------------------------------------------------------- */}

          <div
            className={classNames(
              styles.inputWrapper,
              isFocus ? styles.focused : "",
            )}
          >
            <input
              value={data.title}
              autoFocus
              onChange={(e) => {
                setData({ ...data, title: e.target.value })
              }}
              placeholder="トピックの見出し"
              onBlur={() => setIsFocus(false)}
              onFocus={() => setIsFocus(true)}
            />
          </div>

          <div className={styles.chatHistoryWrap}>
            {/* --------------------------------------------------------------------------- */}
            {/* HISTORY */}
            {/* --------------------------------------------------------------------------- */}

            <div className={styles.chatHistory}>
              {chatHistory.map((message, index) =>
                renderMessage(message, index),
              )}
              <div ref={messagesEndRef} />
            </div>

            {/* --------------------------------------------------------------------------- */}
            {/* INPUT FOR GENERATING DESCRIPTION */}
            {/* --------------------------------------------------------------------------- */}

            <DashboardInput
              resize
              text={userInput}
              onTextChange={setUserInput}
              onSend={onSend}
            />
          </div>
        </div>

        {/* --------------------------------------------------------------------------- */}
        {/* EVENT PREVIEW (LIVE) */}
        {/* --------------------------------------------------------------------------- */}

        <div className={styles.rightWrapper}>
          <div className={styles.resultWrapper}>
            {/* --------------------------------------------------------------------------- */}
            {/* TITLE */}
            {/* --------------------------------------------------------------------------- */}

            <p className={styles.title}>{data.title}</p>

            {/* --------------------------------------------------------------------------- */}
            {/* DESCRIPTION */}
            {/* --------------------------------------------------------------------------- */}

            {loading ? (
              <Placeholder />
            ) : (
              <>
                {data.description && (
                  <textarea
                    ref={textareaGptRef}
                    value={data.description}
                    onChange={(e) => {
                      setData({ ...data, description: e.target.value })
                    }}
                  />
                )}
              </>
            )}
          </div>

          {/* --------------------------------------------------------------------------- */}
          {/* BACKGROUND */}
          {/* --------------------------------------------------------------------------- */}

          <img src={step2} className={styles.titleImage} loading="lazy" />

          {/* --------------------------------------------------------------------------- */}
          {/* REGENARATE BUTTON */}
          {/* --------------------------------------------------------------------------- */}

          <div className={styles.rotateWrapper} onClick={regenarateText}>
            <img src={rotate} className={styles.rotate} />
          </div>
        </div>
      </div>

      {/* --------------------------------------------------------------------------- */}
      {/* NEXT BUTTON */}
      {/* --------------------------------------------------------------------------- */}

      <Button
        className={styles.btnWrapper}
        disabled={!data.title || !data.description}
        onClick={() => {
          setJournal({
            ...journal,
            firstEventTitle: data.title,
            firstEventDescription: data.description,
          })

          onClick()
        }}
      >
        次へ
      </Button>
    </>
  )
}
how to make text appearing one by one not whole the text ?