//
//  ProgressCardGenerator.swift
//  SportsTime
//
//  Generates shareable progress cards for social media.
//  Cards include progress ring, stats, optional username, and app branding.
//

import SwiftUI
import UIKit
import MapKit

// MARK: - Progress Card Generator

@MainActor
final class ProgressCardGenerator {

    // Card dimensions (Instagram story size)
    private static let cardSize = CGSize(width: 1080, height: 1920)
    private static let mapSnapshotSize = CGSize(width: 1000, height: 500)

    // MARK: - Generate Card

    /// Generate a shareable progress card image
    /// - Parameters:
    ///   - progress: The league progress data
    ///   - options: Card generation options
    /// - Returns: The generated UIImage
    func generateCard(
        progress: LeagueProgress,
        options: ProgressCardOptions = ProgressCardOptions()
    ) async throws -> UIImage {
        // Generate map snapshot if needed
        var mapSnapshot: UIImage?
        if options.includeMapSnapshot {
            mapSnapshot = await generateMapSnapshot(
                visited: progress.stadiumsVisited,
                remaining: progress.stadiumsRemaining
            )
        }

        // Render SwiftUI view to image
        let cardView = ProgressCardView(
            progress: progress,
            options: options,
            mapSnapshot: mapSnapshot
        )

        let renderer = ImageRenderer(content: cardView)
        renderer.scale = 3.0 // High resolution

        guard let image = renderer.uiImage else {
            throw CardGeneratorError.renderingFailed
        }

        return image
    }

    /// Generate a map snapshot showing visited/unvisited stadiums
    /// - Parameters:
    ///   - visited: Stadiums that have been visited
    ///   - remaining: Stadiums not yet visited
    /// - Returns: The map snapshot image
    func generateMapSnapshot(
        visited: [Stadium],
        remaining: [Stadium]
    ) async -> UIImage? {
        let allStadiums = visited + remaining
        guard !allStadiums.isEmpty else { return nil }

        // Calculate region to show all stadiums
        let coordinates = allStadiums.map {
            CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)
        }

        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: (maxLat - minLat) * 1.3,
            longitudeDelta: (maxLon - minLon) * 1.3
        )

        let region = MKCoordinateRegion(center: center, span: span)

        // Create snapshot options
        let options = MKMapSnapshotter.Options()
        options.region = region
        options.size = Self.mapSnapshotSize
        options.mapType = .mutedStandard

        let snapshotter = MKMapSnapshotter(options: options)

        do {
            let snapshot = try await snapshotter.start()

            // Draw annotations on snapshot
            let image = UIGraphicsImageRenderer(size: Self.mapSnapshotSize).image { context in
                snapshot.image.draw(at: .zero)

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

                for stadium in visited {
                    let point = snapshot.point(for: CLLocationCoordinate2D(
                        latitude: stadium.latitude,
                        longitude: stadium.longitude
                    ))
                    drawMarker(at: point, color: UIColor(Theme.warmOrange), context: context.cgContext)
                }
            }

            return image
        } catch {
            return nil
        }
    }

    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
        ))

        // White border
        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
        ))
    }
}

// MARK: - Card Generator Errors

enum CardGeneratorError: Error, LocalizedError {
    case renderingFailed
    case mapSnapshotFailed

    var errorDescription: String? {
        switch self {
        case .renderingFailed:
            return "Failed to render progress card"
        case .mapSnapshotFailed:
            return "Failed to generate map snapshot"
        }
    }
}

// MARK: - Progress Card View

struct ProgressCardView: View {
    let progress: LeagueProgress
    let options: ProgressCardOptions
    let mapSnapshot: UIImage?

    var body: some View {
        ZStack {
            // Background gradient
            LinearGradient(
                colors: options.cardStyle == .dark
                    ? [Color(hex: "1A1A2E"), Color(hex: "16213E")]
                    : [Color.white, Color(hex: "F5F5F5")],
                startPoint: .top,
                endPoint: .bottom
            )

            VStack(spacing: 40) {
                // App logo and title
                headerSection

                Spacer()

                // Progress ring
                progressRingSection

                // Stats row
                if options.includeStats {
                    statsSection
                }

                // Map snapshot
                if options.includeMapSnapshot, let snapshot = mapSnapshot {
                    mapSection(image: snapshot)
                }

                Spacer()

                // Username if included
                if options.includeUsername, let username = options.username, !username.isEmpty {
                    usernameSection(username)
                }

                // App branding footer
                footerSection
            }
            .padding(60)
        }
        .frame(width: 1080, height: 1920)
    }

    // MARK: - Header

    private var headerSection: some View {
        VStack(spacing: 16) {
            // Sport icon
            ZStack {
                Circle()
                    .fill(progress.sport.themeColor.opacity(0.2))
                    .frame(width: 80, height: 80)

                Image(systemName: progress.sport.iconName)
                    .font(.system(size: 40))
                    .foregroundStyle(progress.sport.themeColor)
            }

            Text("\(progress.sport.displayName) Stadium Quest")
                .font(.system(size: 48, weight: .bold, design: .rounded))
                .foregroundStyle(options.cardStyle.textColor)
        }
    }

