import SwiftUI

struct AirportSearchField: View {
    let label: String
    @Binding var searchText: String
    @Binding var selectedAirport: Airport?
    let suggestions: [Airport]
    let countrySuggestions: [Country]
    let regionResult: (regionName: String, airports: [MapAirport])?
    let isSearching: Bool
    let service: FlightService
    let database: AirportDatabase
    let onTextChanged: () -> Void
    let onSelect: (Airport) -> Void
    let onClear: () -> Void

    @State private var activeSheet: AirportSheet?

    private enum AirportSheet: Identifiable {
        case browser
        case country(Country)
        case region(name: String, airports: [MapAirport])

        var id: String {
            switch self {
            case .browser: return "browser"
            case .country(let c): return "country-\(c.id)"
            case .region(let name, _): return "region-\(name)"
            }
        }
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            // MARK: - Text Field Row
            HStack {
                TextField(label, text: $searchText)
                    .foregroundStyle(.primary)
                    .autocorrectionDisabled()
                    .textInputAutocapitalization(.characters)
                    .onChange(of: searchText) {
                        onTextChanged()
                    }

                if selectedAirport != nil {
                    Button {
                        onClear()
                    } label: {
                        Image(systemName: "xmark.circle.fill")
                            .foregroundStyle(.secondary)
                    }
                    .buttonStyle(.plain)
                } else if isSearching {
                    ProgressView()
                        .controlSize(.small)
                }

                Button {
                    activeSheet = .browser
                } label: {
                    Image(systemName: "globe")
                        .foregroundStyle(FlightTheme.accent)
                }
                .buttonStyle(.plain)
            }

            // MARK: - Suggestions
            let hasResults = !suggestions.isEmpty || !countrySuggestions.isEmpty || regionResult != nil
            if selectedAirport == nil && hasResults {
                Divider()
                    .padding(.vertical, 6)

                ForEach(suggestions) { airport in
                    Button {
                        onSelect(airport)
                    } label: {
                        HStack(spacing: 6) {
                            Image(systemName: "airplane")
                                .font(.caption)
                                .foregroundStyle(.secondary)
                            Text("\(airport.iata) - \(airport.name)")
                                .foregroundStyle(.primary)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .contentShape(Rectangle())
                    }
                    .buttonStyle(.plain)
                    .padding(.vertical, 8)

                    if airport.id != suggestions.last?.id {
                        Divider()
                    }
                }

                ForEach(countrySuggestions) { country in
                    if !suggestions.isEmpty || country.id != countrySuggestions.first?.id {
                        Divider()
                    }

                    Button {
                        activeSheet = .country(country)
                    } label: {
                        HStack(spacing: 6) {
                            Image(systemName: "flag")
                                .font(.caption)
                                .foregroundStyle(.orange)
                            Text(country.name)
                                .foregroundStyle(.primary)
                            Text("(\(country.id))")
                                .foregroundStyle(.secondary)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .contentShape(Rectangle())
                    }
                    .buttonStyle(.plain)
                    .padding(.vertical, 8)
                }

                if let region = regionResult {
                    if !suggestions.isEmpty || !countrySuggestions.isEmpty {
                        Divider()
                    }

                    Button {
                        activeSheet = .region(name: region.regionName, airports: region.airports)
                    } label: {
                        HStack(spacing: 6) {
                            Image(systemName: "map")
                                .font(.caption)
                                .foregroundStyle(FlightTheme.onTime)
                            Text(region.regionName)
                                .foregroundStyle(.primary)
                            Text("(\(region.airports.count) airports)")
                                .foregroundStyle(.secondary)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .contentShape(Rectangle())
                    }
                    .buttonStyle(.plain)
                    .padding(.vertical, 8)
                }
            }
        }
        .sheet(item: $activeSheet) { sheet in
            switch sheet {
            case .browser:
                AirportBrowserSheet(service: service, database: database) { airport in
                    onSelect(airport)
                    activeSheet = nil
                }
            case .country(let country):
                CountryAirportPickerSheet(
                    country: country,
                    service: service,
                    onSelect: { airport in
                        onSelect(airport)
                        activeSheet = nil
                    }
                )
            case .region(let name, let airports):
                RegionAirportPickerSheet(
                    regionName: name,
                    airports: airports,
                    service: service,
                    onSelect: { airport in
                        onSelect(airport)
                        activeSheet = nil
                    }
                )
            }
        }
    }
}

// MARK: - Country Airport Picker Sheet

/// Sheet that shows airports in a specific country for direct selection
private struct CountryAirportPickerSheet: View {
    let country: Country
    let service: FlightService
    let onSelect: (Airport) -> Void

