import SwiftUI
import MapKit

struct RouteMapView: View {
    let origin: Airport
    let routes: [Route]
    let date: Date
    let service: FlightService
    let database: AirportDatabase
    let loadService: AirlineLoadService
    let onSelectRoute: (Route) -> Void

    @State private var selectedRoute: Route?
    @State private var position: MapCameraPosition

    init(
        origin: Airport,
        routes: [Route],
        date: Date,
        service: FlightService,
        database: AirportDatabase,
        loadService: AirlineLoadService,
        onSelectRoute: @escaping (Route) -> Void
    ) {
        self.origin = origin
        self.routes = routes
        self.date = date
        self.service = service
        self.database = database
        self.loadService = loadService
        self.onSelectRoute = onSelectRoute

        let originCoord = database.airport(byIATA: origin.iata)?.coordinate
            ?? CLLocationCoordinate2D(latitude: 0, longitude: 0)

        // Determine a span that covers the farthest destination
        var maxDelta: Double = 20
        for route in routes {
            let latDelta = abs(route.latitude - originCoord.latitude)
            let lngDelta = abs(route.longitude - originCoord.longitude)
            maxDelta = max(maxDelta, max(latDelta, lngDelta) * 2.5)
        }
        maxDelta = min(maxDelta, 160)

        _position = State(initialValue: .region(MKCoordinateRegion(
            center: originCoord,
            span: MKCoordinateSpan(latitudeDelta: maxDelta, longitudeDelta: maxDelta)
        )))
    }

    private var originCoordinate: CLLocationCoordinate2D {
        database.airport(byIATA: origin.iata)?.coordinate
            ?? CLLocationCoordinate2D(latitude: 0, longitude: 0)
    }

    var body: some View {
        ZStack {
            Map(position: $position) {
                // Origin annotation
                Annotation(origin.iata, coordinate: originCoordinate) {
                    Image(systemName: "airplane.circle.fill")
                        .font(.system(size: 24))
                        .foregroundStyle(.blue)
                        .background(Circle().fill(.white).padding(2))
                }

                // Destination annotations
                ForEach(routes) { route in
                    let coord = CLLocationCoordinate2D(
                        latitude: route.latitude,
                        longitude: route.longitude
                    )

                    Annotation(route.destinationAirport.iata, coordinate: coord) {
                        Button {
                            withAnimation(.easeInOut(duration: 0.2)) {
                                selectedRoute = route
                            }
                        } label: {
                            Image(systemName: "airplane.circle.fill")
                                .font(.system(size: 16))
                                .foregroundStyle(
                                    selectedRoute?.id == route.id
                                        ? .blue
                                        : FlightTheme.onTime
                                )
                                .background(Circle().fill(.white).padding(1))
                        }
                    }

                    // Arc line from origin to destination
                    MapPolyline(coordinates: arcPoints(
                        from: originCoordinate,
                        to: coord
                    ))
                    .stroke(
                        selectedRoute?.id == route.id
                            ? Color.blue
                            : FlightTheme.onTime.opacity(0.5),
                        lineWidth: selectedRoute?.id == route.id ? 2.5 : 1.5
                    )
                }
            }

            // Bottom popup for selected route
            if let route = selectedRoute {
                VStack {
                    Spacer()
                    routePopup(route)
                        .padding()
                        .transition(.move(edge: .bottom).combined(with: .opacity))
                }
                .animation(.easeInOut(duration: 0.2), value: selectedRoute)
            }
        }
    }

    // MARK: - Route Popup

    private func routePopup(_ route: Route) -> some View {
        HStack(spacing: 16) {
            VStack(alignment: .leading, spacing: 4) {
                HStack(spacing: 8) {
                    Text(route.destinationAirport.iata)
                        .font(FlightTheme.airportCode(20))
                        .foregroundStyle(FlightTheme.accent)
                    Text(route.destinationAirport.name)
                        .font(.headline)
                        .lineLimit(1)
                }

                HStack(spacing: 12) {
                    Label(formatDuration(route.durationMinutes), systemImage: "clock")
                        .font(FlightTheme.label(13))
                        .foregroundStyle(.secondary)
                    Label(formatDistance(route.distanceMiles), systemImage: "arrow.left.and.right")
                        .font(FlightTheme.label(13))
                        .foregroundStyle(.secondary)
                }
            }

            Spacer()

            Button {
                onSelectRoute(route)
            } label: {
                Text("View Flights")
                    .fontWeight(.semibold)
                    .font(.subheadline)
                    .padding(.horizontal, 14)
                    .padding(.vertical, 8)
                    .background(FlightTheme.accent)
                    .foregroundStyle(.white)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }

            Button {
                withAnimation(.easeInOut(duration: 0.2)) {
                    selectedRoute = nil
                }
            } label: {
                Image(systemName: "xmark.circle.fill")
                    .font(.title3)
                    .foregroundStyle(.secondary)
            }
        }
        .padding()
        .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: FlightTheme.cardCornerRadius))
        .shadow(radius: 8)
    }

    // MARK: - Helpers

    private func arcPoints(
        from: CLLocationCoordinate2D,
        to: CLLocationCoordinate2D,
        segments: Int = 30
    ) -> [CLLocationCoordinate2D] {
        var points: [CLLocationCoordinate2D] = []
        for i in 0...segments {
            let f = Double(i) / Double(segments)
            let lat = from.latitude + (to.latitude - from.latitude) * f
            let lng = from.longitude + (to.longitude - from.longitude) * f
            points.append(CLLocationCoordinate2D(latitude: lat, longitude: lng))
        }
        return points
    }

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

    private func formatDistance(_ miles: Int) -> String {
        if miles >= 1000 {
            let k = Double(miles) / 1000.0
            return String(format: "%.1fk mi", k)
        }
        return "\(miles) mi"
    }
}