    // MARK: - Progress Ring

    private var progressRingSection: some View {
        ZStack {
            // Background ring
            Circle()
                .stroke(Theme.warmOrange.opacity(0.2), lineWidth: 24)
                .frame(width: 320, height: 320)

            // Progress ring
            Circle()
                .trim(from: 0, to: progress.completionPercentage / 100)
                .stroke(
                    Theme.warmOrange,
                    style: StrokeStyle(lineWidth: 24, lineCap: .round)
                )
                .frame(width: 320, height: 320)
                .rotationEffect(.degrees(-90))

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

                Text("of \(progress.totalStadiums)")
                    .font(.system(size: 32, weight: .medium))
                    .foregroundStyle(options.cardStyle.secondaryTextColor)

                Text("Stadiums Visited")
                    .font(.system(size: 24))
                    .foregroundStyle(options.cardStyle.secondaryTextColor)
            }
        }
    }

    // MARK: - Stats

    private var statsSection: some View {
        HStack(spacing: 60) {
            statItem(value: "\(progress.visitedStadiums)", label: "Visited")
            statItem(value: "\(progress.totalStadiums - progress.visitedStadiums)", label: "Remaining")
            statItem(value: String(format: "%.0f%%", progress.completionPercentage), label: "Complete")
        }
        .padding(.vertical, 30)
        .padding(.horizontal, 40)
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(options.cardStyle == .dark
                    ? Color.white.opacity(0.05)
                    : Color.black.opacity(0.05))
        )
    }

    private func statItem(value: String, label: String) -> some View {
        VStack(spacing: 8) {
            Text(value)
                .font(.system(size: 36, weight: .bold, design: .rounded))
                .foregroundStyle(Theme.warmOrange)

            Text(label)
                .font(.system(size: 20))
                .foregroundStyle(options.cardStyle.secondaryTextColor)
        }
    }

    // MARK: - Map

    private func mapSection(image: UIImage) -> some View {
        Image(uiImage: image)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(maxWidth: 960)
            .clipShape(RoundedRectangle(cornerRadius: 20))
            .overlay {
                RoundedRectangle(cornerRadius: 20)
                    .stroke(Theme.warmOrange.opacity(0.3), lineWidth: 2)
            }
    }

    // MARK: - Username

    private func usernameSection(_ username: String) -> some View {
        HStack(spacing: 12) {
            Image(systemName: "person.circle.fill")
                .font(.system(size: 24))
            Text(username)
                .font(.system(size: 28, weight: .medium))
        }
        .foregroundStyle(options.cardStyle.secondaryTextColor)
    }

    // MARK: - Footer

    private var footerSection: 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.warmOrange)

            Text("Track your stadium adventures")
                .font(.system(size: 18))
                .foregroundStyle(options.cardStyle.secondaryTextColor)
        }
    }
}

// MARK: - Progress Share View

struct ProgressShareView: View {
    let progress: LeagueProgress

    @Environment(\.colorScheme) private var colorScheme
    @Environment(\.dismiss) private var dismiss

    @State private var generatedImage: UIImage?
    @State private var isGenerating = false
    @State private var showShareSheet = false
    @State private var error: String?

