<script setup lang="ts">
import type { Airline, Alliance, Flight, RegionRange, FlightRange, FlightScope } from '@/Types/types'
import { ref, watch } from 'vue'
import AllianceLogo from "@/Components/FlightsGoneBy/AllianceLogo.vue"

const props = defineProps<{
    flights: Flight[]
}>()

const emit = defineEmits<{
    change: [filters: {
        years: number[]
        airlines: number[]
        alliances: number[]
        countries: string[]
        continents: string[]
        flightClasses: number[]
        crewTypes: number[]
        flightScopes: FlightScope[]
        flightRanges: FlightRange[]
        regionRanges: RegionRange[]
        flightReasons: number[]
        seatTypes: number[]
        manufacturers: string[]
        aircraftModels: number[]
        airportRegions: number[]
        otherUsers: string[]
    }]
}>()

// ── Available options ─────────────────────────────────────────────────────────

type AirlineData = { id: number; name: string; airline: Airline }

const FLIGHT_SCOPE_LABELS: Record<FlightScope, string> = {
    domestic:      'Domestic',
    international: 'International',
}

const FLIGHT_RANGE_LABELS: Record<FlightRange, string> = {
    intracontinental: 'Intracontinental',
    intercontinental: 'Intercontinental',
}

const REGION_RANGE_LABELS: Record<RegionRange, string> = {
    intraregional: 'Intraregional',
    interregional: 'Interregional',
}

