<template>
    <div class="flex flex-wrap items-center gap-2 md:gap-2.5 py-3 border-b border-zinc-200">
        <!-- Refine group -->
        <span class="hidden md:inline text-xs font-mono uppercase tracking-widest text-zinc-400 mr-1">
            Refine
        </span>

        <label :class="{ 'is-active': fuelType !== DEFAULTS.fuelType }" class="pill group">
            <iconify-icon class="text-sm opacity-70" icon="lucide:fuel"></iconify-icon>
            <span class="text-sm font-medium">{{ fuelLabel }}</span>
            <iconify-icon class="text-sm opacity-50 group-hover:opacity-100" icon="lucide:chevron-down"></iconify-icon>
            <select
                v-model="fuelType"
                aria-label="Fuel type"
                class="absolute inset-0 opacity-0 cursor-pointer"
                name="fuelType"
            >
                <option v-for="fuel in FUEL_TYPES" :key="fuel.value" :value="fuel.value">{{ fuel.label }}</option>
            </select>
        </label>

        <label :class="{ 'is-active': radius !== DEFAULTS.radius }" class="pill group">
            <iconify-icon class="text-sm opacity-70" icon="lucide:circle-dot"></iconify-icon>
            <span class="text-sm font-medium">{{ radius }} miles</span>
            <iconify-icon class="text-sm opacity-50 group-hover:opacity-100" icon="lucide:chevron-down"></iconify-icon>
            <select
                v-model.number="radius"
                aria-label="Search radius"
                class="absolute inset-0 opacity-0 cursor-pointer"
                name="radius"
            >
                <option :value="5">5 miles</option>
                <option :value="10">10 miles</option>
                <option :value="20">20 miles</option>
            </select>
        </label>

        <button
            :aria-expanded="mapOpen"
            :class="{ 'is-active': mapOpen }"
            aria-controls="leaflet-map-panel"
            class="pill"
            type="button"
            @click="emit('toggle-map')"
        >
            <iconify-icon :icon="mapOpen ? 'lucide:map' : 'lucide:map-off'" class="text-sm opacity-70"></iconify-icon>
            <span class="text-sm font-medium">{{ mapOpen ? 'Hide map' : 'Show map' }}</span>
            <iconify-icon
                :class="mapOpen ? 'rotate-180' : ''"
                class="text-sm opacity-60 transition-transform duration-200"
                icon="lucide:chevron-down"
            ></iconify-icon>
        </button>

        <button
            v-if="hasActive"
            class="inline-flex items-center gap-1 h-10 px-3 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
        </button>

        <!-- Force Sort to a new line on mobile only -->
        <div aria-hidden="true" class="basis-full md:hidden"></div>

        <!-- Sort group -->
        <span class="hidden md:inline text-xs font-mono uppercase tracking-widest text-zinc-400 mx-1">
            Sort
        </span>

        <button
            v-for="option in sortOptions"
            :key="option.value"
            :class="{ 'is-active': sort === option.value }"
            class="pill"
            type="button"
            @click="sort = option.value"
        >
            <iconify-icon :icon="option.icon" class="text-sm opacity-70"></iconify-icon>
            <span class="text-sm font-medium">{{ option.label }}</span>
        </button>

        <label
            v-if="brands.length > 1"
            :class="{ 'is-active': brandFilter }"
            class="pill group"
        >
            <iconify-icon class="text-sm opacity-70" icon="lucide:tag"></iconify-icon>
            <span class="text-sm font-medium">{{ brandFilter || 'All brands' }}</span>
            <iconify-icon class="text-sm opacity-50 group-hover:opacity-100" icon="lucide:chevron-down"></iconify-icon>
            <select
                :value="brandFilter"
                aria-label="Filter by brand"
                class="absolute inset-0 opacity-0 cursor-pointer"
                @change="emit('update:brandFilter', $event.target.value)"
            >
                <option value="">All brands</option>
                <option v-for="brand in brands" :key="brand" :value="brand">{{ brand }}</option>
            </select>
        </label>

        <span class="ml-auto text-sm text-zinc-500 font-medium">
            {{ stationCount }} station{{ stationCount !== 1 ? 's' : '' }} found
        </span>
    </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } 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: '' },
    mapOpen: { type: Boolean, default: true },
    stationCount: { type: Number, default: 0 },
})

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

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

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
    if (postcode.value.trim() || coords.value) emitSearch()
})

const fuelLabel = computed(() => {
    return FUEL_TYPES.find(f => f.value === fuelType.value)?.label ?? 'Fuel'
})

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

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

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,
    })
}
</script>