    @State private var includeUsername = true
    @State private var username = ""
    @State private var includeMap = true
    @State private var cardStyle: ProgressCardOptions.CardStyle = .dark

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: Theme.Spacing.lg) {
                    // Preview card
                    previewCard
                        .padding(.horizontal)

                    // Options
                    optionsSection

                    // Generate button
                    generateButton
                        .padding(.horizontal)
                }
                .padding(.vertical)
            }
            .navigationTitle("Share Progress")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
            }
            .sheet(isPresented: $showShareSheet) {
                if let image = generatedImage {
                    ShareSheet(items: [image])
                }
            }
            .alert("Error", isPresented: .constant(error != nil)) {
                Button("OK") { error = nil }
            } message: {
                Text(error ?? "")
            }
        }
    }

    private var previewCard: some View {
        VStack(spacing: Theme.Spacing.md) {
            Text("Preview")
                .font(.system(size: Theme.FontSize.caption, weight: .medium))
                .foregroundStyle(Theme.textMuted(colorScheme))

            // Mini preview
            ZStack {
                RoundedRectangle(cornerRadius: Theme.CornerRadius.medium)
                    .fill(cardStyle == .dark
                        ? Color(hex: "1A1A2E")
                        : Color.white)
                    .aspectRatio(9/16, contentMode: .fit)
                    .frame(maxHeight: 300)

                VStack(spacing: 12) {
                    // Sport badge
                    HStack(spacing: 4) {
                        Image(systemName: progress.sport.iconName)
                        Text(progress.sport.displayName)
                    }
                    .font(.system(size: 12, weight: .semibold))
                    .foregroundStyle(progress.sport.themeColor)

                    // Progress ring
                    ZStack {
                        Circle()
                            .stroke(Theme.warmOrange.opacity(0.2), lineWidth: 4)
                            .frame(width: 60, height: 60)

                        Circle()
                            .trim(from: 0, to: progress.completionPercentage / 100)
                            .stroke(Theme.warmOrange, style: StrokeStyle(lineWidth: 4, lineCap: .round))
                            .frame(width: 60, height: 60)
                            .rotationEffect(.degrees(-90))

                        VStack(spacing: 0) {
                            Text("\(progress.visitedStadiums)")
                                .font(.system(size: 18, weight: .bold))
                            Text("/\(progress.totalStadiums)")
                                .font(.system(size: 10))
                        }
                        .foregroundStyle(cardStyle == .dark ? .white : .black)
                    }

                    if includeMap {
                        RoundedRectangle(cornerRadius: 4)
                            .fill(Color.gray.opacity(0.2))
                            .frame(height: 40)
                            .overlay {
                                Image(systemName: "map")
                                    .foregroundStyle(Color.gray)
                            }
                    }

                    if includeUsername && !username.isEmpty {
                        Text("@\(username)")
                            .font(.system(size: 10))
                            .foregroundStyle(cardStyle == .dark ? Color.gray : Color.gray)
                    }

                    // Branding
                    HStack(spacing: 4) {
                        Image(systemName: "sportscourt.fill")
                        Text("SportsTime")
                    }
                    .font(.system(size: 10, weight: .medium))
                    .foregroundStyle(Theme.warmOrange)
                }
                .padding()
            }
        }
    }

    private var optionsSection: some View {
        VStack(spacing: Theme.Spacing.md) {
            // Style selector
            VStack(alignment: .leading, spacing: Theme.Spacing.xs) {
                Text("Style")
                    .font(.system(size: Theme.FontSize.caption, weight: .medium))
                    .foregroundStyle(Theme.textMuted(colorScheme))

                HStack(spacing: Theme.Spacing.sm) {
                    styleButton(style: .dark, label: "Dark")
                    styleButton(style: .light, label: "Light")
                }
            }
            .padding(.horizontal)

            // Username toggle
            Toggle(isOn: $includeUsername) {
                Text("Include Username")
                    .font(.system(size: Theme.FontSize.body))
            }
            .padding(.horizontal)

            if includeUsername {
                TextField("Username", text: $username)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            }

            // Map toggle
            Toggle(isOn: $includeMap) {
                Text("Include Map")
                    .font(.system(size: Theme.FontSize.body))
            }
            .padding(.horizontal)
        }
        .padding(.vertical)
        .background(Theme.cardBackground(colorScheme))
    }

    private func styleButton(style: ProgressCardOptions.CardStyle, label: String) -> some View {
        Button {
            withAnimation { cardStyle = style }
        } label: {
            Text(label)
                .font(.system(size: Theme.FontSize.caption, weight: .medium))
                .foregroundStyle(cardStyle == style ? .white : Theme.textPrimary(colorScheme))
                .padding(.horizontal, Theme.Spacing.md)
                .padding(.vertical, Theme.Spacing.sm)
                .background(cardStyle == style ? Theme.warmOrange : Theme.cardBackgroundElevated(colorScheme))
                .clipShape(Capsule())
        }
        .buttonStyle(.plain)
    }

    private var generateButton: some View {
        Button {
            generateCard()
        } label: {
            HStack {
                if isGenerating {
                    ThemedSpinnerCompact(size: 18, color: .white)
                } else {
                    Image(systemName: "square.and.arrow.up")
                }
                Text(isGenerating ? "Generating..." : "Generate & Share")
            }
            .frame(maxWidth: .infinity)
            .padding(Theme.Spacing.md)
            .background(Theme.warmOrange)
            .foregroundStyle(.white)
            .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
        }
        .disabled(isGenerating)
    }

    private func generateCard() {
        isGenerating = true

        Task {
            let options = ProgressCardOptions(
                includeUsername: includeUsername,
                username: username,
                includeMapSnapshot: includeMap,
                includeStats: true,
                cardStyle: cardStyle
            )

            let generator = ProgressCardGenerator()

            do {
                generatedImage = try await generator.generateCard(
                    progress: progress,
                    options: options
                )
                showShareSheet = true
            } catch {
                self.error = error.localizedDescription
            }

            isGenerating = false
        }
    }
}

// MARK: - Preview

#Preview {
    ProgressShareView(progress: LeagueProgress(
        sport: .mlb,
        totalStadiums: 30,
        visitedStadiums: 12,
        stadiumsVisited: [],
        stadiumsRemaining: []
    ))
}
