"use client"

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

import {
  membershipTermsAndConditions,
  privacyPolicy,
} from "@/constants/webHrefs"
import { trpc } from "@/lib/trpc/client"

import Button from "@/components/TempDesignSystem/Button"
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
import CountrySelect from "@/components/TempDesignSystem/Form/Country"
import DateSelect from "@/components/TempDesignSystem/Form/Date"
import DeprecatedPhone from "@/components/TempDesignSystem/Form/DeprecatedPhone"
import Input from "@/components/TempDesignSystem/Form/Input"
import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import { toast } from "@/components/TempDesignSystem/Toasts"
import { useFormTracking } from "@/components/TrackingSDK/hooks"
import useLang from "@/hooks/useLang"

import { type SignUpSchema, signUpSchema } from "./schema"

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

import type { SignUpFormProps } from "@/types/components/form/signupForm"

export default function SignupForm({ title }: SignUpFormProps) {
  const intl = useIntl()
  const router = useRouter()
  const lang = useLang()
  const country = intl.formatMessage({
    defaultMessage: "Country",
  })
  const email = intl.formatMessage({
    defaultMessage: "Email address",
  })
  const phoneNumber = intl.formatMessage({
    defaultMessage: "Phone number",
  })
  const zipCode = intl.formatMessage({
    defaultMessage: "Zip code",
  })
  const signupButtonText = intl.formatMessage({
    defaultMessage: "Join now",
  })

  const signup = trpc.user.signup.useMutation({
    onSuccess: (data) => {
      if (data.success && data.redirectUrl) {
        router.push(data.redirectUrl)
      }
    },
    onError: (error) => {
      if (error.data?.code === "CONFLICT") {
        toast.error(
          intl.formatMessage({
            defaultMessage:
              "An account with this email already exists. Please try signing in instead.",
          })
        )
        return
      }

      toast.error(
        intl.formatMessage({
          defaultMessage: "Something went wrong!",
        })
      )
      console.error("Component Signup error:", error)
    },
  })

  const methods = useForm<SignUpSchema>({
    defaultValues: {
      firstName: "",
      lastName: "",
      email: "",
      phoneNumber: "",
      dateOfBirth: "",
      address: {
        countryCode: "",
        zipCode: "",
      },
      password: "",
      termsAccepted: false,
    },
    mode: "all",
    criteriaMode: "all",
    resolver: zodResolver(signUpSchema),
    reValidateMode: "onChange",
    shouldFocusError: true,
  })

  const { control, subscribe } = methods

  useFormTracking("signup", subscribe, control)

  async function onSubmit(data: SignUpSchema) {
    signup.mutate({ ...data, language: lang })
  }

  return (
    <section className={styles.formWrapper}>
      <Title as="h3">{title}</Title>
      <FormProvider {...methods}>
        <form
          className={styles.form}
          id="register"
          onSubmit={methods.handleSubmit(onSubmit)}
        >
          <section className={styles.userInfo}>
            <div className={styles.container}>
              <header>
                <Subtitle type="two">
                  {intl.formatMessage({
                    defaultMessage: "Contact information",
                  })}
                </Subtitle>
              </header>
              <div className={styles.nameInputs}>
                <Input
                  label={intl.formatMessage({
                    defaultMessage: "First name",
                  })}
                  name="firstName"
                  registerOptions={{ required: true }}
                />
                <Input
                  label={intl.formatMessage({
                    defaultMessage: "Last name",
                  })}
                  name="lastName"
                  registerOptions={{ required: true }}
                />
              </div>
            </div>
            <div className={styles.dateField}>
              <header>
                <Caption type="bold">
                  {intl.formatMessage({
                    defaultMessage: "Birth date",
                  })}
                </Caption>
              </header>
              <DateSelect
                name="dateOfBirth"
                registerOptions={{ required: true }}
              />
            </div>
            <div className={styles.container}>
              <Input
                label={zipCode}
                name="address.zipCode"
                registerOptions={{ required: true }}
              />
              <CountrySelect
                label={country}
                name="address.countryCode"
                registerOptions={{ required: true }}
              />
            </div>
            <Input
              label={email}
              name="email"
              registerOptions={{ required: true }}
              type="email"
            />
            <DeprecatedPhone label={phoneNumber} name="phoneNumber" />
          </section>
          <section className={styles.password}>
            <header>
              <Subtitle type="two">
                {intl.formatMessage({
                  defaultMessage: "Password",
                })}
              </Subtitle>
            </header>
            <PasswordInput
              name="password"
              label={intl.formatMessage({
                defaultMessage: "Password",
              })}
              isNewPassword
            />
          </section>
          <section className={styles.terms}>
            <header>
              <Subtitle type="two">
                {intl.formatMessage({
                  defaultMessage: "Terms and conditions",
                })}
              </Subtitle>
            </header>
            <Checkbox name="termsAccepted" registerOptions={{ required: true }}>
              {intl.formatMessage({
                defaultMessage: "I accept",
              })}
            </Checkbox>
            {/* TODO: Update copy once ready */}
            <Body>
              {intl.formatMessage(
                {
                  defaultMessage:
                    "By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.",
                },
                {
                  termsAndConditionsLink: (str) => (
                    <Link
                      textDecoration="underline"
                      color="Text/Interactive/Secondary"
                      target="_blank"
                      href={membershipTermsAndConditions[lang]}
                    >
                      {str}
                    </Link>
                  ),
                  privacyPolicy: (str) => (
                    <Link
                      textDecoration="underline"
                      color="Text/Interactive/Secondary"
                      target="_blank"
                      href={privacyPolicy[lang]}
                    >
                      {str}
                    </Link>
                  ),
                }
              )}
            </Body>
          </section>

          {/*
            This is a manual validation trigger workaround:
            - The Controller component (which Input uses) doesn't re-render on submit,
              which prevents automatic error display.
            - Future fix requires Input component refactoring (out of scope for now).
          */}
          {!methods.formState.isValid ? (
            <Button
              className={styles.signUpButton}
              type="submit"
              theme="base"
              intent="primary"
              onClick={() => methods.trigger()}
              data-testid="trigger-validation"
            >
              {signupButtonText}
            </Button>
          ) : (
            <Button
              className={styles.signUpButton}
              type="submit"
              theme="base"
              intent="primary"
              disabled={methods.formState.isSubmitting || signup.isPending}
              data-testid="submit"
            >
              {signupButtonText}
            </Button>
          )}
        </form>
      </FormProvider>
    </section>
  )
}
