"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 {
  privacy,
  scandicFriends,
} from "@scandic-hotels/common/constants/routes/customerService"
import { logger } from "@scandic-hotels/common/logger"
import {
  formatPhoneNumber,
  getDefaultCountryFromLang,
} from "@scandic-hotels/common/utils/phone"
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 { FormInput } from "@scandic-hotels/design-system/Form/FormInput"
import Phone from "@scandic-hotels/design-system/Form/Phone"
import { PasswordInput } from "@scandic-hotels/design-system/PasswordInput"
import { TextLink } from "@scandic-hotels/design-system/TextLink"
import { TextLinkButton } from "@scandic-hotels/design-system/TextLinkButton"
import { toast } from "@scandic-hotels/design-system/Toast"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useFormTracking } from "@scandic-hotels/tracking/useFormTracking"
import { trpc } from "@scandic-hotels/trpc/client"
import {
  signupErrors,
  type SignUpSchema,
  signUpSchema,
} from "@scandic-hotels/trpc/routers/user/schemas"

import ProfilingConsentModalReadOnly from "@/components/MyPages/ProfilingConsent/Modal/ReadOnly"
import useLang from "@/hooks/useLang"
import { getFormattedCountryList } from "@/utils/countries"
import {
  formatFormErrorMessage,
  getErrorMessage,
} from "@/utils/getErrorMessage"
import { requestOpen } from "@/utils/profilingConsent"
import { trackLinkClick } from "@/utils/tracking/profilingConsent"

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

interface SignUpFormProps {
  title: string
}

