import type {
  BreakfastPackage,
  BreakfastPackages,
} from "@/types/components/hotelReservation/breakfast"
import type {
  BedTypeSchema,
  BedTypeSelection,
} from "@/types/components/hotelReservation/enterDetails/bedType"
import type {
  DetailsBooking,
  DetailsSchema,
  MultiroomDetailsSchema,
  RoomPrice,
  RoomRate,
  SignedInDetailsSchema,
} from "@/types/components/hotelReservation/enterDetails/details"
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
import type { StepEnum } from "@/types/enums/step"
import type { Price } from "../components/hotelReservation/price"
import type { CurrencyEnum } from "../enums/currency"
import type { Packages } from "../requests/packages"

export interface InitialRoomData {
  // used when there is only one bedtype to preselect it
  bedType?: BedTypeSchema
  bedTypes: BedTypeSelection[]
  breakfastIncluded: boolean
  cancellationText: string
  cancellationRule?: string
  isAvailable: boolean
  isFlexRate: boolean
  mustBeGuaranteed: boolean
  memberMustBeGuaranteed?: boolean
  rateDetails: string[] | undefined
  memberRateDetails?: string[]
  rateTitle?: string
  roomFeatures: Packages | null
  roomRate: RoomRate
  roomType: string
  roomTypeCode: string
}

export type RoomStep = {
  step: StepEnum
  isValid: boolean
}

export interface Room extends InitialRoomData {
  adults: number
  bedType: BedTypeSchema | undefined
  breakfast: BreakfastPackage | false | undefined
  childrenInRoom: Child[] | undefined
  guest: DetailsSchema | MultiroomDetailsSchema | SignedInDetailsSchema
  roomPrice: RoomPrice
  specialRequest: {
    comment: string
  }
}

export interface RoomState {
  actions: {
    setIncomplete: () => void
    updateBedType: (data: BedTypeSchema) => void
    updateBreakfast: (data: BreakfastPackage | false) => void
    updateJoin: (join: boolean) => void
    updatePriceForMembershipNo: (membershipNo: string, isValid: boolean) => void
    updateDetails: (data: DetailsSchema) => void
  }
  isComplete: boolean
  room: Room
  steps: {
    [StepEnum.selectBed]: RoomStep
    [StepEnum.breakfast]?: RoomStep
    [StepEnum.details]: RoomStep
  }
}

export type InitialState = {
  booking: DetailsBooking
  rooms: InitialRoomData[]
  vat: number
}

export interface DetailsState {
  actions: {
    setIsSubmitting: (isSubmitting: boolean) => void
    setTotalPrice: (totalPrice: Price) => void
    toggleSummaryOpen: () => void
    updateSeachParamString: (searchParamString: string) => void
    addPreSubmitCallback: (name: string, callback: () => void) => void
  }
  availableBeds: Record<string, number>
  booking: DetailsBooking
  breakfastPackages: BreakfastPackages
  canProceedToPayment: boolean
  isSubmitting: boolean
  isSummaryOpen: boolean
  lastRoom: number
  rooms: RoomState[]
  searchParamString: string
  totalPrice: Price
  vat: number
  defaultCurrency: CurrencyEnum
  preSubmitCallbacks: Record<string, () => void>
}

export type PersistedState = {
  booking: DetailsBooking
  rooms: RoomState[]
}