function buildOptions(flights: Flight[]) {
    const years          = new Set<number>()
    const airlines       = new Map<number, AirlineData>()
    const alliances      = new Map<number, { id: number; name: string; alliance: Alliance }>()
    const countries      = new Map<string, { code: string; name: string }>()
    const continents     = new Map<string, { code: string; name: string }>()
    const classes        = new Map<number, { id: number; name: string }>()
    const crewTypes      = new Map<number, { id: number; name: string }>()
    const flightReasons  = new Map<number, { id: number; name: string }>()
    const seatTypes      = new Map<number, { id: number; name: string }>()
    const flightScopes   = new Set<FlightScope>()
    const flightRanges   = new Set<FlightRange>()
    const regionRanges   = new Set<RegionRange>()
    const manufacturers  = new Map<string, { name: string }>()
    const aircraftModels = new Map<number, { id: number; name: string }>()
    const airportRegions = new Map<number, { id: number; name: string; countryCodes: Set<string> }>()
    const otherUsers = new Set<string>()

    flights.forEach(f => {
        years.add(new Date(f.departure_date).getFullYear())
        f.other_users_on_flight?.forEach(name => otherUsers.add(name))
        if (f.airline) {
            airlines.set(f.airline.id, { id: f.airline.id, name: f.airline.name, airline: f.airline })

            if (f.airline.alliance?.id != null && f.airline.alliance?.name)
                alliances.set(f.airline.alliance.id, {
                    id: f.airline.alliance.id,
                    name: f.airline.alliance.name,
                    alliance: f.airline.alliance,
                })
        }

        const dep = f.departure_airport.region
        const arr = f.arrival_airport.region

        if (dep?.country) countries.set(dep.country.code, { code: dep.country.code, name: dep.country.name })
        if (arr?.country) countries.set(arr.country.code, { code: arr.country.code, name: arr.country.name })
        if (dep?.continent) continents.set(dep.continent.code, { code: dep.continent.code, name: dep.continent.name })
        if (arr?.continent) continents.set(arr.continent.code, { code: arr.continent.code, name: arr.continent.name })

        for (const airport of [f.departure_airport, f.arrival_airport]) {
            const region = airport.region
            if (region?.id != null && region?.name) {
                if (!airportRegions.has(region.id)) {
                    airportRegions.set(region.id, {
                        id: region.id,
                        name: region.country?.code ? `${region.country.code} - ${region.name}` : region.name,
                        countryCodes: new Set(),
                    })
                }
                if (region.country?.code)
                    airportRegions.get(region.id)!.countryCodes.add(region.country.code)
            }
        }

        if (f.flight_class?.id != null && f.flight_class?.name)
            classes.set(f.flight_class.id, { id: f.flight_class.id, name: f.flight_class.name })

        if (f.crew_type?.id != null && f.crew_type?.name)
            crewTypes.set(f.crew_type.id, { id: f.crew_type.id, name: f.crew_type.name })

        if (f.flight_reason?.id != null && f.flight_reason?.name)
            flightReasons.set(f.flight_reason.id, { id: f.flight_reason.id, name: f.flight_reason.name })

        if (f.seat_type?.id != null && f.seat_type?.name)
            seatTypes.set(f.seat_type.id, { id: f.seat_type.id, name: f.seat_type.name })

        if (f.aircraft?.manufacturer_code)
            manufacturers.set(f.aircraft.manufacturer_code, { name: f.aircraft.manufacturer_code })

        if (f.aircraft?.id != null && f.aircraft?.display_name_short)
            aircraftModels.set(f.aircraft.id, { id: f.aircraft.id, name: f.aircraft.display_name_short })

        flightScopes.add(f.scope)
        flightRanges.add(f.range)
        regionRanges.add(f.region_range)
    })

    const scopeOrder: FlightScope[]   = ['domestic', 'international']
    const rangeOrder: FlightRange[]   = ['intracontinental', 'intercontinental']
    const regionRangeOrder: RegionRange[] = ['intraregional', 'interregional']

    return {
        years:          [...years].sort((a, b) => b - a),
        airlines:       [...airlines.values()].sort((a, b) => a.name.localeCompare(b.name)),
        alliances:      [...alliances.values()].sort((a, b) => a.name.localeCompare(b.name)),
        countries:      [...countries.values()].sort((a, b) => a.name.localeCompare(b.name)),
        continents:     [...continents.values()].sort((a, b) => a.name.localeCompare(b.name)),
        classes:        [...classes.values()].sort((a, b) => a.name.localeCompare(b.name)),
        crewTypes:      [...crewTypes.values()].sort((a, b) => a.name.localeCompare(b.name)),
        flightReasons:  [...flightReasons.values()].sort((a, b) => a.name.localeCompare(b.name)),
        seatTypes:      [...seatTypes.values()].sort((a, b) => a.id - b.id),
        flightScopes:   scopeOrder.filter(s => flightScopes.has(s)).map(s => ({ value: s, label: FLIGHT_SCOPE_LABELS[s] })),
        flightRanges:   rangeOrder.filter(r => flightRanges.has(r)).map(r => ({ value: r, label: FLIGHT_RANGE_LABELS[r] })),
        regionRanges:   regionRangeOrder.filter(r => regionRanges.has(r)).map(r => ({ value: r, label: REGION_RANGE_LABELS[r] })),
        manufacturers:  [...manufacturers.values()].sort((a, b) => a.name.localeCompare(b.name)),
        aircraftModels: [...aircraftModels.values()].sort((a, b) => a.name.localeCompare(b.name)),
        airportRegions: [...airportRegions.values()].sort((a, b) => a.name.localeCompare(b.name)),
        otherUsers: [...otherUsers].sort((a, b) => a.localeCompare(b)),
    }
}

const availableOptions = buildOptions(props.flights)

// ── Filter state ──────────────────────────────────────────────────────────────

const selectedYears          = ref<number[]>([])
const selectedAirlines       = ref<number[]>([])
const selectedAlliances      = ref<number[]>([])
const selectedCountries      = ref<string[]>([])
const selectedContinents     = ref<string[]>([])
const selectedFlightClasses  = ref<number[]>([])
const selectedCrewTypes      = ref<number[]>([])
const selectedFlightScopes   = ref<FlightScope[]>([])
const selectedFlightRanges   = ref<FlightRange[]>([])
const selectedRegionRanges   = ref<RegionRange[]>([])
const selectedFlightReasons  = ref<number[]>([])
const selectedSeatTypes      = ref<number[]>([])
const selectedManufacturers  = ref<string[]>([])
const selectedAircraftModels = ref<number[]>([])
const selectedAirportRegions = ref<number[]>([])
const selectedOtherUsers = ref<string[]>([])

