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

import { 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 Button from "@/components/TempDesignSystem/Button"
import Title from "@/components/TempDesignSystem/Text/Title"
import { toast } from "@/components/TempDesignSystem/Toasts"

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 { inputValue: phoneInput } = usePhoneInput({
    defaultCountry:
      user.phoneNumber && isValidPhoneNumber(user.phoneNumber)
        ? parsePhoneNumberWithError(user.phoneNumber).country?.toLowerCase()
        : "se",
    forceDialCode: true,
    value: 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: phoneInput,
      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 response = await editProfile(data)
    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>
  )
}
