import SwiftUI
import CoreLocation

struct LiveFlightDetailSheet: View {
    let aircraft: LiveAircraft
    let openSky: OpenSkyClient
    let database: AirportDatabase

    @State private var recentFlights: [OpenSkyFlight] = []
    @State private var isLoadingRoute = false

    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(alignment: .leading, spacing: 16) {
                    header

                    Divider()

                    // Live state grid
                    Text("LIVE STATE")
                        .font(FlightTheme.label())
                        .foregroundStyle(FlightTheme.textTertiary)
                        .tracking(1)

                    liveStateGrid

                    if let route = currentRoute {
                        Text("THIS FLIGHT")
                            .font(FlightTheme.label())
                            .foregroundStyle(FlightTheme.textTertiary)
                            .tracking(1)
                            .padding(.top, 4)

                        routeCard(route)
                    } else if isLoadingRoute {
                        HStack {
                            ProgressView()
                            Text("Looking up route…")
                                .font(.caption)
                                .foregroundStyle(FlightTheme.textSecondary)
                        }
                    }

                    if recentFlights.count > 1 {
                        Text("RECENT FLIGHTS")
                            .font(FlightTheme.label())
                            .foregroundStyle(FlightTheme.textTertiary)
                            .tracking(1)
                            .padding(.top, 4)

                        ForEach(recentFlights.prefix(8), id: \.self) { flight in
                            recentFlightRow(flight)
                        }
                    }

                    Text("AIRCRAFT")
                        .font(FlightTheme.label())
                        .foregroundStyle(FlightTheme.textTertiary)
                        .tracking(1)
                        .padding(.top, 4)

                    aircraftCard
                }
                .padding(16)
            }
            .background(FlightTheme.background.ignoresSafeArea())
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button { dismiss() } label: {
                        Image(systemName: "xmark")
                            .font(.subheadline.weight(.semibold))
                    }
                }
            }
            .task {
                await loadRoute()
            }
        }
    }

    // MARK: - Header

    private var header: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack(spacing: 10) {
                Text(aircraft.trimmedCallsign ?? aircraft.icao24)
                    .font(.title.weight(.bold).monospaced())
                    .foregroundStyle(FlightTheme.textPrimary)
                Spacer()
                statusBadge
            }
            Text(airlineDisplayName)
                .font(.subheadline)
                .foregroundStyle(FlightTheme.textSecondary)
        }
    }

    private var statusBadge: some View {
        let (text, color): (String, Color) = {
            if aircraft.onGround { return ("On ground", FlightTheme.textSecondary) }
            switch aircraft.verticalState {
            case .climbing:   return ("Climbing",   FlightTheme.onTime)
            case .descending: return ("Descending", FlightTheme.delayed)
            case .level:      return ("Cruising",   FlightTheme.accent)
            }
        }()
        return Text(text)
            .font(.caption.weight(.bold))
            .foregroundStyle(.white)
            .padding(.horizontal, 10)
            .padding(.vertical, 4)
            .background(color, in: Capsule())
    }

    // MARK: - Live state grid

    private var liveStateGrid: some View {
        VStack(spacing: 0) {
            HStack(spacing: 0) {
                statCell(label: "Altitude",
                         value: aircraft.altitudeFeet.map { "\(formatNumber($0)) ft" } ?? "—")
                statCell(label: "Speed",
                         value: aircraft.velocityKnots.map { "\($0) kt" } ?? "—")
            }
            Divider()
            HStack(spacing: 0) {
                statCell(label: "Heading",
                         value: aircraft.heading.map { "\($0)°" } ?? "—")
                statCell(label: "Vertical",
                         value: verticalDisplay)
            }
            Divider()
            HStack(spacing: 0) {
                statCell(label: "Squawk", value: aircraft.squawk ?? "—")
                statCell(label: "Updated", value: shortTime(aircraft.lastContact))
            }
        }
        .flightCard(padding: 0)
    }

    private var verticalDisplay: String {
        if aircraft.onGround { return "—" }
        switch aircraft.verticalState {
        case .climbing:   return "Climb"
        case .descending: return "Descend"
        case .level:      return "Level"
        }
    }

    private func statCell(label: String, value: String) -> some View {
        VStack(alignment: .leading, spacing: 2) {
            Text(label)
                .font(.caption2)
                .foregroundStyle(FlightTheme.textTertiary)
                .tracking(0.5)
            Text(value)
                .font(.subheadline.weight(.semibold).monospaced())
                .foregroundStyle(FlightTheme.textPrimary)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(16)
    }

    // MARK: - Route

    /// The most recent flight (could be in-progress or just-landed).
    private var currentRoute: OpenSkyFlight? {
        recentFlights.first { f in
            let now = Date().timeIntervalSince1970
            return Double(f.lastSeen) > now - 6 * 3600
        } ?? recentFlights.first
    }

    private func routeCard(_ f: OpenSkyFlight) -> some View {
        VStack(alignment: .leading, spacing: 12) {
            HStack(spacing: 16) {
                routeEndpoint(
                    code: f.estDepartureAirport,
                    label: "Departed",
                    time: f.departureDate
                )
                Image(systemName: "airplane")
                    .font(.title3)
                    .foregroundStyle(FlightTheme.accent)
                    .rotationEffect(.degrees(-45))
                routeEndpoint(
                    code: f.estArrivalAirport,
                    label: aircraft.onGround ? "Arrived" : "Heading to",
                    time: f.arrivalDate
                )
            }
        }
        .flightCard()
    }

    private func routeEndpoint(code: String?, label: String, time: Date) -> some View {
        let iata = code.flatMap(icaoToIATA(_:)) ?? code ?? "—"
        let cityName: String = {
            guard let code, let m = database.airport(byIATA: icaoToIATA(code) ?? code) else { return "" }
            return m.name
        }()

        return VStack(alignment: .leading, spacing: 2) {
            Text(label)
                .font(.caption2)
                .foregroundStyle(FlightTheme.textTertiary)
                .tracking(0.5)
            Text(iata)
                .font(FlightTheme.airportCode(28))
                .foregroundStyle(FlightTheme.textPrimary)
            if !cityName.isEmpty {
                Text(cityName)
                    .font(.caption2)
                    .foregroundStyle(FlightTheme.textSecondary)
                    .lineLimit(1)
            }
            Text(shortDateTime(time))
                .font(.caption2.monospaced())
                .foregroundStyle(FlightTheme.textTertiary)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
    }

    private func recentFlightRow(_ f: OpenSkyFlight) -> some View {
        let dep = f.estDepartureAirport.flatMap(icaoToIATA(_:)) ?? f.estDepartureAirport ?? "—"
        let arr = f.estArrivalAirport.flatMap(icaoToIATA(_:)) ?? f.estArrivalAirport ?? "—"
        return HStack(spacing: 12) {
            Text(dep)
                .font(.subheadline.weight(.semibold).monospaced())
                .foregroundStyle(FlightTheme.textPrimary)
                .frame(width: 56, alignment: .leading)
            Image(systemName: "arrow.right")
                .font(.caption)
                .foregroundStyle(FlightTheme.textTertiary)
            Text(arr)
                .font(.subheadline.weight(.semibold).monospaced())
                .foregroundStyle(FlightTheme.textPrimary)
                .frame(width: 56, alignment: .leading)
            Spacer()
            Text(shortDate(f.departureDate))
                .font(.caption.monospaced())
                .foregroundStyle(FlightTheme.textSecondary)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 10)
        .background(FlightTheme.cardBackground, in: RoundedRectangle(cornerRadius: 10))
    }

    // MARK: - Aircraft card

    private var aircraftCard: some View {
        VStack(spacing: 0) {
            HStack(spacing: 0) {
                statCell(label: "ICAO24", value: aircraft.icao24.uppercased())
                statCell(label: "Country", value: aircraft.originCountry.isEmpty ? "—" : aircraft.originCountry)
            }
            if let cat = aircraft.category, let name = aircraftCategoryName(cat) {
                Divider()
                HStack(spacing: 0) {
                    statCell(label: "Category", value: name)
                    statCell(label: "Position", value: shortCoord(aircraft.coordinate))
                }
            } else {
                Divider()
                HStack(spacing: 0) {
                    statCell(label: "Position", value: shortCoord(aircraft.coordinate))
                    statCell(label: "", value: "")
                }
            }
        }
        .flightCard(padding: 0)
    }

    // MARK: - Helpers

    private var airlineDisplayName: String {
        AircraftRegistry.airline(forICAO: aircraft.airlineICAO).name
    }

    private func loadRoute() async {
        guard !isLoadingRoute else { return }
        isLoadingRoute = true
        defer { isLoadingRoute = false }
        recentFlights = await openSky.recentFlights(icao24: aircraft.icao24)
    }

    private func formatNumber(_ n: Int) -> String {
        let f = NumberFormatter()
        f.numberStyle = .decimal
        return f.string(from: NSNumber(value: n)) ?? "\(n)"
    }

    private func shortCoord(_ c: CLLocationCoordinate2D) -> String {
        String(format: "%.2f, %.2f", c.latitude, c.longitude)
    }

    private func shortTime(_ d: Date) -> String {
        let f = DateFormatter()
        f.timeStyle = .short
        return f.string(from: d)
    }

    private func shortDate(_ d: Date) -> String {
        let f = DateFormatter()
        f.dateFormat = "MMM d"
        return f.string(from: d)
    }

    private func shortDateTime(_ d: Date) -> String {
        let f = DateFormatter()
        f.dateFormat = "MMM d, HH:mm"
        return f.string(from: d)
    }

    /// OpenSky returns 4-letter ICAO airport codes (e.g. "KDFW"). Strip the
    /// leading region letter for common 3-letter IATA codes in the US/
    /// Canada/etc. Best-effort — falls back to the raw value.
    private func icaoToIATA(_ icao: String?) -> String? {
        guard let icao else { return nil }
        let s = icao.uppercased()
        guard s.count == 4 else { return s }
        // US: KXXX, Canada: CYxx (3 chars after C), Mexico: MMxx (3 chars after M).
        if s.hasPrefix("K") { return String(s.dropFirst()) }
        if s.hasPrefix("CY") { return String(s.dropFirst()) }   // YYZ stays YYZ
        if s.hasPrefix("MM") { return String(s.dropFirst()) }
        return s
    }
}
