//
//  ShareCardComponents.swift
//  SportsTime
//
//  Reusable components for share cards: header, footer, stats row, map snapshot.
//

import SwiftUI
import MapKit
import UIKit

// MARK: - Card Background

struct ShareCardBackground: View {
    let theme: ShareTheme
    var sports: Set<Sport>? = nil

    var body: some View {
        if let sports = sports, !sports.isEmpty {
            ShareCardSportBackground(sports: sports, theme: theme)
        } else {
            LinearGradient(
                colors: theme.gradientColors,
                startPoint: .top,
                endPoint: .bottom
            )
        }
    }
}

// MARK: - Card Header

struct ShareCardHeader: View {
    let title: String
    let sport: Sport?
    let theme: ShareTheme

    var body: some View {
        VStack(spacing: 16) {
            if let sport = sport {
                ZStack {
                    Circle()
                        .fill(theme.accentColor.opacity(0.2))
                        .frame(width: 80, height: 80)

                    Image(systemName: sport.iconName)
                        .font(.system(size: 40))
                        .foregroundStyle(theme.accentColor)
                }
            }

            Text(title)
                .font(.system(size: 48, weight: .bold, design: .rounded))
                .foregroundStyle(theme.textColor)
                .multilineTextAlignment(.center)
        }
    }
}

// MARK: - Card Footer

struct ShareCardFooter: View {
    let theme: ShareTheme

    var body: some View {
        VStack(spacing: 12) {
            HStack(spacing: 8) {
                Image(systemName: "sportscourt.fill")
                    .font(.system(size: 20))
                Text("SportsTime")
                    .font(.system(size: 24, weight: .semibold))
            }
            .foregroundStyle(theme.accentColor)

            Text("Plan your stadium adventure")
                .font(.system(size: 18))
                .foregroundStyle(theme.secondaryTextColor)
        }
    }
}

// MARK: - Stats Row

struct ShareStatsRow: View {
    let stats: [(value: String, label: String)]
    let theme: ShareTheme

    var body: some View {
        HStack(spacing: 60) {
            ForEach(Array(stats.enumerated()), id: \.offset) { _, stat in
                VStack(spacing: 8) {
                    Text(stat.value)
                        .font(.system(size: 36, weight: .bold, design: .rounded))
                        .foregroundStyle(theme.accentColor)

                    Text(stat.label)
                        .font(.system(size: 20))
                        .foregroundStyle(theme.secondaryTextColor)
                }
            }
        }
        .padding(.vertical, 30)
        .padding(.horizontal, 40)
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(theme.textColor.opacity(0.05))
        )
    }
}

// MARK: - Progress Ring

struct ShareProgressRing: View {
    let current: Int
    let total: Int
    let theme: ShareTheme
    var size: CGFloat = 320
    var lineWidth: CGFloat = 24

    private var progress: Double {
        guard total > 0 else { return 0 }
        return Double(current) / Double(total)
    }

    var body: some View {
        ZStack {
            // Background ring
            Circle()
                .stroke(theme.accentColor.opacity(0.2), lineWidth: lineWidth)
                .frame(width: size, height: size)

            // Progress ring
            Circle()
                .trim(from: 0, to: progress)
                .stroke(
                    theme.accentColor,
                    style: StrokeStyle(lineWidth: lineWidth, lineCap: .round)
                )
                .frame(width: size, height: size)
                .rotationEffect(.degrees(-90))

            // Center content
            VStack(spacing: 8) {
                Text("\(current)")
                    .font(.system(size: 96, weight: .bold, design: .rounded))
                    .foregroundStyle(theme.textColor)

                Text("of \(total)")
                    .font(.system(size: 32, weight: .medium))
                    .foregroundStyle(theme.secondaryTextColor)
            }
        }
    }
}

// MARK: - Map Snapshot Generator

@MainActor
final class ShareMapSnapshotGenerator {

    /// Generate a progress map showing visited/remaining stadiums
    func generateProgressMap(
        visited: [Stadium],
        remaining: [Stadium],
        theme: ShareTheme
    ) async -> UIImage? {
        let allStadiums = visited + remaining
        guard !allStadiums.isEmpty else { return nil }

        let region = calculateRegion(for: allStadiums)
        let options = MKMapSnapshotter.Options()
        options.region = region
        options.size = ShareCardDimensions.mapSnapshotSize
        options.mapType = theme.useDarkMap ? .mutedStandard : .standard

        let snapshotter = MKMapSnapshotter(options: options)

        do {
            let snapshot = try await snapshotter.start()
            return drawStadiumMarkers(
                on: snapshot,
                visited: visited,
                remaining: remaining,
                accentColor: UIColor(theme.accentColor)
            )
        } catch {
            return nil
        }
    }

    /// Generate a route map for trip cards
    func generateRouteMap(
        stops: [TripStop],
        theme: ShareTheme
    ) async -> UIImage? {
        let stopsWithCoordinates = stops.filter { $0.coordinate != nil }
        guard stopsWithCoordinates.count >= 2 else { return nil }

        let coordinates = stopsWithCoordinates.compactMap { $0.coordinate }

        let region = calculateRegion(for: coordinates)
        let options = MKMapSnapshotter.Options()
        options.region = region
        options.size = ShareCardDimensions.routeMapSize
        options.mapType = theme.useDarkMap ? .mutedStandard : .standard

        let snapshotter = MKMapSnapshotter(options: options)

        do {
            let snapshot = try await snapshotter.start()
            return drawRoute(
                on: snapshot,
                stops: stopsWithCoordinates,
                accentColor: UIColor(theme.accentColor)
            )
        } catch {
            return nil
        }
    }

