"use client"

import { usePathname, useSearchParams } from "next/navigation"
import { useEffect } from "react"
import { useIntl } from "react-intl"

import { useHotelFilterStore } from "@/stores/hotel-filters"

import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import useInitializeFiltersFromUrl from "@/hooks/useInitializeFiltersFromUrl"
import { trackEvent } from "@/utils/tracking/base"

import FilterCheckbox from "./FilterCheckbox"

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

import type {
  HotelFilter,
  HotelFiltersProps,
} from "@/types/components/hotelReservation/selectHotel/hotelFilters"

export default function HotelFilter({ className, filters }: HotelFiltersProps) {
  const intl = useIntl()
  const searchParams = useSearchParams()
  const pathname = usePathname()
  const toggleFilter = useHotelFilterStore((state) => state.toggleFilter)
  useInitializeFiltersFromUrl()
  const activeFilters = useHotelFilterStore((state) => state.activeFilters)
  const facilityMap = new Map(
    filters.facilityFilters.map((f) => [f.id.toString(), f.name])
  )
  const surroundingsMap = new Map(
    filters.surroundingsFilters.map((f) => [f.id.toString(), f.name])
  )

  function trackFiltersEvent() {
    const hotelFacilitiesFilter = activeFilters
      .filter((id) => facilityMap.has(id))
      .map((id) => facilityMap.get(id))
      .join(",")

    const hotelSurroundingsFilter = activeFilters
      .filter((id) => surroundingsMap.has(id))
      .map((id) => surroundingsMap.get(id))
      .join(",")

    trackEvent({
      event: "filterUsed",
      filter: {
        filtersUsed: `Filters values - hotelfacilities:${hotelFacilitiesFilter}|hotelsurroundings:${hotelSurroundingsFilter}`,
      },
    })
  }

  // Update the URL when the filters changes
  useEffect(() => {
    const newSearchParams = new URLSearchParams(searchParams)
    const values = activeFilters.join(",")

    if (values === "") {
      newSearchParams.delete("filters")
    } else {
      trackFiltersEvent()
      newSearchParams.set("filters", values)
    }

    if (values !== searchParams.values.toString()) {
      window.history.replaceState(
        null,
        "",
        `${pathname}?${newSearchParams.toString()}`
      )
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeFilters])

  if (!filters.facilityFilters.length && !filters.surroundingsFilters.length) {
    return null
  }

  let filteredHotelIds: string[] | undefined
  if (activeFilters.length) {
    const allFilters = [
      ...filters.facilityFilters,
      ...filters.surroundingsFilters,
    ]
    filteredHotelIds = allFilters
      .filter((f) => activeFilters.includes(f.id.toString()))
      .map((f) => f.hotelIds)
      .reduce((accumlatedHotelIds, currentHotelIds) =>
        accumlatedHotelIds?.filter((hotelId) =>
          currentHotelIds?.includes(hotelId)
        )
      )
  }

  function filterOutput(filters: HotelFilter[]) {
    return filters.map((filter) => {
      const isDisabled = filteredHotelIds?.length
        ? !filter.hotelIds?.some((hotelId) =>
            filteredHotelIds.includes(hotelId)
          )
        : false
      return (
        <li key={`li-${filter.id}`} className={styles.filter}>
          <FilterCheckbox
            name={filter.name}
            id={filter.id.toString()}
            onChange={() => toggleFilter(filter.id.toString())}
            isSelected={activeFilters.some((f) => f === filter.id.toString())}
            isDisabled={isDisabled}
          />
          {!isDisabled ? (
            // eslint-disable-next-line formatjs/no-literal-string-in-jsx
            <span>{`(${filteredHotelIds?.filter((id) => filter.hotelIds.includes(id))?.length ?? filter.hotelIds.length})`}</span>
          ) : null}
        </li>
      )
    })
  }

  return (
    <aside className={`${styles.container} ${className}`}>
      <form>
        <Title as="h4">
          {intl.formatMessage({
            defaultMessage: "Filter by",
          })}
        </Title>
        <div className={styles.facilities}>
          <Subtitle>
            {intl.formatMessage({
              defaultMessage: "Hotel facilities",
            })}
          </Subtitle>
          <ul>{filterOutput(filters.facilityFilters)}</ul>
        </div>

        <div className={styles.facilities}>
          <Subtitle>
            {intl.formatMessage({
              defaultMessage: "Hotel surroundings",
            })}
          </Subtitle>
          <ul>{filterOutput(filters.surroundingsFilters)}</ul>
        </div>
      </form>
    </aside>
  )
}
