<template>
    <div ref="popoverRoot">
        <div class="flex flex-wrap items-center justify-end gap-2 md:gap-2.5 py-2 border-b border-zinc-200">
            <button
                :aria-expanded="open"
                :class="{ 'is-active': activeCount > 0 || open }"
                aria-controls="post-search-filters-panel"
                aria-haspopup="dialog"
                class="pill !rounded-xl"
                type="button"
                @click="open = !open"
            >
                <iconify-icon class="text-sm opacity-70" icon="lucide:sliders-horizontal"></iconify-icon>
                <span class="text-sm font-medium">Filters</span>
                <span
                    v-if="activeCount > 0"
                    class="inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-accent text-accent-foreground text-xs font-semibold"
                    aria-label="Active filter count"
                >
                    {{ activeCount }}
                </span>
                <iconify-icon
                    :class="open ? 'rotate-180' : ''"
                    class="text-sm opacity-50 transition-transform duration-200"
                    icon="lucide:chevron-down"
                ></iconify-icon>
            </button>

        </div>

        <div
            v-if="open"
            id="post-search-filters-panel"
            role="dialog"
            aria-label="Filters"
            class="mt-3 rounded-2xl border border-zinc-200 bg-white shadow-sm p-4 space-y-4 max-h-[70vh] overflow-y-auto"
        >
                <div>
                    <span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">Fuel</span>
                    <div class="grid grid-cols-2 sm:grid-cols-3 gap-2" role="radiogroup" aria-label="Fuel type">
                        <button
                            v-for="fuel in FUEL_TYPES"
                            :key="fuel.value"
                            :aria-checked="fuelType === fuel.value"
                            :class="{ 'is-active': fuelType === fuel.value }"
                            class="pill-sm"
                            role="radio"
                            type="button"
                            @click="fuelType = fuel.value"
                        >
                            {{ fuel.label }}
                        </button>
                    </div>
                </div>

                <div>
                    <span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">Radius</span>
                    <div class="grid grid-cols-3 gap-2" role="radiogroup" aria-label="Search radius">
                        <button
                            v-for="option in [5, 10, 20]"
                            :key="option"
                            :aria-checked="radius === option"
                            :class="{ 'is-active': radius === option }"
                            class="pill-sm"
                            role="radio"
                            type="button"
                            @click="radius = option"
                        >
                            {{ option }} miles
                        </button>
                    </div>
                </div>

                <div>
                    <span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">Sort by</span>
                    <div class="grid grid-cols-2 sm:grid-cols-4 gap-2" role="radiogroup" aria-label="Sort by">
                        <button
                            v-for="option in sortOptions"
                            :key="option.value"
                            :aria-checked="sort === option.value"
                            :class="{ 'is-active': sort === option.value }"
                            class="pill-sm"
                            role="radio"
                            type="button"
                            @click="sort = option.value"
                        >
                            <iconify-icon :icon="option.icon" class="text-sm opacity-70"></iconify-icon>
                            <span>{{ option.label }}</span>
                        </button>
                    </div>
                </div>

                <div v-if="brands.length > 1">
                    <span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">Brand</span>
                    <div class="flex flex-wrap gap-2" role="radiogroup" aria-label="Filter by brand">
                        <button
                            :aria-checked="!brandFilter"
                            :class="{ 'is-active': !brandFilter }"
                            class="pill-sm"
                            role="radio"
                            type="button"
                            @click="selectBrand('')"
                        >
                            All brands
                        </button>
                        <button
                            v-for="brand in brands"
                            :key="brand"
                            :aria-checked="brandFilter === brand"
                            :class="{ 'is-active': brandFilter === brand }"
                            class="pill-sm"
                            role="radio"
                            type="button"
                            @click="selectBrand(brand)"
                        >
                            {{ brand }}
                        </button>
                    </div>
                </div>

                <div class="flex items-center justify-between pt-2 border-t border-zinc-200">
                    <button
                        v-if="hasActive"
                        class="inline-flex items-center gap-1 text-sm text-zinc-500 hover:text-zinc-900 transition-colors cursor-pointer"
                        type="button"
                        @click="resetFilters"
                    >
                        <iconify-icon class="text-sm" icon="lucide:x"></iconify-icon>
                        Clear all
                    </button>
                    <span v-else class="text-sm text-zinc-400">No filters applied</span>

                    <button
                        class="inline-flex items-center h-9 px-4 rounded-full bg-accent text-accent-foreground text-sm font-medium hover:bg-accent-content transition-colors cursor-pointer"
                        type="button"
                        @click="open = false"
                    >
                        Done
                    </button>
                </div>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
