import SwiftUI

/// Multi-select filter sheet. Each section is the universe of values
/// the user actually has in their log (years they've flown in,
/// airlines they've actually flown, etc.) so we never show options
/// that would match zero flights. Counts are next to each row.
struct HistoryFilterSheet: View {
    let allFlights: [LoggedFlight]
    @Binding var filters: HistoryFilters

    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            List {
                if !filters.isEmpty {
                    Section {
                        Button(role: .destructive) {
                            filters = HistoryFilters()
                        } label: {
                            Label("Clear all filters", systemImage: "xmark.circle")
                        }
                    }
                }

                Section("Year") {
                    ForEach(yearOptions, id: \.value) { o in
                        toggleRow(label: String(o.value), count: o.count,
                                  isOn: filters.years.contains(o.value)) { on in
                            toggle(&filters.years, o.value, on)
                            // Years are the user's primary "scope this
                            // whole screen" filter — picking one is a
                            // commitment, so close the sheet so the
                            // animation can play immediately.
                            if on { dismiss() }
                        }
                    }
                }
                Section("Airline") {
                    ForEach(airlineOptions, id: \.value) { o in
                        let entry = AircraftRegistry.shared.lookup(icao: o.value)
                        let name = entry?.name ?? o.value
                        toggleRow(label: name, count: o.count,
                                  isOn: filters.airlines.contains(o.value)) { on in
                            toggle(&filters.airlines, o.value, on)
                        }
                    }
                }
                Section("Airport") {
                    ForEach(airportOptions, id: \.value) { o in
                        toggleRow(label: o.value, count: o.count,
                                  isOn: filters.airports.contains(o.value)) { on in
                            toggle(&filters.airports, o.value, on)
                        }
                    }
                }
                Section("Aircraft type") {
                    ForEach(typeOptions, id: \.value) { o in
                        let friendly = AircraftDatabase.shared.displayName(forTypeCode: o.value)
                        let label = friendly == o.value ? o.value : "\(friendly) · \(o.value)"
                        toggleRow(label: label, count: o.count,
                                  isOn: filters.aircraftTypes.contains(o.value)) { on in
                            toggle(&filters.aircraftTypes, o.value, on)
                        }
                    }
                }
            }
            .navigationTitle("Filters")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {
                    Button("Done") { dismiss() }
                }
            }
        }
    }

    // MARK: - Option lists derived from log

    private struct Option {
        let value: String
        let count: Int
    }

    private var yearOptions: [Item<Int>] {
        let yrs = allFlights.map { Calendar.current.component(.year, from: $0.flightDate) }
        return Dictionary(grouping: yrs) { $0 }
            .map { Item(value: $0.key, count: $0.value.count) }
            .sorted { $0.value > $1.value }
    }
    private var airlineOptions: [Item<String>] {
        let codes = allFlights.compactMap { $0.carrierICAO ?? $0.carrierIATA }
        return Dictionary(grouping: codes) { $0 }
            .map { Item(value: $0.key, count: $0.value.count) }
            .sorted { $0.count > $1.count }
    }
    private var airportOptions: [Item<String>] {
        let codes = allFlights.flatMap { [$0.departureIATA, $0.arrivalIATA] }
            .filter { !$0.isEmpty }
        return Dictionary(grouping: codes) { $0 }
            .map { Item(value: $0.key, count: $0.value.count) }
            .sorted { $0.count > $1.count }
    }
    private var typeOptions: [Item<String>] {
        let codes = allFlights.compactMap { $0.aircraftType }
        return Dictionary(grouping: codes) { $0 }
            .map { Item(value: $0.key, count: $0.value.count) }
            .sorted { $0.count > $1.count }
    }

    private struct Item<T: Hashable> {
        let value: T
        let count: Int
    }

    private func toggleRow(label: String, count: Int, isOn: Bool, change: @escaping (Bool) -> Void) -> some View {
        HStack {
            Image(systemName: isOn ? "checkmark.circle.fill" : "circle")
                .foregroundStyle(isOn ? FlightTheme.accent : FlightTheme.textTertiary)
            Text(label)
            Spacer()
            Text("\(count)")
                .font(.caption.monospacedDigit())
                .foregroundStyle(FlightTheme.textTertiary)
        }
        .contentShape(Rectangle())
        .onTapGesture { change(!isOn) }
    }

    private func toggle<T: Hashable>(_ set: inout Set<T>, _ v: T, _ on: Bool) {
        if on { set.insert(v) } else { set.remove(v) }
    }
}
