"use client"

import { usePathname, useRouter } from "next/navigation"
import { useTransition } from "react"
import { Form as FormRAC } from "react-aria-components"
import { useFormContext } from "react-hook-form"

import {
  selectHotel,
  selectHotelMap,
  selectRate,
} from "@scandic-hotels/common/constants/routes/hotelReservation"
import { trackBookingSearchClick } from "@scandic-hotels/tracking/booking"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"

import { setBookingWidgetState } from "../../../hooks/useBookingWidgetState"
import useLang from "../../../hooks/useLang"
import {
  BookingCodeFilterEnum,
  useBookingCodeFilterStore,
} from "../../../stores/bookingCode-filter"
import { serializeBookingSearchParams } from "../../../utils/url"
import FormContent, { BookingWidgetFormContentSkeleton } from "./FormContent"
import { bookingWidgetVariants } from "./variants"

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

import type { BookingWidgetType } from ".."
import type { BookingWidgetSchema } from "../Client"

const formId = "booking-widget"

type BookingWidgetFormProps = {
  type?: BookingWidgetType
  isFloating: boolean
  onClose: () => void
}
export default function Form({
  type,
  isFloating,
  onClose,
}: BookingWidgetFormProps) {
  const router = useRouter()
  const pathname = usePathname()
  const lang = useLang()
  const [isPending, startTransition] = useTransition()
  const setBookingCodeFilter = useBookingCodeFilterStore(
    (state) => state.setFilter
  )

  const classNames = bookingWidgetVariants({
    type,
  })

  const { handleSubmit, setValue, reset } =
    useFormContext<BookingWidgetSchema>()

  function onSubmit(data: BookingWidgetSchema) {
    trackBookingSearchClick(data.search, data.hotel ? "hotel" : "destination")
    const isMapView = pathname.endsWith("/map")
    const bookingFlowPage = data.hotel
      ? selectRate(lang)
      : isMapView
        ? selectHotelMap(lang)
        : selectHotel(lang)
    const bookingWidgetParams = serializeBookingSearchParams({
      rooms: data.rooms,
      ...data.date,
      ...(data.city ? { city: data.city } : {}),
      ...(data.hotel ? { hotel: data.hotel } : {}),
      ...(data.bookingCode?.value
        ? { bookingCode: data.bookingCode.value }
        : {}),
      // Followed current url structure to keep searchtype=redemption param incase of reward night
      ...(data.redemption ? { searchType: SEARCH_TYPE_REDEMPTION } : {}),
    })
    setBookingWidgetState({
      fromDate: data.date.fromDate,
      toDate: data.date.toDate,
      rooms: data.rooms,
    })
    onClose()
    startTransition(() => {
      router.push(`${bookingFlowPage}?${bookingWidgetParams.toString()}`)
    })

    if (data.bookingCode?.value) {
      // Reset the booking code filter if changed by user to "All rates"
      setBookingCodeFilter(BookingCodeFilterEnum.Discounted)

      if (data.bookingCode.remember) {
        localStorage.setItem("bookingCode", JSON.stringify(data.bookingCode))
      }
    } else {
      setValue("bookingCode.remember", false, {
        shouldDirty: true,
      })
      localStorage.removeItem("bookingCode")
    }
    reset(data)
  }

  return (
    <section className={classNames}>
      <FormRAC
        onSubmit={handleSubmit(onSubmit)}
        className={styles.form}
        id={formId}
      >
        <FormContent
          formId={formId}
          onSubmit={handleSubmit(onSubmit)}
          isSearching={isPending}
          isFloating={isFloating}
        />
      </FormRAC>
    </section>
  )
}

export function BookingWidgetFormSkeleton({
  type,
}: {
  type: BookingWidgetType
}) {
  const classNames = bookingWidgetVariants({
    type,
  })

  return (
    <section className={classNames}>
      <form className={styles.form}>
        <BookingWidgetFormContentSkeleton />
      </form>
    </section>
  )
}