    // MARK: - Private Helpers

    private func calculateRegion(for stadiums: [Stadium]) -> MKCoordinateRegion {
        let coordinates = stadiums.map {
            CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)
        }
        return calculateRegion(for: coordinates)
    }

    private func calculateRegion(for coordinates: [CLLocationCoordinate2D]) -> MKCoordinateRegion {
        let minLat = coordinates.map(\.latitude).min() ?? 0
        let maxLat = coordinates.map(\.latitude).max() ?? 0
        let minLon = coordinates.map(\.longitude).min() ?? 0
        let maxLon = coordinates.map(\.longitude).max() ?? 0

        let center = CLLocationCoordinate2D(
            latitude: (minLat + maxLat) / 2,
            longitude: (minLon + maxLon) / 2
        )

        let span = MKCoordinateSpan(
            latitudeDelta: max((maxLat - minLat) * 1.4, 1),
            longitudeDelta: max((maxLon - minLon) * 1.4, 1)
        )

        return MKCoordinateRegion(center: center, span: span)
    }

    private func drawStadiumMarkers(
        on snapshot: MKMapSnapshotter.Snapshot,
        visited: [Stadium],
        remaining: [Stadium],
        accentColor: UIColor
    ) -> UIImage {
        let size = ShareCardDimensions.mapSnapshotSize
        return UIGraphicsImageRenderer(size: size).image { context in
            snapshot.image.draw(at: .zero)

            // Draw remaining (gray) first
            for stadium in remaining {
                let point = snapshot.point(for: CLLocationCoordinate2D(
                    latitude: stadium.latitude,
                    longitude: stadium.longitude
                ))
                drawMarker(at: point, color: .gray, context: context.cgContext)
            }

            // Draw visited (accent) on top
            for stadium in visited {
                let point = snapshot.point(for: CLLocationCoordinate2D(
                    latitude: stadium.latitude,
                    longitude: stadium.longitude
                ))
                drawMarker(at: point, color: accentColor, context: context.cgContext)
            }
        }
    }

    private func drawRoute(
        on snapshot: MKMapSnapshotter.Snapshot,
        stops: [TripStop],
        accentColor: UIColor
    ) -> UIImage {
        let size = ShareCardDimensions.routeMapSize
        return UIGraphicsImageRenderer(size: size).image { context in
            snapshot.image.draw(at: .zero)

            let cgContext = context.cgContext

            // Draw route line
            cgContext.setStrokeColor(accentColor.cgColor)
            cgContext.setLineWidth(4)
            cgContext.setLineCap(.round)
            cgContext.setLineJoin(.round)

            let points = stops.compactMap { stop -> CGPoint? in
                guard let coord = stop.coordinate else { return nil }
                return snapshot.point(for: coord)
            }

            if let first = points.first {
                cgContext.move(to: first)
                for point in points.dropFirst() {
                    cgContext.addLine(to: point)
                }
                cgContext.strokePath()
            }

            // Draw city markers
            for (index, stop) in stops.enumerated() {
                guard let coord = stop.coordinate else { continue }
                let point = snapshot.point(for: coord)
                drawCityMarker(
                    at: point,
                    label: String(stop.city.prefix(3)).uppercased(),
                    isFirst: index == 0,
                    isLast: index == stops.count - 1,
                    color: accentColor,
                    context: cgContext
                )
            }
        }
    }

    private func drawMarker(at point: CGPoint, color: UIColor, context: CGContext) {
        let markerSize: CGFloat = 16

        context.setFillColor(color.cgColor)
        context.fillEllipse(in: CGRect(
            x: point.x - markerSize / 2,
            y: point.y - markerSize / 2,
            width: markerSize,
            height: markerSize
        ))

        context.setStrokeColor(UIColor.white.cgColor)
        context.setLineWidth(2)
        context.strokeEllipse(in: CGRect(
            x: point.x - markerSize / 2,
            y: point.y - markerSize / 2,
            width: markerSize,
            height: markerSize
        ))
    }

    private func drawCityMarker(
        at point: CGPoint,
        label: String,
        isFirst: Bool,
        isLast: Bool,
        color: UIColor,
        context: CGContext
    ) {
        let markerSize: CGFloat = isFirst || isLast ? 24 : 18

        // Outer circle
        context.setFillColor(color.cgColor)
        context.fillEllipse(in: CGRect(
            x: point.x - markerSize / 2,
            y: point.y - markerSize / 2,
            width: markerSize,
            height: markerSize
        ))

        // White border
        context.setStrokeColor(UIColor.white.cgColor)
        context.setLineWidth(3)
        context.strokeEllipse(in: CGRect(
            x: point.x - markerSize / 2,
            y: point.y - markerSize / 2,
            width: markerSize,
            height: markerSize
        ))

        // Label above marker
        let labelRect = CGRect(
            x: point.x - 30,
            y: point.y - markerSize / 2 - 22,
            width: 60,
            height: 20
        )

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center

        let attributes: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 12, weight: .bold),
            .foregroundColor: UIColor.white,
            .paragraphStyle: paragraphStyle
        ]

        // Draw label background
        let labelBgRect = CGRect(
            x: point.x - 22,
            y: point.y - markerSize / 2 - 24,
            width: 44,
            height: 18
        )
        context.setFillColor(color.withAlphaComponent(0.9).cgColor)
        let path = UIBezierPath(roundedRect: labelBgRect, cornerRadius: 4)
        context.addPath(path.cgPath)
        context.fillPath()

        label.draw(in: labelRect, withAttributes: attributes)
    }
}
