import type { ListingCard } from "~/types/listing"
import { buildListingFilterFacets, createListingFilterState, filterListingItems, medianListingPrice } from "~/utils/listing-filters"

export function useLocalListingBrowser(items: MaybeRefOrGetter<ListingCard[]>, pageSize = 12) {
  const currency = new Intl.NumberFormat("es-CL", {
    style: "currency",
    currency: "CLP",
    maximumFractionDigits: 0
  })

  const filters = ref(createListingFilterState())
  const currentPage = ref(1)

  const sourceItems = computed(() => toValue(items))
  const facets = computed(() => buildListingFilterFacets(sourceItems.value))
  const filteredItems = computed(() => filterListingItems(sourceItems.value, filters.value))
  const total = computed(() => filteredItems.value.length)
  const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)))
  const pagedItems = computed(() => filteredItems.value.slice((currentPage.value - 1) * pageSize, currentPage.value * pageSize))
  const medianPrice = computed(() => medianListingPrice(filteredItems.value.map((item) => item.priceClp)))
  const cheapest = computed(() => filteredItems.value[0]?.priceClp ?? 0)

  const hasPriceFilter = computed(() => {
    const facetMaxPrice = facets.value.maxPrice
    return Boolean(filters.value.maxPrice && facetMaxPrice && filters.value.maxPrice < facetMaxPrice)
  })

  const hasActiveFilters = computed(() =>
    Boolean(
      filters.value.q ||
      filters.value.source ||
      filters.value.make ||
      filters.value.transmission ||
      filters.value.fuel ||
      filters.value.minYear ||
      filters.value.maxYear ||
      hasPriceFilter.value
    )
  )

  const priceLabel = computed(() => {
    if (!filters.value.maxPrice) {
      return "Sin tope"
    }

    return currency.format(filters.value.maxPrice)
  })

  const previousPage = () => {
    currentPage.value = Math.max(1, currentPage.value - 1)
  }

  const nextPage = () => {
    currentPage.value = Math.min(totalPages.value, currentPage.value + 1)
  }

  const clearFilters = () => {
    filters.value = createListingFilterState({
      maxPrice: facets.value.maxPrice || null
    })
    currentPage.value = 1
  }

  watch(filters, () => {
    currentPage.value = 1
  }, { deep: true })

  watch(() => totalPages.value, (value) => {
    currentPage.value = Math.min(currentPage.value, value)
  })

  watch(() => facets.value.maxPrice, (value) => {
    if (!value) {
      filters.value.maxPrice = null
      return
    }

    if (filters.value.maxPrice == null || filters.value.maxPrice > value) {
      filters.value.maxPrice = value
    }
  }, { immediate: true })

  return {
    filters,
    facets,
    filteredItems,
    pagedItems,
    total,
    totalPages,
    currentPage,
    medianPrice,
    cheapest,
    priceLabel,
    hasActiveFilters,
    clearFilters,
    previousPage,
    nextPage,
    pageSize
  }
}