// When selected countries change, drop any selected regions that no longer
// belong to any of the selected countries.
watch(selectedCountries, (countries) => {
    if (countries.length === 0) return
    selectedAirportRegions.value = selectedAirportRegions.value.filter(regionId => {
        const region = availableOptions.airportRegions.find(r => r.id === regionId)
        if (!region) return false
        return [...(region as any).countryCodes].some((code: string) => countries.includes(code))
    })
})

function emitFilters() {
    emit('change', {
        years:          selectedYears.value,
        airlines:       selectedAirlines.value,
        alliances:      selectedAlliances.value,
        countries:      selectedCountries.value,
        continents:     selectedContinents.value,
        flightClasses:  selectedFlightClasses.value,
        crewTypes:      selectedCrewTypes.value,
        flightScopes:   selectedFlightScopes.value,
        flightRanges:   selectedFlightRanges.value,
        regionRanges:   selectedRegionRanges.value,
        flightReasons:  selectedFlightReasons.value,
        seatTypes:      selectedSeatTypes.value,
        manufacturers:  selectedManufacturers.value,
        aircraftModels: selectedAircraftModels.value,
        airportRegions: selectedAirportRegions.value,
        otherUsers: selectedOtherUsers.value,
    })
}

// ── Helpers ───────────────────────────────────────────────────────────────────

const countryFlagClass = (code: string) =>
    `fi fi-${code.toLowerCase()}`
</script>