import { FUEL_TYPES } from '../constants/fuelTypes.js'

const DEFAULTS = Object.freeze({
    fuelType: 'e10',
    radius: 10,
    sort: 'reliable',
})

const sortOptions = [
    { label: 'Reliable', value: 'reliable', icon: 'lucide:shield-check' },
    { label: 'Price', value: 'price', icon: 'lucide:pound-sterling' },
    { label: 'Distance', value: 'distance', icon: 'lucide:map-pin' },
    { label: 'Updated', value: 'updated', icon: 'lucide:clock' },
]

const props = defineProps({
    initial: { type: Object, default: () => ({}) },
    brands: { type: Array, default: () => [] },
    brandFilter: { type: String, default: '' },
})

const emit = defineEmits(['search', 'update:brandFilter'])

const postcode = ref('')
const coords = ref(null)
const fuelType = ref(DEFAULTS.fuelType)
const radius = ref(DEFAULTS.radius)
const sort = ref(DEFAULTS.sort)

const open = ref(false)
const popoverRoot = ref(null)

let hydrating = false

watch(() => props.initial, (v) => {
    if (!v) return
    hydrating = true
    if (typeof v.postcode === 'string') postcode.value = v.postcode
    if (v.lat != null && v.lng != null) coords.value = { lat: v.lat, lng: v.lng }
    if (v.fuelType) fuelType.value = v.fuelType
    if (v.radius != null) radius.value = Number(v.radius)
    if (v.sort) sort.value = v.sort
    nextTick(() => { hydrating = false })
}, { immediate: true, deep: true })

watch([fuelType, radius, sort], () => {
    if (hydrating) return
    open.value = false
    if (postcode.value.trim() || coords.value) emitSearch()
})

const hasActive = computed(() => (
    fuelType.value !== DEFAULTS.fuelType
    || radius.value !== DEFAULTS.radius
    || sort.value !== DEFAULTS.sort
    || Boolean(props.brandFilter)
))

const activeCount = computed(() => {
    let count = 0
    if (fuelType.value !== DEFAULTS.fuelType) count++
    if (radius.value !== DEFAULTS.radius) count++
    if (sort.value !== DEFAULTS.sort) count++
    if (props.brandFilter) count++
    return count
})

function resetFilters() {
    fuelType.value = DEFAULTS.fuelType
    radius.value = DEFAULTS.radius
    sort.value = DEFAULTS.sort
    if (props.brandFilter) emit('update:brandFilter', '')
    open.value = false
}

function selectBrand(brand) {
    emit('update:brandFilter', brand)
    open.value = false
}

function emitSearch() {
    const hasPostcode = postcode.value.trim().length > 0
    const hasCoords = coords.value !== null
    if (!hasPostcode && !hasCoords) return

    emit('search', {
        postcode: hasPostcode ? postcode.value.trim() : null,
        lat: hasCoords ? coords.value.lat : null,
        lng: hasCoords ? coords.value.lng : null,
        fuelType: fuelType.value,
        radius: radius.value,
        sort: sort.value,
    })
}

function onDocumentPointerDown(event) {
    if (!open.value) return
    if (popoverRoot.value && !popoverRoot.value.contains(event.target)) {
        open.value = false
    }
}

function onDocumentKeydown(event) {
    if (event.key === 'Escape' && open.value) {
        open.value = false
    }
}

onMounted(() => {
    document.addEventListener('pointerdown', onDocumentPointerDown)
    document.addEventListener('keydown', onDocumentKeydown)
})

onBeforeUnmount(() => {
    document.removeEventListener('pointerdown', onDocumentPointerDown)
    document.removeEventListener('keydown', onDocumentKeydown)
})
</script>
