import SwiftUI

/// Renders one `RouteConnection` (1+ chained legs) as a single tappable card.
/// Each leg is independently tappable via the inner buttons — tapping the
/// outer card just expands/collapses the leg detail by default; we wire
/// per-leg taps via the `onLegTap` callback.
struct ConnectionRow: View {
    let connection: RouteConnection
    let appendix: RouteAppendix?
    let database: AirportDatabase
    let onLegTap: (RouteFlight) -> Void

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            // MARK: - Summary header
            summaryHeader

            Divider()

            // MARK: - Legs
            VStack(spacing: 10) {
                ForEach(Array(connection.flights.enumerated()), id: \.element.id) { index, leg in
                    if index > 0, let layover = layoverMinutes(at: index) {
                        layoverRow(minutes: layover, at: leg.departure.airportIata)
                    }
                    Button {
                        onLegTap(leg)
                    } label: {
                        LegSummary(leg: leg, appendix: appendix, database: database)
                    }
                    .buttonStyle(.plain)
                }
            }
        }
        .flightCard()
    }

    // MARK: - Summary header

    private var summaryHeader: some View {
        HStack(alignment: .center) {
            VStack(alignment: .leading, spacing: 2) {
                Text(stopsLabel)
                    .font(.caption.weight(.semibold))
                    .foregroundStyle(FlightTheme.accent)
                    .padding(.horizontal, 8)
                    .padding(.vertical, 3)
                    .background(FlightTheme.accent.opacity(0.12), in: Capsule())

                Text(carriersLabel)
                    .font(.caption)
                    .foregroundStyle(FlightTheme.textSecondary)
                    .lineLimit(1)
            }

            Spacer()

            VStack(alignment: .trailing, spacing: 2) {
                Text(formatDuration(connection.durationMinutes))
                    .font(.subheadline.weight(.bold))
                    .foregroundStyle(FlightTheme.textPrimary)
                Text("total")
                    .font(.caption2)
                    .foregroundStyle(FlightTheme.textTertiary)
            }
        }
    }

    private var stopsLabel: String {
        switch connection.stopCount {
        case 0:  return "Direct"
        case 1:  return "1 stop"
        default: return "\(connection.stopCount) stops"
        }
    }

    private var carriersLabel: String {
        let codes = connection.carrierIatas
        if codes.count == 1, let app = appendix?.airline(iata: codes[0])?.name {
            return app
        }
        return codes.joined(separator: " · ")
    }

    // MARK: - Layover

    private func layoverMinutes(at index: Int) -> Int? {
        guard index >= 1, index < connection.flights.count else { return nil }
        let arr = connection.flights[index - 1].arrival.dateTime
        let dep = connection.flights[index].departure.dateTime
        let mins = Int(dep.timeIntervalSince(arr) / 60)
        return mins > 0 ? mins : nil
    }

    private func layoverRow(minutes: Int, at iata: String) -> some View {
        HStack(spacing: 8) {
            Image(systemName: "arrow.down")
                .font(.caption2)
                .foregroundStyle(FlightTheme.textTertiary)
            Text("Layover at \(iata) · \(formatDuration(minutes))")
                .font(.caption)
                .foregroundStyle(FlightTheme.textSecondary)
            Spacer()
        }
        .padding(.leading, 8)
    }

    private func formatDuration(_ minutes: Int) -> String {
        let h = minutes / 60
        let m = minutes % 60
        if h > 0, m > 0 { return "\(h)h \(m)m" }
        if h > 0        { return "\(h)h" }
        return "\(m)m"
    }
}

// MARK: - Single leg summary

private struct LegSummary: View {
    let leg: RouteFlight
    let appendix: RouteAppendix?
    let database: AirportDatabase

    private static let timeFormatter: DateFormatter = {
        let f = DateFormatter()
        f.dateFormat = "HH:mm"
        return f
    }()

    var body: some View {
        HStack(alignment: .top, spacing: 10) {
            // Airline + flight number (fixed-width left column)
            VStack(alignment: .leading, spacing: 2) {
                Text(leg.carrierIata)
                    .font(.caption.weight(.bold))
                    .foregroundStyle(FlightTheme.textPrimary)
                // verbatim: prevents SwiftUI from rendering Int as "3,189".
                Text(verbatim: "\(leg.flightNumber)")
                    .font(FlightTheme.flightNumber(11))
                    .foregroundStyle(FlightTheme.textSecondary)
            }
            .frame(width: 44, alignment: .leading)

            // Times + airports + names + aircraft
            VStack(alignment: .leading, spacing: 4) {
                // Row A — times and IATAs (compact)
                HStack(spacing: 8) {
                    timeAirport(leg.departure)
                    Image(systemName: "arrow.right")
                        .font(.caption2)
                        .foregroundStyle(FlightTheme.textTertiary)
                    timeAirport(leg.arrival)
                    Spacer(minLength: 0)
                }

                // Row B — full airport names, single line, middle-truncated
                Text("\(airportName(for: leg.departure.airportIata)) → \(airportName(for: leg.arrival.airportIata))")
                    .font(.caption2)
                    .foregroundStyle(FlightTheme.textSecondary)
                    .lineLimit(1)
                    .truncationMode(.middle)

                // Row C — aircraft (if known), single line, tail-truncated
                if let aircraft = aircraftLabel {
                    Text(aircraft)
                        .font(.caption2)
                        .foregroundStyle(FlightTheme.textTertiary)
                        .lineLimit(1)
                        .truncationMode(.tail)
                }
            }

            Spacer(minLength: 4)

            Image(systemName: "chevron.right")
                .font(.caption2)
                .foregroundStyle(FlightTheme.textTertiary)
                .padding(.top, 4)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 10)
        .background(FlightTheme.elevatedBackground)
        .clipShape(RoundedRectangle(cornerRadius: 10))
        .contentShape(Rectangle())
    }

    private func timeAirport(_ endpoint: RouteEndpoint) -> some View {
        VStack(alignment: .leading, spacing: 1) {
            Text(Self.timeFormatter.string(from: endpoint.dateTime))
                .font(.subheadline.weight(.semibold).monospaced())
                .foregroundStyle(FlightTheme.textPrimary)
            Text(endpoint.airportIata)
                .font(.caption2.weight(.semibold))
                .foregroundStyle(FlightTheme.textSecondary)
        }
    }

    private var aircraftLabel: String? {
        guard let iata = leg.equipmentIata else { return nil }
        return appendix?.equipment(iata: iata)?.name ?? iata
    }

    /// Bundled DB first (clean city names), then route-explorer appendix.
    private func airportName(for iata: String) -> String {
        if let m = database.airport(byIATA: iata) { return m.name }
        if let n = appendix?.airport(iata: iata)?.cityName, !n.isEmpty { return n }
        if let n = appendix?.airport(iata: iata)?.name, !n.isEmpty { return n }
        return iata
    }
}