export default function SignupForm({ title }: SignUpFormProps) {
  const intl = useIntl()
  const router = useRouter()
  const lang = useLang()

  const signupButtonText = intl.formatMessage({
    id: "signUp.joinNow",
    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({
            id: "signUp.accountExistsError",
            defaultMessage:
              "An account with this email already exists. Please try signing in instead.",
          })
        )
        return
      }

      toast.error(
        intl.formatMessage({
          id: "errorMessage.somethingWentWrong",
          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,
      profilingConsent: 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()
  }

  function openPersonalizationModal() {
    trackLinkClick({
      position: "signup",
      name: "read more about personalization at scandic",
    })
    requestOpen()
  }

  return (
    <div className={styles.formWrapper}>
      <ProfilingConsentModalReadOnly />
      {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({
                      id: "signUp.contactInformation",
                      defaultMessage: "Contact information",
                    })}
                  </h3>
                </Typography>
              </header>
              <div className={styles.nameInputs}>
                <FormInput
                  errorFormatter={formatFormErrorMessage}
                  label={intl.formatMessage({
                    id: "common.firstName",
                    defaultMessage: "First name",
                  })}
                  name="firstName"
                  registerOptions={{ required: true }}
                />
                <FormInput
                  errorFormatter={formatFormErrorMessage}
                  label={intl.formatMessage({
                    id: "common.lastName",
                    defaultMessage: "Last name",
                  })}
                  name="lastName"
                  registerOptions={{ required: true }}
                />
              </div>
            </div>
            <div className={styles.dateField}>
              <Typography variant="Body/Supporting text (caption)/smBold">
                <p>
                  {intl.formatMessage({
                    id: "common.birthDate",
                    defaultMessage: "Birth date",
                  })}
                </p>
              </Typography>
              <DateSelect
                labels={{
                  day: intl.formatMessage({
                    id: "common.day",
                    defaultMessage: "Day",
                  }),
                  month: intl.formatMessage({
                    id: "common.month",
                    defaultMessage: "Month",
                  }),
                  year: intl.formatMessage({
                    id: "common.year",
                    defaultMessage: "Year",
                  }),
                  errorMessage: getErrorMessage(
                    intl,
                    errors.dateOfBirth?.message?.toString()
                  ),
                }}
                lang={lang}
                name="dateOfBirth"
                registerOptions={{ required: true }}
              />
            </div>
            <div className={cx(styles.container, styles.additional)}>
              <FormInput
                errorFormatter={formatFormErrorMessage}
                label={intl.formatMessage({
                  id: "common.zipCode",
                  defaultMessage: "Zip code",
                })}
                name="address.zipCode"
                registerOptions={{ required: true }}
              />
              <CountrySelect
                countries={getFormattedCountryList(intl)}
                errorMessage={getErrorMessage(
                  intl,
                  errors.address?.countryCode?.message
                )}
                label={intl.formatMessage({
                  id: "common.country",
                  defaultMessage: "Country",
                })}
                lang={lang}
                name="address.countryCode"
                registerOptions={{ required: true }}
              />
              <FormInput
                errorFormatter={formatFormErrorMessage}
                label={intl.formatMessage({
                  id: "common.emailAddress",
                  defaultMessage: "Email address",
                })}
                name="email"
                type="email"
                registerOptions={{ required: true }}
              />
              <Phone
                countryLabel={intl.formatMessage({
                  id: "common.countryCode",
                  defaultMessage: "Country code",
                })}
                countriesWithTranslatedName={getFormattedCountryList(intl)}
                defaultCountryCode={getDefaultCountryFromLang(lang)}
                errorMessage={getErrorMessage(
                  intl,
                  errors.phoneNumber?.message
                )}
                label={intl.formatMessage({
                  id: "common.phoneNumber",
                  defaultMessage: "Phone number",
                })}
                name="phoneNumber"
              />
            </div>
          </section>
          <section className={styles.password}>
            <header>
              <Typography variant="Title/Subtitle/md">
                <h3>
                  {intl.formatMessage({
                    id: "common.password",
                    defaultMessage: "Password",
                  })}
                </h3>
              </Typography>
            </header>
            <PasswordInput
              name="password"
              label={intl.formatMessage({
                id: "common.password",
                defaultMessage: "Password",
              })}
              isNewPassword
              errorFormatter={formatFormErrorMessage}
            />
          </section>

          <section className={styles.personalization}>
            <header>
              <Typography variant="Title/Subtitle/md">
                <h3>
                  {intl.formatMessage({
                    id: "signup.UnlockYourPersonalizedExperience",
                    defaultMessage: "Unlock your personalized experience!",
                  })}
                </h3>
              </Typography>
            </header>
            <Checkbox
              name="profilingConsent"
              registerOptions={{ required: true }}
            >
              {intl.formatMessage({
                id: "signup.yesConsent",
                defaultMessage:
                  "I consent to Scandic using my information to give me even more personalized travel inspiration and offers from Scandic and trusted Scandic Friends partners. This means Scandic may use information about my interactions with Scandic Friends partners, and share details of my interactions with Scandic with those partners, to make the experience even more relevant to me.",
              })}
            </Checkbox>
            <TextLinkButton
              typography="Link/sm"
              color="Primary"
              className={styles.personalizationButton}
              onClick={openPersonalizationModal}
            >
              {intl.formatMessage({
                id: "signup.ReadMoreAboutPersonalization",
                defaultMessage: "Read more about personalization at Scandic",
              })}
            </TextLinkButton>
          </section>

          <section className={styles.terms}>
            <header>
              <Typography variant="Title/Subtitle/md">
                <h3>
                  {intl.formatMessage({
                    id: "signUp.termsAndConditions",
                    defaultMessage: "Terms and conditions",
                  })}
                </h3>
              </Typography>
            </header>
            <Checkbox
              name="termsAccepted"
              registerOptions={{ required: true }}
              errorCodeMessages={{
                [signupErrors.TERMS_REQUIRED]: intl.formatMessage({
                  id: "common.mustAcceptTermsError",
                  defaultMessage: "You must accept the terms and conditions",
                }),
              }}
            >
              {intl.formatMessage({
                id: "signUp.iAccept",
                defaultMessage: "I accept",
              })}
            </Checkbox>
            <Typography variant="Body/Paragraph/mdRegular">
              <p>
                {intl.formatMessage(
                  {
                    id: "signUp.termsAndConditionsDescription",
                    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) => (
                      <TextLink
                        color="Text/Interactive/Secondary"
                        target="_blank"
                        href={scandicFriends[lang]}
                        isInline
                      >
                        {str}
                      </TextLink>
                    ),
                    privacyPolicy: (str) => (
                      <TextLink
                        color="Text/Interactive/Secondary"
                        target="_blank"
                        href={privacy[lang]}
                        isInline
                      >
                        {str}
                      </TextLink>
                    ),
                  }
                )}
              </p>
            </Typography>
          </section>

          <Button
            className={styles.signUpButton}
            type="submit"
            variant="Primary"
            isDisabled={methods.formState.isSubmitting || signup.isPending}
            data-testid="submit"
          >
            {signupButtonText}
          </Button>
        </form>
      </FormProvider>
    </div>
  )
}
