import { useEffect, useState } from "react"
import StepWizard from "./components/StepWizard"
import SelectableCard from "./components/SelectableCard"
import Loader from "./components/Loader"
import { useNavigate } from "react-router"
import { useShallow } from "zustand/react/shallow"
import useStore, { TDifficulty } from "./utils/store"

import { publicInteractiveCreation, isHuman } from "./utils/rigo"
import {
  checkParams,
  isValidRigoToken,
  loginWithToken,
  parseLesson,
  fixTitleLength,
  getTechnologies,
  detectLanguage,
  isValidPublicToken,
} from "./utils/lib"

import { Uploader } from "./components/Uploader"
import toast from "react-hot-toast"
import { ParamsChecker } from "./components/ParamsChecker"
import { DEV_MODE, RIGO_FLOAT_GIF } from "./utils/constants"
import TurnstileChallenge from "./components/TurnstileChallenge"
// import TurnstileChallenge from "./components/TurnstileChallenge"
import ResumeCourseModal from "./components/ResumeCourseModal"
import { possiblePurposes, PurposeSelector } from "./components/PurposeSelector"
import { useTranslation } from "react-i18next"
import NotificationListener from "./components/NotificationListener"
import { slugify } from "./utils/creatorUtils"
import TurnstileModal from "./components/TurnstileModal"
import { TMessage } from "./components/Message"
import LanguageDetectionModal from "./components/LanguageDetectionModal"

