import SwiftUI
import MapKit

/// Non-interactive map showing a polyline for a GPS track. Optional photo
/// annotations can be tapped to fire a callback.
struct MiniRouteMap: View {
    let track: [GPSPoint]
    var lineWidth: CGFloat = 3
    var photoLocations: [PhotoLocation] = []
    var onPhotoTap: ((PhotoLocation) -> Void)? = nil

    var body: some View {
        Map(initialPosition: .region(region)) {
            MapPolyline(coordinates: coordinates)
                .stroke(Color.accentColor, style: StrokeStyle(lineWidth: lineWidth, lineJoin: .round))

            ForEach(photoLocations) { loc in
                Annotation("", coordinate: CLLocationCoordinate2D(latitude: loc.lat, longitude: loc.lon)) {
                    Button {
                        onPhotoTap?(loc)
                    } label: {
                        Image(systemName: "camera.circle.fill")
                            .font(.title2)
                            .foregroundStyle(.white, Color.accentColor)
                            .background(.white, in: Circle())
                            .shadow(radius: 2)
                    }
                    .buttonStyle(.plain)
                    .disabled(onPhotoTap == nil)
                }
            }
        }
        .mapStyle(.standard(elevation: .flat, pointsOfInterest: .excludingAll))
        .allowsHitTesting(onPhotoTap != nil)
    }

    private var coordinates: [CLLocationCoordinate2D] {
        track.map { CLLocationCoordinate2D(latitude: $0.lat, longitude: $0.lon) }
    }

    private var region: MKCoordinateRegion {
        let lats = track.map(\.lat)
        let lons = track.map(\.lon)
        let minLat = lats.min() ?? 0
        let maxLat = lats.max() ?? 0
        let minLon = lons.min() ?? 0
        let maxLon = lons.max() ?? 0
        let center = CLLocationCoordinate2D(
            latitude: (minLat + maxLat) / 2,
            longitude: (minLon + maxLon) / 2
        )
        let latDelta = max((maxLat - minLat) * 1.4, 0.002)
        let lonDelta = max((maxLon - minLon) * 1.4, 0.002)
        return MKCoordinateRegion(
            center: center,
            span: MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
        )
    }
}
