"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 { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
import { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
import { logger } from "@scandic-hotels/common/logger"
import { Alert } from "@scandic-hotels/design-system/Alert"
import { Button } from "@scandic-hotels/design-system/Button"
import { FormInput } from "@scandic-hotels/design-system/Form/FormInput"
import { TextLink } from "@scandic-hotels/design-system/TextLink"
import { toast } from "@scandic-hotels/design-system/Toast"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { trpc } from "@scandic-hotels/trpc/client"

import useLang from "@/hooks/useLang"
import { formatFormErrorMessage } from "@/utils/getErrorMessage"

import { type FindMyBookingFormSchema, findMyBookingFormSchema } from "./schema"
import { Title } from "./Title"
import { type FindMyBookingErrorEnum, getErrorMessage } from "./utils"

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

import type { AdditionalInfoCookieValue } from "@scandic-hotels/booking-flow/types/components/findMyBooking/additionalInfoCookieValue"

const DEFAULT_VALUES: FindMyBookingFormSchema = {
  confirmationNumber: "",
  firstName: "",
  lastName: "",
  email: "",
}

export default function FindMyBooking({
  error,
  defaultValues = DEFAULT_VALUES,
}: {
  error?: FindMyBookingErrorEnum
  defaultValues: AdditionalInfoCookieValue | undefined
}) {
  const router = useRouter()

  const intl = useIntl()
  const lang = useLang()
  const form = useForm<FindMyBookingFormSchema>({
    defaultValues,
    resolver: zodResolver(findMyBookingFormSchema),
    mode: "all",
    criteriaMode: "all",
    reValidateMode: "onChange",
  })

  const update = trpc.booking.createRefId.useMutation({
    onSuccess: (result) => {
      const values = form.getValues()
      const value: AdditionalInfoCookieValue = {
        ...values,
      }
      document.cookie = `bv=${JSON.stringify(value)}; Path=/; Max-Age=600; Secure; SameSite=Strict`
      router.push(`${myStay[lang]}?RefId=${encodeURIComponent(result.refId)}`)
    },
    onError: (error) => {
      logger.error("Failed to create ref id", error)
      toast.error(
        intl.formatMessage({
          id: "findMyBooking.failedToSubmit",
          defaultMessage: "Failed to submit form, please try again later.",
        })
      )
    },
  })

  async function onSubmit(data: FindMyBookingFormSchema) {
    update.mutate({
      confirmationNumber: data.confirmationNumber,
      lastName: data.lastName,
    })
  }

  const errorMessage = getErrorMessage(intl, error)

  return (
    <FormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className={styles.form}>
        <Title />
        {errorMessage ? (
          <Alert
            type={AlertTypeEnum.Alarm}
            heading={errorMessage.heading}
            text={errorMessage.text}
            className={styles.alert}
          />
        ) : null}
        <div className={[styles.inputs, styles.grid].join(" ")}>
          <FormInput
            label={intl.formatMessage({
              id: "common.bookingNumber",
              defaultMessage: "Booking number",
            })}
            name="confirmationNumber"
            registerOptions={{ required: true }}
            errorFormatter={formatFormErrorMessage}
          />
          <FormInput
            label={intl.formatMessage({
              id: "common.firstName",
              defaultMessage: "First name",
            })}
            name="firstName"
            registerOptions={{ required: true }}
            errorFormatter={formatFormErrorMessage}
          />
          <FormInput
            label={intl.formatMessage({
              id: "common.lastName",
              defaultMessage: "Last name",
            })}
            name="lastName"
            registerOptions={{ required: true }}
            errorFormatter={formatFormErrorMessage}
          />
          <FormInput
            label={intl.formatMessage({
              id: "common.email",
              defaultMessage: "Email",
            })}
            name="email"
            type="email"
            registerOptions={{ required: true }}
            errorFormatter={formatFormErrorMessage}
          />
        </div>
        <div className={styles.buttons}>
          <div className={styles.footnote}>
            <Typography variant="Body/Supporting text (caption)/smBold">
              <p>
                {intl.formatMessage({
                  id: "findMyBooking.cantFindYourStay",
                  defaultMessage: "Can't find your stay?",
                })}
              </p>
            </Typography>
            <Typography variant="Body/Supporting text (caption)/smRegular">
              <p>
                {intl.formatMessage(
                  {
                    id: "findMyBooking.customerService",
                    defaultMessage:
                      "Please contact <link>customer service</link>.",
                  },
                  {
                    link: (str) => (
                      <TextLink
                        isInline
                        href={customerService[lang]}
                        typography="Link/sm"
                        target="_blank"
                      >
                        {str}
                      </TextLink>
                    ),
                  }
                )}
              </p>
            </Typography>
          </div>
          <Button
            type="submit"
            variant="Primary"
            size="Large"
            isDisabled={form.formState.isSubmitting || update.isPending}
          >
            {intl.formatMessage({
              id: "common.find",
              defaultMessage: "Find",
            })}
          </Button>
        </div>
      </form>
    </FormProvider>
  )
}
