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

import { Typography } from "@scandic-hotels/design-system/Typography"

import { PaymentMethodEnum } from "@/constants/booking"
import { guaranteeCallback } from "@/constants/routes/hotelReservation"
import { bookingTermsAndConditions, privacyPolicy } from "@/constants/webHrefs"
import { env } from "@/env/client"
import { useMyStayStore } from "@/stores/my-stay"

import { writeGlaToSessionStorage } from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback/helpers"
import PaymentOptionsGroup from "@/components/HotelReservation/EnterDetails/Payment/PaymentOptionsGroup"
import MySavedCards from "@/components/HotelReservation/MySavedCards"
import PaymentOption from "@/components/HotelReservation/PaymentOption"
import LoadingSpinner from "@/components/LoadingSpinner"
import Divider from "@/components/TempDesignSystem/Divider"
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
import Link from "@/components/TempDesignSystem/Link"
import { toast } from "@/components/TempDesignSystem/Toasts"
import { useGuaranteeBooking } from "@/hooks/booking/useGuaranteeBooking"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import { trackGlaSaveCardAttempt } from "@/utils/tracking/myStay"

import { type GuaranteeFormData, paymentSchema } from "./schema"

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

export default function Form() {
  const intl = useIntl()
  const lang = useLang()

  const { confirmationNumber, currencyCode, hotelId, refId, savedCreditCards } =
    useMyStayStore((state) => ({
      confirmationNumber: state.bookedRoom.confirmationNumber,
      currencyCode: state.bookedRoom.currencyCode,
      hotelId: state.bookedRoom.hotelId,
      refId: state.bookedRoom.refId,
      savedCreditCards: state.savedCreditCards,
    }))

  const methods = useForm<GuaranteeFormData>({
    defaultValues: {
      paymentMethod: savedCreditCards?.length
        ? savedCreditCards[0].id
        : PaymentMethodEnum.card,
      termsAndConditions: false,
    },
    mode: "all",
    reValidateMode: "onChange",
    resolver: zodResolver(paymentSchema),
  })

  const guaranteeRedirectUrl = `${env.NEXT_PUBLIC_NODE_ENV === "development" ? `http://localhost:${env.NEXT_PUBLIC_PORT}` : ""}${guaranteeCallback(lang)}`

  const { guaranteeBooking, isLoading, handleGuaranteeError } =
    useGuaranteeBooking(refId, false, hotelId)

  if (isLoading) {
    return (
      <div className={styles.loading}>
        <LoadingSpinner />
      </div>
    )
  }

  function handleGuaranteeLateArrival(data: GuaranteeFormData) {
    const savedCreditCard = savedCreditCards?.find(
      (card) => card.id === data.paymentMethod
    )
    trackGlaSaveCardAttempt(hotelId, savedCreditCard, "yes")
    if (confirmationNumber) {
      const card = savedCreditCard
        ? {
            alias: savedCreditCard.alias,
            expiryDate: savedCreditCard.expirationDate,
            cardType: savedCreditCard.cardType,
          }
        : undefined
      writeGlaToSessionStorage("yes", hotelId)
      guaranteeBooking.mutate({
        refId,
        language: lang,
        ...(card && { card }),
        success: `${guaranteeRedirectUrl}?status=success&RefId=${encodeURIComponent(refId)}`,
        error: `${guaranteeRedirectUrl}?status=error&RefId=${encodeURIComponent(refId)}`,
        cancel: `${guaranteeRedirectUrl}?status=cancel&RefId=${encodeURIComponent(refId)}`,
      })
    } else {
      handleGuaranteeError("No confirmation number")
      toast.error(
        intl.formatMessage({
          defaultMessage: "Something went wrong!",
        })
      )
    }
  }

  const guaranteeMsg = intl.formatMessage(
    {
      defaultMessage:
        "I accept the terms for this stay and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand Scandic will process my personal data for this stay in accordance with <privacyPolicyLink>Scandic's Privacy Policy</privacyPolicyLink>. ",
    },
    {
      termsAndConditionsLink: (str) => (
        <Link
          textDecoration="underline"
          color="Text/Interactive/Secondary"
          target="_blank"
          href={bookingTermsAndConditions[lang]}
          onClick={(e) => e.stopPropagation()}
        >
          {str}
        </Link>
      ),
      privacyPolicyLink: (str) => (
        <Link
          textDecoration="underline"
          color="Text/Interactive/Secondary"
          target="_blank"
          href={privacyPolicy[lang]}
          onClick={(e) => e.stopPropagation()}
        >
          {str}
        </Link>
      ),
    }
  )

  return (
    <FormProvider {...methods}>
      <form
        className={styles.form}
        id="guarantee"
        onSubmit={methods.handleSubmit(handleGuaranteeLateArrival)}
      >
        {savedCreditCards?.length ? (
          <MySavedCards savedCreditCards={savedCreditCards} />
        ) : null}
        <PaymentOptionsGroup
          name="paymentMethod"
          label={
            savedCreditCards?.length
              ? intl.formatMessage({
                  defaultMessage: "OTHER",
                })
              : undefined
          }
        >
          <PaymentOption
            value={PaymentMethodEnum.card}
            label={intl.formatMessage({
              defaultMessage: "Credit card",
            })}
          />
        </PaymentOptionsGroup>
        <div className={styles.termsAndConditions}>
          <Checkbox className={styles.checkbox} name="termsAndConditions">
            <Typography variant="Body/Supporting text (caption)/smRegular">
              <p>{guaranteeMsg}</p>
            </Typography>
          </Checkbox>
        </div>
        <div className={styles.guaranteeCost}>
          <div className={styles.guaranteeCostText}>
            <Typography variant="Body/Supporting text (caption)/smBold">
              <span className={styles.textDefault}>
                {intl.formatMessage({
                  defaultMessage: "Total due",
                })}
              </span>
            </Typography>
            <Typography variant="Body/Supporting text (caption)/smRegular">
              <span className={styles.textDefault}>
                {intl.formatMessage({
                  defaultMessage:
                    "Your card will only be charged in the event of a no-show",
                })}
              </span>
            </Typography>
          </div>
          <Divider variant="vertical" color="subtle" />
          <Typography variant="Title/Subtitle/md">
            <span className={styles.baseTextHighContrast}>
              {formatPrice(intl, 0, currencyCode)}
            </span>
          </Typography>
        </div>
      </form>
    </FormProvider>
  )
}
