import SwiftUI
import MapKit
import UIKit

/// Renders a sharable card with map snapshot + stats for a route.
@MainActor
enum RouteShareImage {
    static func render(detail: RouteDetail, size: CGFloat = 1200) async -> UIImage? {
        let mapSize = CGSize(width: size, height: size * 0.75)
        guard let mapImage = await mapSnapshot(track: detail.gpsTrack, size: mapSize) else {
            return nil
        }

        let card = ShareCard(detail: detail, mapImage: mapImage, width: size)
        let renderer = ImageRenderer(content: card)
        renderer.scale = 2
        return renderer.uiImage
    }

    private static func mapSnapshot(track: [GPSPoint], size: CGSize) async -> UIImage? {
        guard track.count >= 2 else { return nil }
        let coords = track.map { CLLocationCoordinate2D(latitude: $0.lat, longitude: $0.lon) }

        let options = MKMapSnapshotter.Options()
        options.size = size
        options.pointOfInterestFilter = .excludingAll
        let lats = track.map(\.lat)
        let lons = track.map(\.lon)
        options.region = MKCoordinateRegion(
            center: CLLocationCoordinate2D(
                latitude: (lats.min()! + lats.max()!) / 2,
                longitude: (lons.min()! + lons.max()!) / 2
            ),
            span: MKCoordinateSpan(
                latitudeDelta: max((lats.max()! - lats.min()!) * 1.4, 0.002),
                longitudeDelta: max((lons.max()! - lons.min()!) * 1.4, 0.002)
            )
        )

        do {
            let snapshot = try await MKMapSnapshotter(options: options).start()
            let uiRenderer = UIGraphicsImageRenderer(size: size)
            return uiRenderer.image { ctx in
                snapshot.image.draw(in: CGRect(origin: .zero, size: size))
                ctx.cgContext.setLineWidth(6)
                ctx.cgContext.setStrokeColor(UIColor(red: 0xC4 / 255.0, green: 0x84 / 255.0, blue: 0x3A / 255.0, alpha: 1).cgColor)
                ctx.cgContext.setLineJoin(.round)
                ctx.cgContext.setLineCap(.round)
                var first = true
                for coord in coords {
                    let p = snapshot.point(for: coord)
                    if first { ctx.cgContext.move(to: p); first = false }
                    else { ctx.cgContext.addLine(to: p) }
                }
                ctx.cgContext.strokePath()
            }
        } catch {
            return nil
        }
    }
}

private struct ShareCard: View {
    let detail: RouteDetail
    let mapImage: UIImage
    let width: CGFloat

    var body: some View {
        VStack(spacing: 0) {
            Image(uiImage: mapImage)
                .resizable()
                .scaledToFit()

            VStack(alignment: .leading, spacing: 16) {
                Text(detail.name)
                    .font(.system(size: 36, weight: .bold))
                    .lineLimit(2)

                HStack(spacing: 28) {
                    stat(value: String(format: "%.2f km", detail.distanzKm ?? 0), label: "Distanz")
                    stat(value: durationLabel, label: "Dauer")
                    stat(value: "\(detail.gpsTrack.count)", label: "Punkte")
                }

                HStack {
                    Image(systemName: "pawprint.fill")
                        .foregroundStyle(Color(red: 0xC4 / 255.0, green: 0x84 / 255.0, blue: 0x3A / 255.0))
                    Text("Ban Yaro Go")
                        .font(.headline)
                    Spacer()
                }
            }
            .padding(28)
            .background(Color.white)
        }
        .frame(width: width)
        .background(Color.white)
    }

    private func stat(value: String, label: String) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(value).font(.system(size: 28, weight: .semibold))
            Text(label).font(.system(size: 16)).foregroundStyle(.secondary)
        }
    }

    private var durationLabel: String {
        let mins = detail.dauerMin ?? 0
        if mins >= 60 { return "\(mins / 60) h \(mins % 60) min" }
        return "\(mins) min"
    }
}