<template>
    <div class="flight-filters">

        <v-select
            v-model="selectedYears"
            :items="availableOptions.years"
            label="Year"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ item }}<span v-if="index < Math.min(selectedYears.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedYears.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-model="selectedAirlines"
            :items="availableOptions.airlines"
            item-title="name" item-value="id"
            label="Airline"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #item="{ item, props: itemProps }">
                <v-list-item v-bind="itemProps">
                    <template #prepend="{ isSelected }">
                        <v-checkbox-btn :model-value="isSelected" tabindex="-1" />
                    </template>
                    <template #title>
                        <img
                            :src="(item as AirlineData).airline.logo_url"
                            width="32" height="32"
                            style="object-fit: contain; margin-right: 8px; vertical-align: middle;"
                            alt=""
                        />
                        {{ (item as any).name }}
                    </template>
                </v-list-item>
            </template>
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedAirlines.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedAirlines.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.alliances.length > 0"
            v-model="selectedAlliances"
            :items="availableOptions.alliances"
            item-title="name" item-value="id"
            label="Alliance"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #item="{ item, props: itemProps }">
                <v-list-item v-bind="itemProps">
                    <template #prepend="{ isSelected }">
                        <v-checkbox-btn :model-value="isSelected" tabindex="-1" />
                    </template>
                    <template #title>
                        <AllianceLogo :size="22" :alliance="(item as any).alliance" style="margin-right: 8px;" />
                        {{ (item as any).name }}
                    </template>
                </v-list-item>
            </template>
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedAlliances.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedAlliances.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-model="selectedCountries"
            :items="availableOptions.countries"
            item-title="name" item-value="code"
            label="Country"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #item="{ item, props: itemProps }">
                <v-list-item v-bind="itemProps">
                    <template #prepend="{ isSelected }">
                        <v-checkbox-btn :model-value="isSelected" tabindex="-1" />
                    </template>
                    <template #title>
                        <span :class="countryFlagClass((item as any).code)" style="margin-right: 8px; font-size: 1.1em;" />
                        {{ (item as any).name }}
                    </template>
                </v-list-item>
            </template>
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    <span :class="countryFlagClass((item as any).code)" style="margin-right: 4px;" />
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedCountries.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedCountries.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.flightScopes.length > 1"
            v-model="selectedFlightScopes"
            :items="availableOptions.flightScopes"
            item-title="label" item-value="value"
            label="Flight Scope"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).label }}<span v-if="index < Math.min(selectedFlightScopes.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedFlightScopes.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.airportRegions.length > 0"
            v-model="selectedAirportRegions"
            :items="availableOptions.airportRegions"
            item-title="name" item-value="id"
            label="Region"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedAirportRegions.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedAirportRegions.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.regionRanges.length > 1"
            v-model="selectedRegionRanges"
            :items="availableOptions.regionRanges"
            item-title="label" item-value="value"
            label="Region Range"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).label }}<span v-if="index < Math.min(selectedRegionRanges.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedRegionRanges.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-model="selectedContinents"
            :items="availableOptions.continents"
            item-title="name" item-value="code"
            label="Continent"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedContinents.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedContinents.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.flightRanges.length > 1"
            v-model="selectedFlightRanges"
            :items="availableOptions.flightRanges"
            item-title="label" item-value="value"
            label="Flight Range"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).label }}<span v-if="index < Math.min(selectedFlightRanges.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedFlightRanges.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-model="selectedFlightClasses"
            :items="availableOptions.classes"
            item-title="name" item-value="id"
            label="Flight Class"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedFlightClasses.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedFlightClasses.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.flightReasons.length > 0"
            v-model="selectedFlightReasons"
            :items="availableOptions.flightReasons"
            item-title="name" item-value="id"
            label="Flight Reason"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedFlightReasons.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedFlightReasons.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.seatTypes.length > 0"
            v-model="selectedSeatTypes"
            :items="availableOptions.seatTypes"
            item-title="name" item-value="id"
            label="Seat Type"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedSeatTypes.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedSeatTypes.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.manufacturers.length > 0"
            v-model="selectedManufacturers"
            :items="availableOptions.manufacturers"
            item-title="name" item-value="name"
            label="Aircraft Manufacturer"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedManufacturers.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedManufacturers.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.aircraftModels.length > 0"
            v-model="selectedAircraftModels"
            :items="availableOptions.aircraftModels"
            item-title="name" item-value="id"
            label="Aircraft Model"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedAircraftModels.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedAircraftModels.length - 2 }}</span>
            </template>
        </v-select>

        <v-select
            v-if="availableOptions.crewTypes.length > 0"
            v-model="selectedCrewTypes"
            :items="availableOptions.crewTypes"
            item-title="name" item-value="id"
            label="Crew Type"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
                <span v-if="index < 2" class="v-select__selection-text">
                    {{ (item as any).name }}<span v-if="index < Math.min(selectedCrewTypes.length, 2) - 1">,&nbsp;</span>
                </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedCrewTypes.length - 2 }}</span>
            </template>
        </v-select>
        <v-select
            v-if="availableOptions.otherUsers.length > 0"
            v-model="selectedOtherUsers"
            :items="availableOptions.otherUsers"
            label="Flew With"
            multiple clearable hide-details
            density="compact" variant="outlined"
            @update:model-value="emitFilters"
        >
            <template #selection="{ item, index }">
        <span v-if="index < 2" class="v-select__selection-text">
            {{ item }}<span v-if="index < Math.min(selectedOtherUsers.length, 2) - 1">,&nbsp;</span>
        </span>
                <span v-if="index === 2" class="text-caption text-medium-emphasis">+{{ selectedOtherUsers.length - 2 }}</span>
            </template>
        </v-select>
    </div>
</template>

<style scoped>
.flight-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 12px;
}

.flight-filters .v-select {
    flex: 1 1 160px;
}
</style>
