import { cookies } from "next/headers"
import { notFound } from "next/navigation"

import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { dt } from "@scandic-hotels/common/dt"
import * as maskValue from "@scandic-hotels/common/utils/maskValue"
import ScandicLogoIcon from "@scandic-hotels/design-system/Icons/ScandicLogoIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { parseRefId } from "@scandic-hotels/trpc/utils/refId"

import {
  findBooking,
  getAncillaryPackages,
  getBookingConfirmation,
  getProfileSafely,
} from "@/lib/trpc/memoizedRequests"

import AdditionalInfoForm from "@/components/HotelReservation/FindMyBooking/AdditionalInfoForm"
import { getIntl } from "@/i18n"
import { isLoggedInUser } from "@/utils/isLoggedInUser"

import accessBooking, {
  ACCESS_GRANTED,
  ERROR_BAD_REQUEST,
  ERROR_UNAUTHORIZED,
} from "../accessBooking"
import Footer from "./Footer"
import Specification from "./Specification"
import Total from "./Total"
import Tracking from "./tracking"

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

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

export async function Receipt({ refId }: { refId: string }) {
  const { confirmationNumber, lastName } = parseRefId(refId)

  if (!confirmationNumber) {
    return notFound()
  }

  const isLoggedIn = await isLoggedInUser()

  const cookieStore = await cookies()
  const bv = cookieStore.get("bv")?.value
  let bookingConfirmation
  if (isLoggedIn) {
    bookingConfirmation = await getBookingConfirmation(refId)
  } else if (bv) {
    const values = JSON.parse(bv) as AdditionalInfoCookieValue
    const firstName = values.firstName
    const email = values.email

    if (firstName && email) {
      bookingConfirmation = await findBooking(
        confirmationNumber,
        lastName,
        firstName,
        email
      )
    } else {
      return (
        <RenderAdditionalInfoForm
          confirmationNumber={confirmationNumber}
          lastName={lastName}
        />
      )
    }
  } else {
    return (
      <RenderAdditionalInfoForm
        confirmationNumber={confirmationNumber}
        lastName={lastName}
      />
    )
  }
  if (!bookingConfirmation) {
    return notFound()
  }

  const { hotel, room, booking } = bookingConfirmation
  const user = await getProfileSafely()
  const intl = await getIntl()

  const access = accessBooking(booking.guest, lastName, user, bv)

  if (access === ACCESS_GRANTED) {
    const ancillaryPackages = await getAncillaryPackages({
      fromDate: dt(booking.checkInDate).format("YYYY-MM-DD"),
      hotelId: hotel.operaId,
      toDate: dt(booking.checkOutDate).format("YYYY-MM-DD"),
    })

    const currency =
      booking.currencyCode !== CurrencyEnum.POINTS
        ? booking.currencyCode
        : (booking.ancillaries.find((a) => a.currency !== CurrencyEnum.POINTS)
            ?.currency ??
          booking.packages.find((p) => p.currency !== CurrencyEnum.POINTS)
            ?.currency)

    const maskedBookingConfirmation = {
      ...bookingConfirmation,
      booking: {
        ...bookingConfirmation.booking,
        guest: {
          ...bookingConfirmation.booking.guest,
          email: maskValue.email(bookingConfirmation.booking.guest.email),
          phoneNumber: maskValue.phone(
            bookingConfirmation.booking.guest.phoneNumber ?? ""
          ),
        },
      },
    } satisfies BookingConfirmation

    const { booking: maskedBooking } = maskedBookingConfirmation

    return (
      <main className={styles.main}>
        <div>
          <ScandicLogoIcon width="89px" height="19px" />
          <div className={styles.addresses}>
            <div>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div>{hotel.name}</div>
              </Typography>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div>
                  {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                  {`${hotel.address.streetAddress}, ${hotel.address.zipCode} ${hotel.address.city}`}
                </div>
              </Typography>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div className={`${styles.tertiary} ${styles.addressMargin}`}>
                  {hotel.contactInformation.email}
                </div>
              </Typography>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div className={styles.tertiary}>
                  {hotel.contactInformation.phoneNumber}
                </div>
              </Typography>
            </div>
            <div className={styles.rightColumn}>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                <div>{`${maskedBooking.guest.firstName} ${maskedBooking.guest.lastName}`}</div>
              </Typography>
              {maskedBooking.guest.membershipNumber && (
                <Typography variant="Body/Supporting text (caption)/smRegular">
                  {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
                  <div>{`${intl.formatMessage({
                    defaultMessage: "Member",
                  })} ${maskedBooking.guest.membershipNumber}`}</div>
                </Typography>
              )}
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div className={`${styles.tertiary} ${styles.addressMargin}`}>
                  {maskedBooking.guest.email}
                </div>
              </Typography>
              <Typography variant="Body/Supporting text (caption)/smRegular">
                <div className={styles.tertiary}>
                  {maskedBooking.guest.phoneNumber}
                </div>
              </Typography>
            </div>
          </div>
        </div>
        <Total booking={maskedBooking} currency={currency} />
        <Specification
          ancillaryPackages={ancillaryPackages}
          booking={maskedBooking}
          currency={currency}
        />

        <hr className={styles.divider} />

        <Footer booking={maskedBooking} room={room} />
        <Tracking />
      </main>
    )
  }

  if (access === ERROR_BAD_REQUEST) {
    return (
      <main className={styles.main}>
        <div className={styles.form}>
          <AdditionalInfoForm
            confirmationNumber={confirmationNumber}
            lastName={lastName}
          />
        </div>
      </main>
    )
  }

  if (access === ERROR_UNAUTHORIZED) {
    return (
      <main className={styles.main}>
        <div className={styles.logIn}>
          <Typography variant="Title/md">
            <h1>
              {intl.formatMessage({
                defaultMessage: "You need to be logged in to view your booking",
              })}
            </h1>
          </Typography>
          <Typography variant="Body/Lead text">
            <p>
              {intl.formatMessage({
                defaultMessage:
                  "And you need to be logged in with the same member account that made the booking.",
              })}
            </p>
          </Typography>
        </div>
      </main>
    )
  }

  return notFound()
}

function RenderAdditionalInfoForm({
  confirmationNumber,
  lastName,
}: {
  confirmationNumber: string
  lastName: string
}) {
  return (
    <main className={styles.main}>
      <div className={styles.form}>
        <AdditionalInfoForm
          confirmationNumber={confirmationNumber}
          lastName={lastName}
        />
      </div>
    </main>
  )
}
