//
//  ShareableContent.swift
//  SportsTime
//
//  Protocol for shareable content and theme definitions.
//

import SwiftUI
import UIKit

// MARK: - Shareable Content Protocol

protocol ShareableContent {
    var cardType: ShareCardType { get }
    func render(theme: ShareTheme) async throws -> UIImage
}

// MARK: - Card Types

enum ShareCardType: String, CaseIterable {
    case tripSummary
    case achievementSpotlight
    case achievementCollection
    case stadiumProgress
}

// MARK: - Share Theme

struct ShareTheme: Identifiable, Hashable {
    let id: String
    let name: String
    let gradientColors: [Color]
    let accentColor: Color
    let textColor: Color
    let secondaryTextColor: Color
    let useDarkMap: Bool

    // MARK: - Preset Themes

    static let dark = ShareTheme(
        id: "dark",
        name: "Dark",
        gradientColors: [Color(hex: "1A1A2E"), Color(hex: "16213E")],
        accentColor: Color(hex: "FF6B35"),
        textColor: .white,
        secondaryTextColor: Color(hex: "B8B8D1"),
        useDarkMap: true
    )

    static let light = ShareTheme(
        id: "light",
        name: "Light",
        gradientColors: [.white, Color(hex: "F5F5F5")],
        accentColor: Color(hex: "FF6B35"),
        textColor: Color(hex: "1A1A2E"),
        secondaryTextColor: Color(hex: "666666"),
        useDarkMap: false
    )

    static let midnight = ShareTheme(
        id: "midnight",
        name: "Midnight",
        gradientColors: [Color(hex: "0D1B2A"), Color(hex: "1B263B")],
        accentColor: Color(hex: "00D4FF"),
        textColor: .white,
        secondaryTextColor: Color(hex: "A0AEC0"),
        useDarkMap: true
    )

    static let forest = ShareTheme(
        id: "forest",
        name: "Forest",
        gradientColors: [Color(hex: "1B4332"), Color(hex: "2D6A4F")],
        accentColor: Color(hex: "95D5B2"),
        textColor: .white,
        secondaryTextColor: Color(hex: "B7E4C7"),
        useDarkMap: false
    )

    static let sunset = ShareTheme(
        id: "sunset",
        name: "Sunset",
        gradientColors: [Color(hex: "FF6B35"), Color(hex: "F7931E")],
        accentColor: .white,
        textColor: .white,
        secondaryTextColor: Color(hex: "FFE5D9"),
        useDarkMap: false
    )

    static let berry = ShareTheme(
        id: "berry",
        name: "Berry",
        gradientColors: [Color(hex: "4A0E4E"), Color(hex: "81267E")],
        accentColor: Color(hex: "FF85A1"),
        textColor: .white,
        secondaryTextColor: Color(hex: "E0B0FF"),
        useDarkMap: true
    )

    static let ocean = ShareTheme(
        id: "ocean",
        name: "Ocean",
        gradientColors: [Color(hex: "023E8A"), Color(hex: "0077B6")],
        accentColor: Color(hex: "90E0EF"),
        textColor: .white,
        secondaryTextColor: Color(hex: "CAF0F8"),
        useDarkMap: true
    )

    static let slate = ShareTheme(
        id: "slate",
        name: "Slate",
        gradientColors: [Color(hex: "2B2D42"), Color(hex: "3D405B")],
        accentColor: Color(hex: "F4A261"),
        textColor: Color(hex: "EDF2F4"),
        secondaryTextColor: Color(hex: "8D99AE"),
        useDarkMap: true
    )

    static let all: [ShareTheme] = [.dark, .light, .midnight, .forest, .sunset, .berry, .ocean, .slate]

    static func theme(byId id: String) -> ShareTheme {
        all.first { $0.id == id } ?? .dark
    }

    // MARK: - Derived Theme Properties

    /// Glass panel fill — textColor at low opacity
    var surfaceColor: Color {
        textColor.opacity(0.08)
    }

    /// Panel border — textColor at medium-low opacity
    var borderColor: Color {
        textColor.opacity(0.15)
    }

    /// Glow effect color — accentColor at medium opacity
    var glowColor: Color {
        accentColor.opacity(0.4)
    }

    /// Highlight gradient for accent elements
    var highlightGradient: [Color] {
        [accentColor, accentColor.opacity(0.6)]
    }

    /// Mid-tone color derived from gradient endpoints for richer backgrounds
    var midGradientColor: Color {
        gradientColors.count >= 2
            ? gradientColors[0].blendedWith(gradientColors[1], fraction: 0.5)
            : gradientColors.first ?? .black
    }
}

// MARK: - Color Blending Helper

extension Color {
    /// Simple blend between two colors at a given fraction (0 = self, 1 = other)
    func blendedWith(_ other: Color, fraction: Double) -> Color {
        let f = max(0, min(1, fraction))
        let c1 = UIColor(self).rgbaComponents
        let c2 = UIColor(other).rgbaComponents
        return Color(
            red: c1.r + (c2.r - c1.r) * f,
            green: c1.g + (c2.g - c1.g) * f,
            blue: c1.b + (c2.b - c1.b) * f,
            opacity: c1.a + (c2.a - c1.a) * f
        )
    }
}

private extension UIColor {
    var rgbaComponents: (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
        var r: CGFloat = 0
        var g: CGFloat = 0
        var b: CGFloat = 0
        var a: CGFloat = 0

        if getRed(&r, green: &g, blue: &b, alpha: &a) {
            return (r, g, b, a)
        }

        var white: CGFloat = 0
        if getWhite(&white, alpha: &a) {
            return (white, white, white, a)
        }

        return (0, 0, 0, 1)
    }
}

// MARK: - Share Errors

enum ShareError: Error, LocalizedError {
    case renderingFailed
    case mapSnapshotFailed
    case instagramNotInstalled

    var errorDescription: String? {
        switch self {
        case .renderingFailed:
            return "Failed to render share card"
        case .mapSnapshotFailed:
            return "Failed to generate map snapshot"
        case .instagramNotInstalled:
            return "Instagram is not installed"
        }
    }
}

// MARK: - Card Dimensions

enum ShareCardDimensions {
    static let cardSize = CGSize(width: 1080, height: 1920)
    static let mapSnapshotSize = CGSize(width: 960, height: 480)  // Must fit within cardSize.width - 2*padding
    static let routeMapSize = CGSize(width: 960, height: 576)     // Must fit within cardSize.width - 2*padding
    static let padding: CGFloat = 60
    static let headerHeight: CGFloat = 120
    static let footerHeight: CGFloat = 100
}