function App() {
  const navigate = useNavigate()
  const { t, i18n } = useTranslation()

  const {
    formState,
    setFormState,
    setAuth,
    push,
    cleanHistory,
    setPlanToRedirect,
    history,
    uploadedFiles,
    auth,
    resetFormState,
    cleanAll,
    setMessages,
    technologies,
    setTechnologies,
  } = useStore(
    useShallow((state) => ({
      formState: state.formState,
      setFormState: state.setFormState,
      setAuth: state.setAuth,
      technologies: state.technologies,
      setTechnologies: state.setTechnologies,
      push: state.push,
      history: state.history,
      cleanHistory: state.cleanHistory,
      setPlanToRedirect: state.setPlanToRedirect,
      uploadedFiles: state.uploadedFiles,
      auth: state.auth,
      resetFormState: state.resetFormState,
      cleanAll: state.cleanAll,
      setMessages: state.setMessages,
    }))
  )

  const [notificationId, setNotificationId] = useState<string>("")
  const [showTurnstileModal, setShowTurnstileModal] = useState(false)
  const [showLanguageDetectionModal, setShowLanguageDetectionModal] = useState(false)
  const [detectedLanguage, setDetectedLanguage] = useState<string>("")

  useEffect(() => {
    if (formState.isCompleted) {
      handleCreateTutorial()
    }
  }, [formState.isCompleted])

  useEffect(() => {
    verifyToken()
    checkQueryParams()
    checkTechs()
  }, [])

  const verifyToken = async () => {
    const { token } = checkParams(["token"])
    if (token) {
      const user = await loginWithToken(token)
      setAuth({
        bcToken: token,
        userId: user.id,
        rigoToken: user.rigobot.key,
        user: user,
        publicToken: "",
      })
    }
  }

  const checkQueryParams = () => {
    const {
      description,
      duration,
      plan,
      purpose,
      language,
      new: newParam,
      difficulty,
    } = checkParams([
      "description",
      "duration",
      "plan",
      "purpose",
      "language",
      "new",
      "difficulty",
    ])

    if (newParam && newParam.toLowerCase().trim() === "true") {
      cleanAll()
    }

    if (description) {
      setFormState({
        description: description,
      })
    }
    if (duration && !isNaN(parseInt(duration))) {
      if (["15", "30", "60"].includes(duration)) {
        const durationInt = parseInt(duration)
        setFormState({
          duration: durationInt,
        })
      } else {
        console.error("Invalid duration received in params", duration)
      }
    }
    
    if (plan) {
      setPlanToRedirect(plan)
    } else {
      console.debug("No plan received in params")
    }
    
    // Language detection logic
    let finalLanguage = language

    // Change if query param is provided
    if (finalLanguage && finalLanguage.length === 2) {
      console.log("LANGUAGE", finalLanguage)
      setFormState({
        language: finalLanguage,
      })
      if (i18n.language !== finalLanguage) {
        i18n.changeLanguage(finalLanguage)
      }
    }

    // If no language is provided, detect the language of the description
    if (!finalLanguage && description) {
      const detectedLang = detectLanguage(description)
      if (detectedLang && detectedLang !== i18n.language) {
        finalLanguage = detectedLang
        setDetectedLanguage(detectedLang)
        setShowLanguageDetectionModal(true)
      }
    }


    if (purpose && purpose.length > 0 && possiblePurposes.includes(purpose)) {
      setFormState({
        purpose: purpose,
      })
    }

    if (
      difficulty &&
      ["easy", "beginner", "intermediate", "hard"].includes(difficulty)
    ) {
      setFormState({
        difficulty: difficulty as TDifficulty,
      })
    }

    if (description && purpose) {
      setFormState({
        currentStep: "duration",
      })
    }
    if (description && !purpose) {
      setFormState({
        currentStep: "purpose",
      })
    }
  }

  const handleCreateTutorial = async () => {
    try {
      let isAuthenticated = false
      let tokenToUse = ""
      let tokenType = ""
      if (auth.rigoToken) {
        const isRigoTokenValid = await isValidRigoToken(auth.rigoToken)
        if (isRigoTokenValid) {
          tokenToUse = auth.rigoToken
          isAuthenticated = true
          tokenType = "rigo"
        } else {
          setAuth({
            ...auth,
            rigoToken: "",
            bcToken: "",
            userId: "",
            user: null,
          })
        }
      }

      if (auth.publicToken && !isAuthenticated) {
        const isPublicTokenValid = await isValidPublicToken(auth.publicToken)
        if (isPublicTokenValid) {
          tokenToUse = auth.publicToken
          isAuthenticated = true
          tokenType = "public"
        }
      }
      if (!isAuthenticated) {
        setShowTurnstileModal(true)
        return
      }

      let techs = technologies.filter((t) => t.lang === formState.language)

      if (techs.length === 0) {
        techs = technologies.filter((t) => t.lang === "en")
      }

      const res = await publicInteractiveCreation(
        {
          courseInfo: `${JSON.stringify(
            formState
          )}. The following technologies are available, choose up to 3 from the following list: <techs>${techs
            .map((t) => t.slug)
            .join(", ")}</techs>
            
            The following files have been uploaded by the user: ${uploadedFiles.map((f) => `<FILE name="${f.name}">${f.text}</FILE>`).join("\n")}
            `,
          prevInteractions: "USER: " + formState.description,
        },
        tokenToUse,
        formState.purpose || "learnpack-lesson-writer",
        tokenType === "rigo" ? false : true
      )
      setNotificationId(res.notificationId)
    } catch (error) {
      console.error(error, "ERROR CREATING TUTORIAL")
      toast.error("Something went wrong. Please try again.")
      setFormState({
        isCompleted: false,
        currentStep: "hasContentIndex",
      })
    }
  }

  const checkTechs = async () => {
    if (technologies.length === 0) {
      const technologies = await getTechnologies()
      console.log("TECHNOLOGIES", technologies)
      setTechnologies(technologies)
    }
  }

  const handleLanguageSwitch = () => {
    setFormState({
      language: detectedLanguage,
    })
    i18n.changeLanguage(detectedLanguage)
    setShowLanguageDetectionModal(false)
  }

  const handleLanguageStay = () => {
    setShowLanguageDetectionModal(false)
  }

  const buildSteps = () => {
    const steps = [
      {
        title: t("stepWizard.description"),
        slug: "description",
        isCompleted: formState.description.length > 0,
        required: true,
        validator: (value: string) => {
          const lang = detectLanguage(value)
          console.log("Description validator language detection:", { lang, currentLang: i18n.language, value })

          if (lang && lang !== "en" && lang !== i18n.language) {
            setDetectedLanguage(lang)
            setShowLanguageDetectionModal(true)
          }

          return value.length > 0
        },
        content: (
          <textarea
            required
            placeholder={t("stepWizard.descriptionPlaceholder")}
            className="w-full h-24 border-2 border-gray-300 rounded-md p-2 bg-white"
            value={formState.description}
            onChange={(e) => {
              setFormState({
                description: e.target.value,
              })
            }}
          />
        ),
      },
      {
        title: t("stepWizard.purpose"),
        slug: "purpose",
        isCompleted: formState?.purpose?.length > 0,
        required: true,
        content: (
          <PurposeSelector
            onFinish={(purpose) => {
              setFormState({
                purpose: purpose,
                currentStep: "duration",
              })
            }}
          />
        ),
      },
      {
        title: t("stepWizard.duration"),
        slug: "duration",
        isCompleted: formState.duration > 0,
        required: true,
        content: (
          <div className="flex flex-col md:flex-row gap-2">
            <SelectableCard
              title={t("stepWizard.durationCard.15")}
              // subtitle="This is a tutorial that will take 15 minutes to complete"
              onClick={() => {
                setFormState({
                  duration: 15,
                  currentStep: "verifyHuman",
                })
              }}
              selected={formState.duration === 15}
            />
            <SelectableCard
              title={t("stepWizard.durationCard.30")}
              // subtitle="This is a tutorial that will take 30 minutes to complete"
              onClick={() => {
                setFormState({
                  duration: 30,
                  currentStep: "verifyHuman",
                })
              }}
              selected={formState.duration === 30}
            />
            <SelectableCard
              title={t("stepWizard.durationCard.60")}
              // subtitle="This is a tutorial that will take 1 hour to complete"
              onClick={() => {
                setFormState({
                  duration: 60,
                  currentStep: "verifyHuman",
                })
              }}
              selected={formState.duration === 60}
            />
          </div>
        ),
      },
      {
        title: t("stepWizard.verifyHuman"),
        slug: "verifyHuman",
        isCompleted: false,
        required: true,
        content: (
          <TurnstileChallenge
            siteKey={
              DEV_MODE ? "0x4AAAAAABeKMBYYinMU4Ib0" : "0x4AAAAAABeZ9tjEevGBsJFU"
            }
            onSuccess={async (token) => {
              const { human, message, token: jwtToken } = await isHuman(token)
              if (human) {
                toast.success(t("stepWizard.humanSuccess"))

                console.log("JWT TOKEN received", jwtToken)
                setAuth({
                  ...auth,
                  publicToken: jwtToken,
                })
                setFormState({
                  currentStep: "hasContentIndex",
                })
              } else {
                toast.error(message)
                setFormState({
                  currentStep: "duration",
                })
              }
            }}
            onError={() => {
              toast.error(t("turnstileModal.error"), {
                duration: 10000,
              })
              setFormState({
                currentStep: "duration",
              })
            }}
          />
        ),
      },
      {
        title: t("stepWizard.hasContentIndex"),
        slug: "hasContentIndex",
        isCompleted: false,
        content: (
          <>
            <div className="flex flex-col md:flex-row gap-2 justify-center">
              <SelectableCard
                title={t("stepWizard.hasContentIndexCard.no")}
                onClick={() => {
                  setFormState({
                    hasContentIndex: false,
                    variables: [
                      ...formState.variables.filter(
                        (v) => v !== "contentIndex"
                      ),
                    ],
                    isCompleted: true,
                  })
                }}
                // selected={formState.hasContentIndex === false}
              />
              <SelectableCard
                title={t("stepWizard.hasContentIndexCard.yes")}
                onClick={() => {
                  setFormState({
                    hasContentIndex: true,
                    currentStep: "contentIndex",
                    variables: [...formState.variables, "contentIndex"],
                  })
                }}
                // selected={formState.hasContentIndex === true}
              />
            </div>
          </>
        ),
      },
      {
        title: t("stepWizard.contentIndex"),
        slug: "contentIndex",
        helpText: t("stepWizard.contentIndexHelpText"),
        isCompleted:
          formState.contentIndex.length > 0 || uploadedFiles.length > 0,
        required: true,
        content: (
          <Uploader
            onFinish={(text) => {
              setFormState({
                contentIndex: text,
                isCompleted: true,
              })
            }}
          />
        ),
      },
    ]

    return steps.filter(
      (step) =>
        formState.variables.includes(step.slug) ||
        step.slug === formState.currentStep
    )
  }

  return (
    <>
      <ParamsChecker />
      {showLanguageDetectionModal && (
        <LanguageDetectionModal
          detectedLanguage={detectedLanguage}
          onSwitch={handleLanguageSwitch}
          onStay={handleLanguageStay}
        />
      )}
      {showTurnstileModal && (
        <TurnstileModal
          onClose={() => {
            setShowTurnstileModal(false)
            handleCreateTutorial()
          }}
          onError={() => {
            toast.error(t("turnstileModal.error"), {
              duration: 10000,
            })
            setShowTurnstileModal(false)
            setFormState({
              currentStep: "purpose",
            })
          }}
        />
      )}
      {formState.isCompleted && history.length === 0 ? (
        <>
          <Loader
            text={t("loader.text")}
            icon={<img src={RIGO_FLOAT_GIF} alt="rigo" className="w-20 h-20" />}
          />
          {notificationId && (
            <NotificationListener
              onNotification={(res) => {
                const lessons = res.parsed.listOfSteps.map((lesson: any) => {
                  return parseLesson(lesson, [])
                })

                push({
                  lessons,
                  courseInfo: {
                    ...formState,
                    title: res.parsed.title,
                    slug: slugify(fixTitleLength(res.parsed.title)),
                    description: res.parsed.description,
                    language:
                      res.parsed.languageCode || formState.language || "en",
                    technologies:
                      res.parsed.technologies.length > 0
                        ? res.parsed.technologies
                        : ["education", "quizzes"],
                  },
                })

                if (res.parsed.languageCode) {
                  i18n.changeLanguage(res.parsed.languageCode)
                }

                let initialMessages: TMessage[] = [
                  {
                    type: "user",
                    content: formState.description,
                  },
                  {
                    type: "assistant",
                    content: res.parsed.aiMessage,
                  },
                ]

                if (lessons.length > 0) {
                  initialMessages.push({
                    type: "assistant",
                    content: t("contentIndex.okMessage"),
                  })
                  initialMessages.push({
                    type: "assistant",
                    content: t("contentIndex.instructionsMessage"),
                  })
                }

                setMessages(initialMessages)
                navigate("/creator/syllabus")
                setFormState({
                  isCompleted: false,
                  currentStep: "description",
                })
              }}
              notificationId={notificationId}
            />
          )}
        </>
      ) : (
        <>
          {history.length > 0 && (
            <ResumeCourseModal
              onContinue={() => {
                navigate("/creator/syllabus")
              }}
              onStartOver={() => {
                resetFormState()
                cleanAll()
                cleanHistory()
              }}
            />
          )}
          <StepWizard
            hideLastButton={true}
            formState={formState}
            steps={buildSteps()}
            setFormState={setFormState}
            onFinish={() => {
              setFormState({
                isCompleted: true,
              })
            }}
          />
        </>
      )}
    </>
  )
}

export default App
