"use client"

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

import { logger } from "@scandic-hotels/common/logger"
import { Button } from "@scandic-hotels/design-system/Button"
import Checkbox from "@scandic-hotels/design-system/Form/Checkbox"
import CountrySelect from "@scandic-hotels/design-system/Form/Country"
import DateSelect from "@scandic-hotels/design-system/Form/Date"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import Link from "@scandic-hotels/design-system/Link"
import { toast } from "@scandic-hotels/design-system/Toast"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { trpc } from "@scandic-hotels/trpc/client"
import {
  signupErrors,
  type SignUpSchema,
  signUpSchema,
} from "@scandic-hotels/trpc/routers/user/schemas"

import { getDefaultCountryFromLang } from "@/constants/languages"
import {
  membershipTermsAndConditions,
  privacyPolicy,
} from "@/constants/webHrefs"

import Input from "@/components/TempDesignSystem/Form/Input"
import PasswordInput from "@/components/TempDesignSystem/Form/PasswordInput"
import { useFormTracking } from "@/components/TrackingSDK/hooks"
import useLang from "@/hooks/useLang"
import { getFormattedCountryList } from "@/utils/countries"
import { getErrorMessage } from "@/utils/getErrorMessage"
import { formatPhoneNumber } from "@/utils/phone"

// 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 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!",
        })
      )
      logger.error("Component Signup error:", error)
    },
  })

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

  const {
    control,
    subscribe,
    formState: { errors },
  } = methods

  const { trackFormSubmit } = useFormTracking("signup", subscribe, control)

  async function onSubmit(data: SignUpSchema) {
    const phoneNumber = formatPhoneNumber(data.phoneNumber, data.phoneNumberCC)
    signup.mutate({ ...data, phoneNumber, language: lang })
    trackFormSubmit()
  }

  return (
    <div className={styles.formWrapper}>
      {title ? (
        <Typography variant="Title/md">
          <h2>{title}</h2>
        </Typography>
      ) : null}
      <FormProvider {...methods}>
        <form
          className={styles.form}
          id="register"
          onSubmit={methods.handleSubmit(onSubmit)}
        >
          <section className={styles.userInfo}>
            <div className={styles.container}>
              <header>
                <Typography variant="Title/Subtitle/md">
                  <h3>
                    {intl.formatMessage({
                      defaultMessage: "Contact information",
                    })}
                  </h3>
                </Typography>
              </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}>
              <Typography variant="Body/Supporting text (caption)/smBold">
                <p>
                  {intl.formatMessage({
                    defaultMessage: "Birth date",
                  })}
                </p>
              </Typography>
              <DateSelect
                labels={{
                  day: intl.formatMessage({ defaultMessage: "Day" }),
                  month: intl.formatMessage({ defaultMessage: "Month" }),
                  year: intl.formatMessage({ defaultMessage: "Year" }),
                  errorMessage: getErrorMessage(
                    intl,
                    errors.dateOfBirth?.message?.toString()
                  ),
                }}
                lang={lang}
                name="dateOfBirth"
                registerOptions={{ required: true }}
              />
            </div>
            <div className={cx(styles.container, styles.additional)}>
              <Input
                label={intl.formatMessage({
                  defaultMessage: "Zip code",
                })}
                name="address.zipCode"
                registerOptions={{ required: true }}
              />
              <CountrySelect
                countries={getFormattedCountryList(intl)}
                errorMessage={getErrorMessage(
                  intl,
                  errors.address?.countryCode?.message
                )}
                label={intl.formatMessage({
                  defaultMessage: "Country",
                })}
                lang={lang}
                name="address.countryCode"
                registerOptions={{ required: true }}
              />
              <Input
                label={intl.formatMessage({
                  defaultMessage: "Email address",
                })}
                name="email"
                registerOptions={{ required: true }}
                type="email"
              />
              <Phone
                countryLabel={intl.formatMessage({
                  defaultMessage: "Country code",
                })}
                countriesWithTranslatedName={getFormattedCountryList(intl)}
                defaultCountryCode={getDefaultCountryFromLang(lang)}
                errorMessage={getErrorMessage(
                  intl,
                  errors.phoneNumber?.message
                )}
                label={intl.formatMessage({
                  defaultMessage: "Phone number",
                })}
                name="phoneNumber"
              />
            </div>
          </section>
          <section className={styles.password}>
            <header>
              <Typography variant="Title/Subtitle/md">
                <h3>
                  {intl.formatMessage({
                    defaultMessage: "Password",
                  })}
                </h3>
              </Typography>
            </header>
            <PasswordInput
              name="password"
              label={intl.formatMessage({
                defaultMessage: "Password",
              })}
              isNewPassword
            />
          </section>
          <section className={styles.terms}>
            <header>
              <Typography variant="Title/Subtitle/md">
                <h3>
                  {intl.formatMessage({
                    defaultMessage: "Terms and conditions",
                  })}
                </h3>
              </Typography>
            </header>
            <Checkbox
              name="termsAccepted"
              registerOptions={{
                required: true,
              }}
              errorCodeMessages={{
                [signupErrors.TERMS_REQUIRED]: intl.formatMessage({
                  defaultMessage: "You must accept the terms and conditions",
                }),
              }}
            >
              {intl.formatMessage({
                defaultMessage: "I accept",
              })}
            </Checkbox>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>
                {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>
                    ),
                  }
                )}
              </p>
            </Typography>
          </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"
              variant="Primary"
              onPress={() => methods.trigger()}
              typography="Body/Paragraph/mdBold"
              data-testid="trigger-validation"
            >
              {signupButtonText}
            </Button>
          ) : (
            <Button
              className={styles.signUpButton}
              type="submit"
              variant="Primary"
              isDisabled={methods.formState.isSubmitting || signup.isPending}
              typography="Body/Paragraph/mdBold"
              data-testid="submit"
            >
              {signupButtonText}
            </Button>
          )}
        </form>
      </FormProvider>
    </div>
  )
}
