"use client"

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

import { privacyPolicy } from "@/constants/currentWebHrefs"

import { registerUser } from "@/actions/registerUser"
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 Input from "@/components/TempDesignSystem/Form/Input"
import NewPassword from "@/components/TempDesignSystem/Form/NewPassword"
import Phone from "@/components/TempDesignSystem/Form/Phone"
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 useLang from "@/hooks/useLang"

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

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

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

export default function SignupForm({ link, subtitle, title }: SignUpFormProps) {
  const intl = useIntl()
  const lang = useLang()
  const country = intl.formatMessage({ id: "Country" })
  const email = intl.formatMessage({ id: "Email address" })
  const phoneNumber = intl.formatMessage({ id: "Phone number" })
  const zipCode = intl.formatMessage({ id: "Zip code" })

  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",
  })

  async function onSubmit(data: SignUpSchema) {
    try {
      const result = await registerUser(data)
      if (result && !result.success) {
        toast.error(intl.formatMessage({ id: "Something went wrong!" }))
      }
    } catch (error) {
      // The server-side redirect will throw an error, which we can ignore
      // as it's handled by Next.js.
      if (error instanceof Error && error.message.includes("NEXT_REDIRECT")) {
        return
      }
      toast.error(intl.formatMessage({ id: "Something went wrong!" }))
    }
  }

  return (
    <section className={styles.formWrapper}>
      <Title as="h3">{title}</Title>
      <FormProvider {...methods}>
        <form
          className={styles.form}
          id="register"
          onSubmit={methods.handleSubmit(onSubmit)}
          /**
           * Ignoring since ts doesn't recognize that tRPC
           * parses FormData before reaching the route
           * @ts-ignore */
          action={registerUser}
        >
          <section className={styles.userInfo}>
            <div className={styles.container}>
              <header>
                <Subtitle type="two">
                  {intl.formatMessage({ id: "Contact information" })}
                </Subtitle>
              </header>
              <div className={styles.nameInputs}>
                <Input
                  label={intl.formatMessage({ id: "First name" })}
                  name="firstName"
                  registerOptions={{ required: true }}
                />
                <Input
                  label={intl.formatMessage({ id: "Last name" })}
                  name="lastName"
                  registerOptions={{ required: true }}
                />
              </div>
            </div>
            <div className={styles.dateField}>
              <header>
                <Caption type="bold">
                  {intl.formatMessage({ id: "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"
            />
            <Phone label={phoneNumber} name="phoneNumber" />
          </section>
          <section className={styles.password}>
            <header>
              <Subtitle type="two">
                {intl.formatMessage({ id: "Password" })}
              </Subtitle>
            </header>
            <NewPassword
              name="password"
              placeholder="Password"
              label={intl.formatMessage({ id: "Password" })}
            />
          </section>
          <section className={styles.terms}>
            <header>
              <Subtitle type="two">
                {intl.formatMessage({ id: "Terms and conditions" })}
              </Subtitle>
            </header>
            <Checkbox name="termsAccepted" registerOptions={{ required: true }}>
              <Body>
                {intl.formatMessage({
                  id: "Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with",
                })}{" "}
                <Link
                  variant="underscored"
                  color="peach80"
                  target="_blank"
                  href={privacyPolicy[lang]}
                >
                  {intl.formatMessage({ id: "Scandic's Privacy Policy." })}
                </Link>
              </Body>
            </Checkbox>
          </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="button"
              theme="base"
              intent="primary"
              onClick={() => methods.trigger()}
              data-testid="trigger-validation"
            >
              {intl.formatMessage({ id: "Sign up to Scandic Friends" })}
            </Button>
          ) : (
            <Button
              className={styles.signUpButton}
              type="submit"
              theme="base"
              intent="primary"
              disabled={methods.formState.isSubmitting}
              data-testid="submit"
            >
              {intl.formatMessage({ id: "Sign up to Scandic Friends" })}
            </Button>
          )}
        </form>
      </FormProvider>
    </section>
  )
}
