"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useParams, useRouter } from "next/navigation"
import { useEffect, useState } from "react"
import { FormProvider, useForm } from "react-hook-form"
import { useIntl } from "react-intl"

import {
  getDefaultCountryFromLang,
  type Lang,
  langToApiLang,
} from "@/constants/languages"
import { logout } from "@/constants/routes/handleAuth"
import { profile } from "@/constants/routes/myPages"
import { trpc } from "@/lib/trpc/client"

import { editProfile } from "@/actions/editProfile"
import Dialog from "@/components/Dialog"
import ChangeNameDisclaimer from "@/components/MyPages/Profile/ChangeNameDisclaimer"
import Button from "@/components/TempDesignSystem/Button"
import Title from "@/components/TempDesignSystem/Text/Title"
import { toast } from "@/components/TempDesignSystem/Toasts"
import usePhoneNumberParsing from "@/hooks/usePhoneNumberParsing"
import { formatPhoneNumber } from "@/utils/phone"

import FormContent from "./FormContent"
import { type EditProfileSchema, editProfileSchema } from "./schema"

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

import {
  type EditFormProps,
  Status,
} from "@/types/components/myPages/myProfile/edit"

const formId = "edit-profile"

export default function Form({ user }: EditFormProps) {
  const intl = useIntl()
  const router = useRouter()
  const params = useParams()
  const lang = params.lang as Lang
  const utils = trpc.useUtils()
  /**
   * RHF isValid defaults to false and never
   * changes when JS is disabled, therefore
   * we need to keep it insync ourselves
   */
  const [isValid, setIsValid] = useState(true)

  const { phoneNumber, phoneNumberCC } = usePhoneNumberParsing(user.phoneNumber)

  const methods = useForm<EditProfileSchema>({
    defaultValues: {
      address: {
        city: user.address?.city ?? "",
        countryCode: user.address?.countryCode ?? "",
        streetAddress: user.address?.streetAddress ?? "",
        zipCode: user.address?.zipCode ?? "",
      },
      dateOfBirth: user.dateOfBirth,
      email: user.email,
      language: user.language ?? langToApiLang[lang],
      phoneNumber: phoneNumber,
      phoneNumberCC: phoneNumberCC || getDefaultCountryFromLang(lang),
      password: "",
      newPassword: "",
      retypeNewPassword: "",
    },
    mode: "all",
    criteriaMode: "all",
    resolver: zodResolver(editProfileSchema),
    reValidateMode: "onChange",
  })
  const trigger = methods.trigger

  async function handleSubmit(data: EditProfileSchema) {
    const isPasswordChanged = !!data.newPassword
    const phoneNumber = formatPhoneNumber(data.phoneNumber, data.phoneNumberCC)
    const response = await editProfile({ ...data, phoneNumber })
    switch (response.status) {
      case Status.error:
        if (response.issues?.length) {
          response.issues.forEach((issue) => {
            console.error(issue)
          })
        }
        toast.error(response.message)
        break
      case Status.success:
        toast.success(response.message)
        utils.user.get.invalidate()
        if (isPasswordChanged) {
          // Kept logout out of Next router forcing browser to navigate on logout url
          window.location.href = logout[lang]
        } else {
          const myStayReturnRoute = sessionStorage.getItem("myStayReturnRoute")
          if (myStayReturnRoute) {
            const returnRoute = JSON.parse(myStayReturnRoute)
            sessionStorage.removeItem("myStayReturnRoute")
            router.push(returnRoute.path)
          } else {
            router.push(profile[lang])
          }
          router.refresh() // Can be removed on NextJs 15
        }
        break
    }
  }

  useEffect(() => {
    setIsValid(methods.formState.isValid)
  }, [setIsValid, methods.formState.isValid])

  useEffect(() => {
    trigger()
  }, [trigger])

  return (
    <>
      <section className={styles.container}>
        <div className={styles.title}>
          <Title as="h4" color="red" level="h1" textTransform="capitalize">
            {intl.formatMessage({
              defaultMessage: "Welcome",
            })}
          </Title>
          <Title
            data-hj-suppress
            as="h4"
            color="burgundy"
            level="h2"
            textTransform="capitalize"
          >
            {user.name}
          </Title>
        </div>
        <div className={styles.btnContainer}>
          <Dialog
            bodyText={intl.formatMessage({
              defaultMessage: "Any changes you've made will be lost.",
            })}
            cancelButtonText={intl.formatMessage({
              defaultMessage: "Go back to edit",
            })}
            proceedHref={profile[lang]}
            proceedText={intl.formatMessage({
              defaultMessage: "Yes, discard changes",
            })}
            titleText={intl.formatMessage({
              defaultMessage: "Discard unsaved changes?",
            })}
            trigger={
              <Button intent="secondary" size="small" theme="base">
                {intl.formatMessage({
                  defaultMessage: "Discard changes",
                })}
              </Button>
            }
          />
          <Button
            disabled={!isValid || methods.formState.isSubmitting}
            form={formId}
            intent="primary"
            size="small"
            theme="base"
            type="submit"
          >
            {intl.formatMessage({
              defaultMessage: "Save",
            })}
          </Button>
        </div>
        <form
          /**
           * Ignoring since ts doesn't recognize that tRPC
           * parses FormData before reaching the route
           * @ts-ignore */
          action={editProfile}
          className={styles.form}
          id={formId}
          onSubmit={methods.handleSubmit(handleSubmit)}
        >
          <FormProvider {...methods}>
            <FormContent />
          </FormProvider>
        </form>
      </section>

      <ChangeNameDisclaimer />
    </>
  )
}