    @Environment(\.dismiss) private var dismiss
    @State private var airports: [BrowseAirport] = []
    @State private var isLoading = true
    @State private var error: String?
    @State private var search = ""
    @State private var selectingIATA: String?

    var filteredAirports: [BrowseAirport] {
        guard !search.isEmpty else { return airports }
        return airports.filter {
            $0.city.localizedCaseInsensitiveContains(search) ||
            $0.iata.localizedCaseInsensitiveContains(search)
        }
    }

    var body: some View {
        NavigationStack {
            Group {
                if isLoading {
                    ProgressView("Loading airports...")
                } else if airports.isEmpty {
                    ContentUnavailableView(
                        "No Airports",
                        systemImage: "airplane.slash",
                        description: Text("No airports found in \(country.name).")
                    )
                } else {
                    List(filteredAirports) { airport in
                        Button {
                            selectAirport(airport)
                        } label: {
                            HStack {
                                VStack(alignment: .leading, spacing: 2) {
                                    Text(airport.city)
                                        .font(.headline)
                                        .foregroundStyle(.primary)
                                    Text(airport.iata)
                                        .font(.caption)
                                        .foregroundStyle(.secondary)
                                }
                                Spacer()
                                if selectingIATA == airport.iata {
                                    ProgressView()
                                        .controlSize(.small)
                                }
                            }
                        }
                        .disabled(selectingIATA != nil)
                    }
                    .searchable(text: $search, prompt: "Search airports")
                }
            }
            .navigationTitle("Airports in \(country.name)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
            }
            .task {
                do {
                    airports = try await service.fetchAirports(country: country)
                } catch {
                    self.error = error.localizedDescription
                }
                isLoading = false
            }
        }
    }

    private func selectAirport(_ browseAirport: BrowseAirport) {
        selectingIATA = browseAirport.iata
        Task {
            do {
                let results = try await service.searchAirports(term: browseAirport.iata)
                if let match = results.first(where: { $0.iata == browseAirport.iata }) {
                    onSelect(match)
                } else {
                    onSelect(Airport(id: "", iata: browseAirport.iata, name: browseAirport.city))
                }
            } catch {
                selectingIATA = nil
            }
        }
    }
}

// MARK: - Region Airport Picker Sheet

/// Sheet that shows airports in a region/state for direct selection
private struct RegionAirportPickerSheet: View {
    let regionName: String
    let airports: [MapAirport]
    let service: FlightService
    let onSelect: (Airport) -> Void

    @Environment(\.dismiss) private var dismiss
    @State private var search = ""
    @State private var selectingIATA: String?

    var filteredAirports: [MapAirport] {
        guard !search.isEmpty else { return airports }
        return airports.filter {
            $0.name.localizedCaseInsensitiveContains(search) ||
            $0.iata.localizedCaseInsensitiveContains(search)
        }
    }

    var body: some View {
        NavigationStack {
            List(filteredAirports) { airport in
                Button {
                    selectAirport(airport)
                } label: {
                    HStack {
                        VStack(alignment: .leading, spacing: 2) {
                            Text(airport.name)
                                .font(.headline)
                                .foregroundStyle(.primary)
                            Text(airport.iata)
                                .font(.caption)
                                .foregroundStyle(.secondary)
                        }
                        Spacer()
                        if selectingIATA == airport.iata {
                            ProgressView()
                                .controlSize(.small)
                        }
                    }
                }
                .disabled(selectingIATA != nil)
            }
            .searchable(text: $search, prompt: "Search airports")
            .navigationTitle("Airports in \(regionName)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
            }
        }
    }

    private func selectAirport(_ mapAirport: MapAirport) {
        selectingIATA = mapAirport.iata
        Task {
            do {
                let results = try await service.searchAirports(term: mapAirport.iata)
                if let match = results.first(where: { $0.iata == mapAirport.iata }) {
                    onSelect(match)
                } else {
                    // API doesn't know this airport — use bundled data
                    onSelect(Airport(id: "", iata: mapAirport.iata, name: mapAirport.name))
                }
            } catch {
                selectingIATA = nil
            }
        }
    }
}
