import { computed, type ComputedRef, type Ref } from 'vue'
import type { Flight } from '@/Types/types'

export type CodeType = 'iata' | 'icao'

export interface AlphabetFlightData {
    /** All 26 uppercase letters A–Z */
    allLetters: string[]
    /** Letters the user has visited (has at least one qualifying airport) */
    visitedLetters: ComputedRef<Set<string>>
    /** Map of letter → flights that touch an airport starting with that letter */
    flightsByLetter: ComputedRef<Record<string, Flight[]>>
    /** The code type being used */
    codeType: CodeType
}

/**
 * Returns which letters of the alphabet have been "visited" based on
 * the IATA or ICAO code of the departure or arrival airport on each flight.
 *
 * A letter is considered visited when at least one flight departs from or
 * arrives at an airport whose chosen code starts with that letter.
 *
 * Airports without a code of the chosen type are ignored.
 */
export function useAlphabetFlights(
    flights: Ref<Flight[]> | ComputedRef<Flight[]>,
    codeType: CodeType = 'iata',
): AlphabetFlightData {
    const allLetters = Array.from({ length: 26 }, (_, i) =>
        String.fromCharCode(65 + i), // 'A' … 'Z'
    )

    /** Pick the right code from an airport, uppercased first character or null */
    function getCode(airport: Flight['departure_airport'] | Flight['arrival_airport']): string | null {
        const raw = codeType === 'iata' ? airport.iata_code : airport.icao_code
        return raw ? raw.trim().toUpperCase() : null
    }

    const flightsByLetter = computed<Record<string, Flight[]>>(() => {
        const map: Record<string, Flight[]> = {}
        for (const letter of allLetters) {
            map[letter] = []
        }

        for (const flight of flights.value) {
            const codes = new Set<string>()

            const depCode = getCode(flight.departure_airport)
            if (depCode) codes.add(depCode[0])

            const arrCode = getCode(flight.arrival_airport)
            if (arrCode) codes.add(arrCode[0])

            for (const letter of codes) {
                if (letter >= 'A' && letter <= 'Z') {
                    map[letter]?.push(flight)
                }
            }
        }

        return map
    })

    const visitedLetters = computed<Set<string>>(() => {
        const visited = new Set<string>()
        for (const [letter, letterFlights] of Object.entries(flightsByLetter.value)) {
            if (letterFlights.length > 0) {
                visited.add(letter)
            }
        }
        return visited
    })

    return {
        allLetters,
        visitedLetters,
        flightsByLetter,
        codeType,
    }
}
