import {
  type Facilities,
  type FacilityCard,
  FacilityCardButtonText,
  type FacilityCardType,
  FacilityCardTypeEnum,
  type FacilityGrid,
  type FacilityImage,
  HealthFacilitiesEnum,
  MeetingsHeading,
  RestaurantHeadings,
  WellnessHeadings,
} from "@/types/components/hotelPage/facilities"
import {
  type HotelHashValue,
  SidepeekSlugs,
} from "@/types/components/hotelPage/hotelPage";
import type { HotelPageSections } from "@/types/components/hotelPage/sections"
import { FacilityEnum } from "@/types/enums/facilities"
import { HotelHashValues } from "@/types/enums/hotelPage"
import type {
  Amenities,
  Facility,
  FacilityData,
  HealthFacilities,
} from "@/types/hotel"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"

export function setFacilityCards(
  restaurantImages: FacilityData | undefined,
  conferencesAndMeetings: FacilityData | undefined,
  healthAndWellness: FacilityData | undefined,
  pageSections: HotelPageSections
): Facility[] {
  const facilities = []
  if (pageSections.restaurant) {
    facilities.push(
      setFacilityCard(
        restaurantImages,
        FacilityCardTypeEnum.restaurant,
        pageSections.restaurant.heading
      )
    )
  }
  if (pageSections.meetings) {
    facilities.push(
      setFacilityCard(
        conferencesAndMeetings,
        FacilityCardTypeEnum.conference,
        pageSections.meetings.heading
      )
    )
  }
  if (pageSections.wellness) {
    facilities.push(
      setFacilityCard(
        healthAndWellness,
        FacilityCardTypeEnum.wellness,
        pageSections.wellness.heading
      )
    )
  }
  return facilities
}

function setFacilityCard(
  facility: FacilityData | undefined,
  type: FacilityCardTypeEnum,
  heading: string
): Facility {
  return {
    ...facility,
    id: type,
    headingText: heading,
    heroImages: facility?.heroImages ?? [],
  }
}

export function isFacilityCard(card: FacilityCardType): card is FacilityCard {
  return "heading" in card
}

export function isFacilityImage(card: FacilityCardType): card is FacilityImage {
  return "backgroundImage" in card
}

function setCardProps(
  theme: CardProps["theme"],
  buttonText: (typeof FacilityCardButtonText)[keyof typeof FacilityCardButtonText],
  href: HotelHashValue,
  heading: string,
  slug: SidepeekSlugs,
  scriptedTopTitle?: string
): FacilityCard {
  return {
    theme,
    id: href,
    heading,
    scriptedTopTitle,
    secondaryButton: {
      href: `?s=${slug}`,
      title: buttonText,
      isExternal: false,
      scrollOnClick: false,
    },
  }
}

export function setFacilityCardGrids(
  facilities: Facility[],
  amenities: Amenities,
  healthFacilities: HealthFacilities
): Facilities {
  const cards: Facilities = facilities
    .filter((fac) => !!fac.headingText)
    .map((facility) => {
      let card: FacilityCard

      const grid: FacilityGrid = facility.heroImages
        .slice(0, 2)
        .map((image) => {
          // Can be a maximum 2 images per grid
          const img: FacilityImage = {
            backgroundImage: {
              url: image.imageSizes.large,
              title: image.metaData.title,
              meta: {
                alt: image.metaData.altText,
                caption: image.metaData.altText_En,
              },
              id: image.imageSizes.large,
            },
            theme: "image",
            id: image.imageSizes.large,
          }
          return img
        })

      switch (facility.id) {
        case FacilityCardTypeEnum.wellness:
          const wellnessTitle = getWellnessHeading(healthFacilities)
          card = setCardProps(
            "one",
            FacilityCardButtonText.WELLNESS,
            HotelHashValues.wellness,
            facility.headingText,
            SidepeekSlugs.wellness,
            wellnessTitle
          )
          facilities.findIndex((f) => f === facility) % 2 === 0
            ? grid.unshift(card)
            : grid.push(card)

          break

        case FacilityCardTypeEnum.conference:
          card = setCardProps(
            "primaryDim",
            FacilityCardButtonText.MEETINGS,
            HotelHashValues.meetings,
            facility.headingText,
            SidepeekSlugs.meetings,
            MeetingsHeading.Default
          )
          facilities.findIndex((f) => f === facility) % 2 === 0
            ? grid.unshift(card)
            : grid.push(card)
          break

        case FacilityCardTypeEnum.restaurant:
          const restaurantTitle = getRestaurantHeading(amenities)
          card = setCardProps(
            "primaryDark",
            FacilityCardButtonText.RESTAURANT,
            HotelHashValues.restaurant,
            facility.headingText,
            SidepeekSlugs.restaurant,
            restaurantTitle
          )
          facilities.findIndex((f) => f === facility) % 2 === 0
            ? grid.unshift(card)
            : grid.push(card)
          break
      }
      return grid
    })
  return cards
}

function getRestaurantHeading(amenities: Amenities): RestaurantHeadings {
  // For now return a generic message for all
  return RestaurantHeadings.generic

  // TODO: Revisit logic below when Content team decides to do so.
  const hasBar = amenities.some(
    (facility) =>
      facility.id === FacilityEnum.Bar ||
      facility.id === FacilityEnum.RooftopBar ||
      facility.id === FacilityEnum.Skybar
  )
  const hasRestaurant = amenities.some(
    (facility) => facility.id === FacilityEnum.Restaurant
  )

  if (hasBar && hasRestaurant) {
    return RestaurantHeadings.restaurantAndBar
  } else if (hasBar) {
    return RestaurantHeadings.bar
  } else if (hasRestaurant) {
    return RestaurantHeadings.restaurant
  }
  return RestaurantHeadings.breakfastRestaurant
}

export function getWellnessHeading(
  healthFacilities: HealthFacilities
): WellnessHeadings | undefined {
  // For now return a generic message for all
  return WellnessHeadings.generic

  // TODO: Revisit logic below when Content team decides to do so.
  const hasGym = healthFacilities.some(
    (facility) => facility.type === HealthFacilitiesEnum.Gym
  )
  const hasSauna = healthFacilities.some(
    (faility) => faility.type === HealthFacilitiesEnum.Sauna
  )
  const hasRelax = healthFacilities.some(
    (facility) => facility.type === HealthFacilitiesEnum.Relax
  )
  const hasJacuzzi = healthFacilities.some(
    (facility) => facility.type === HealthFacilitiesEnum.Jacuzzi
  )
  const hasPool = healthFacilities.some(
    (facility) =>
      facility.type === HealthFacilitiesEnum.IndoorPool ||
      facility.type === HealthFacilitiesEnum.OutdoorPool
  )

  if (hasGym && hasJacuzzi && hasSauna && hasRelax) {
    return WellnessHeadings.GymJacuzziSaunaRelax
  } else if (hasGym && hasPool && hasSauna && hasRelax) {
    return WellnessHeadings.GymPoolSaunaRelax
  } else if (hasGym && hasSauna) {
    return WellnessHeadings.GymSauna
  } else if (hasGym && hasPool) {
    return WellnessHeadings.GymPool
  }
  return undefined
}

export function filterFacilityCards(cards: FacilityGrid) {
  const card = cards.filter((card) => isFacilityCard(card))
  const images = cards.filter((card) => isFacilityImage(card))

  return {
    card: card[0] as FacilityCard,
    images: images as FacilityImage[],
  }
}
