//
//  Constants.swift
//  vibes
//
//  Created by Yamill Vallecillo on 6/30/25.
//

import SwiftUI

struct Constants {
    // MARK: - App Colors (Semantic Tokens)
    struct Colors {
        // MARK: - Background Colors
        struct Background {
            static let primary = Color(hex: "#101012")       // Dumbo.50
            static let secondary = Color(hex: "#1c1c1f")     // Dumbo.100
            static let tertiary = Color(hex: "#252529")      // Dumbo.150

            // Glass Effects
            struct Glass {
                static let thin = Color.white.opacity(0.04)   // Opacity.White.4
                static let thick = Color.white.opacity(0.10)  // Opacity.White.10
                static let dense = Color.white.opacity(0.20)  // Opacity.White.20
            }

            // Fog Effects
            struct Fog {
                static let thin = Color.white.opacity(0.04)   // Opacity.White.4
                static let thick = Color.white.opacity(0.10)  // Opacity.White.10
                static let dense = Color.white.opacity(0.30)  // Opacity.White.30
            }

            // Overlays
            static let lightOverlay = Color.white.opacity(0.90)  // Opacity.White.90
            static let darkOverlay = Color.black.opacity(0.30)   // Opacity.Black.30

            // Smoke Effects
            struct Smoke {
                static let thin = Color(rgba: (28, 28, 31, 0.04))   // Opacity.Gray.4
                static let thick = Color(rgba: (28, 28, 31, 0.40))  // Opacity.Gray.40
                static let dense = Color(rgba: (28, 28, 31, 0.60))  // Opacity.Gray.60
            }

            // Gradient
            struct Gradient {
                static let start = Color(rgba: (28, 28, 31, 0.60))  // Opacity.Gray.60
                static let end = Color(rgba: (28, 28, 31, 0))       // Opacity.Gray.0
            }
        }

        // MARK: - Foreground Colors
        struct Foreground {
            static let primary = Color(hex: "#f7f4ef")       // Dumbo.900
            static let secondary = Color(hex: "#c2c2c1")     // Dumbo.700
            static let tertiary = Color(hex: "#a3a3a3")      // Dumbo.600
            static let inactive = Color(hex: "#6a6a72")      // Dumbo.450
            static let onError = Color(hex: "#ffffff")       // White
        }

        // MARK: - Border Colors
        struct Border {
            static let primary = Color.white.opacity(0.10)   // Opacity.White.10
            static let secondary = Color.white.opacity(0.15) // Opacity.White.15
        }

        // MARK: - Overlay Colors
        struct Overlay {
            static let onPrimary = Color.white.opacity(0.04)  // Opacity.White.4
            static let onLight = Color.black.opacity(0.04)    // Opacity.Black.4
            static let onDark = Color.white.opacity(0.04)     // Opacity.White.4
        }
        
        // MARK: - Accent Colors
        struct Accent {
            static let brand = Color(hex: "#fd429c")         // Strawberry.600
            static let v4 = Color(hex: "#c3e734")            // Green.300
            static let pink = Color(hex: "#fd429c")          // Strawberry.600
            static let blue = Color(hex: "#1f8bff")          // Dodger Blue.600
            static let orange = Color(hex: "#ff6a00")        // Pumpkin.500
            static let green = Color(hex: "#02d95c")         // Slime.600
            static let yellow = Color(hex: "#f5d907")        // Dandelion.700
            static let purple = Color(hex: "#8b6efe")        // Amethyst.600
            static let success = Color(hex: "#4aab04")       // Grass.500
            static let error = Color(hex: "#f8441b")         // Vermilion.500
        }
    }
    
    // MARK: - Palette Colors (Raw Color Values)
    struct Palette {
        // MARK: - Dumbo (Primary Gray Scale)
        struct Dumbo {
            static let _50 = Color(hex: "#101012")
            static let _100 = Color(hex: "#1c1c1f")
            static let _150 = Color(hex: "#252529")
            static let _200 = Color(hex: "#2e2e33")
            static let _250 = Color(hex: "#38383e")
            static let _300 = Color(hex: "#424249")
            static let _350 = Color(hex: "#4e4d55")
            static let _400 = Color(hex: "#5b5b62")
            static let _450 = Color(hex: "#6a6a72")
            static let _500 = Color(hex: "#7d7c83")
            static let _550 = Color(hex: "#919093")
            static let _600 = Color(hex: "#a3a3a3")
            static let _650 = Color(hex: "#b3b3b2")
            static let _700 = Color(hex: "#c2c2c1")
            static let _750 = Color(hex: "#d2d0ce")
            static let _800 = Color(hex: "#e0deda")
            static let _850 = Color(hex: "#edeae4")
            static let _900 = Color(hex: "#f7f4ef")
            static let _950 = Color(hex: "#fcfbf9")
        }
        
        // MARK: - Strawberry (Brand Pink)
        struct Strawberry {
            static let _100 = Color(hex: "#2e0c1d")
            static let _200 = Color(hex: "#4f1330")
            static let _300 = Color(hex: "#701943")
            static let _400 = Color(hex: "#981e59")
            static let _500 = Color(hex: "#de1677")
            static let _600 = Color(hex: "#fd429c")
            static let _700 = Color(hex: "#ff78b9")
            static let _800 = Color(hex: "#ffa4d0")
            static let _900 = Color(hex: "#ffcfe6")
        }
        
        // MARK: - Dodger Blue
        struct DodgerBlue {
            static let _100 = Color(hex: "#002041")
            static let _200 = Color(hex: "#003671")
            static let _300 = Color(hex: "#004a98")
            static let _400 = Color(hex: "#005cbe")
            static let _500 = Color(hex: "#0071ea")
            static let _600 = Color(hex: "#1f8bff")
            static let _700 = Color(hex: "#58a8ff")
            static let _800 = Color(hex: "#91c6ff")
            static let _900 = Color(hex: "#cae3ff")
        }
        
        // MARK: - Pumpkin (Orange)
        struct Pumpkin {
            static let _100 = Color(hex: "#3b1900")
            static let _200 = Color(hex: "#652a00")
            static let _300 = Color(hex: "#8d3b00")
            static let _400 = Color(hex: "#bc4e00")
            static let _500 = Color(hex: "#ff6a00")
            static let _600 = Color(hex: "#ff9448")
            static let _700 = Color(hex: "#ffb27b")
            static let _800 = Color(hex: "#ffcba6")
            static let _900 = Color(hex: "#ffe4d1")
        }
        
        // MARK: - Slime (Green)
        struct Slime {
            static let _100 = Color(hex: "#003516")
            static let _200 = Color(hex: "#015725")
            static let _300 = Color(hex: "#017431")
            static let _400 = Color(hex: "#01903d")
            static let _500 = Color(hex: "#02af4a")
            static let _600 = Color(hex: "#02d95c")
            static let _700 = Color(hex: "#23fd7e")
            static let _800 = Color(hex: "#7afeb1")
            static let _900 = Color(hex: "#c6fedd")
        }
        
        // MARK: - Dandelion (Yellow)
        struct Dandelion {
            static let _100 = Color(hex: "#2b2201")
            static let _200 = Color(hex: "#504102")
            static let _300 = Color(hex: "#725f03")
            static let _400 = Color(hex: "#947d04")
            static let _500 = Color(hex: "#b49c05")
            static let _600 = Color(hex: "#d4bb06")
            static let _700 = Color(hex: "#f5d907")
            static let _800 = Color(hex: "#f9e54f")
            static let _850 = Color(hex: "#faed87")
            static let _900 = Color(hex: "#fbf4ba")
            static let _950 = Color(hex: "#fdfae2")
        }
        
        // MARK: - Amethyst (Purple)
        struct Amethyst {
            static let _100 = Color(hex: "#251b51")
            static let _200 = Color(hex: "#3d2a87")
            static let _300 = Color(hex: "#4d33b7")
            static let _400 = Color(hex: "#6244d7")
            static let _500 = Color(hex: "#7251f7")
            static let _600 = Color(hex: "#8b6efe")
            static let _700 = Color(hex: "#9e86ff")
            static let _800 = Color(hex: "#b7a4ff")
            static let _900 = Color(hex: "#d7cdff")
        }
        
        // MARK: - Vermilion (Error Red)
        struct Vermilion {
            static let _100 = Color(hex: "#3b0c02")
            static let _200 = Color(hex: "#661503")
            static let _300 = Color(hex: "#901e04")
            static let _400 = Color(hex: "#c32906")
            static let _500 = Color(hex: "#f8441b")
            static let _600 = Color(hex: "#fa7658")
            static let _700 = Color(hex: "#fb9b85")
            static let _800 = Color(hex: "#fcbaab")
            static let _900 = Color(hex: "#fedad2")
        }
        
        // MARK: - Grass (Success Green)
        struct Grass {
            static let _100 = Color(hex: "#173501")
            static let _200 = Color(hex: "#255602")
            static let _300 = Color(hex: "#317203")
            static let _400 = Color(hex: "#3d8d03")
            static let _500 = Color(hex: "#4aab04")
            static let _600 = Color(hex: "#5bd205")
            static let _700 = Color(hex: "#7afa1f")
            static let _800 = Color(hex: "#aefc76")
            static let _900 = Color(hex: "#ddfec5")
        }
        
        // MARK: - Basic Colors
        static let white = Color(hex: "#ffffff")
        static let black = Color(hex: "#000000")
        
        // MARK: - Green (V4 Accent)
        struct Green {
            static let _300 = Color(hex: "#c3e734")
            static let _500 = Color(hex: "#46731b")
        }
    }
    
    // Legacy constants (kept for backwards compatibility)
    static let BorderPrimary: Color = Colors.Border.primary
    static let BackgroundPrimary: Color = Colors.Background.primary
    static let ForegroundPrimary: Color = Colors.Foreground.primary
    static let ForegroundSecondary: Color = Colors.Foreground.secondary
    static let ForegroundTertiary: Color = Colors.Foreground.tertiary
    
    // Typography System
    struct Typography {
        // Timecode - 10/12 - Using Input Sans Regular
        static let timecode = Font.custom("Input Sans", size: 10)
        
        static let timecodeMedium = Font.custom("Input Sans", size: 12).weight(.medium)
        
        // xSmall (Title) - 12/16 with medium weight
        static let xSmallTitle = Font.custom("PP Neue Montreal", size: 12).weight(.medium)
        
        // xSmall (Regular) - 12/16 with kerning 0.24
        static let xSmallRegular = Font.custom("PP Neue Montreal", size: 12)
        
        // Small (Title) - 14/20
        static let smallTitle = Font.custom("PPNeueMontreal-Medium", size: 14)
        
        // Small 14/20
        static let small = Font.custom("PP Neue Montreal", size: 14)
        
        // Medium (Title) - 16/24
        static let mediumTitle = Font.custom("PPNeueMontreal-Medium", size: 16)
        
        // Medium (Regular) - 16/24
        static let mediumRegular = Font.custom("PP Neue Montreal", size: 16)
        
        // Large (Title) - 18/28
        static let largeTitle = Font.custom("PPNeueMontreal-Medium", size: 18)
        
        // Large (Regular) - 18/28
        static let largeRegular = Font.custom("PP Neue Montreal", size: 18)

        // xLarge (Title) - 24/28
        static let xLargeTitle = Font.custom("PPNeueMontreal-Semibold", size: 24)

        // xLarge (Regular) - 24/28
        static let xLargeRegular = Font.custom("PP Neue Montreal", size: 24)
    }
    
    // Line Heights (for reference when needed)
    struct LineHeight {
        static let timecode: CGFloat = 12
        static let xSmall: CGFloat = 16
        static let small: CGFloat = 20
        static let medium: CGFloat = 24
        static let large: CGFloat = 28
        static let xLarge: CGFloat = 28
    }
}

extension Color {
    init(hex: String) {
        let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
        var int: UInt64 = 0
        Scanner(string: hex).scanHexInt64(&int)
        let a, r, g, b: UInt64
        switch hex.count {
        case 3: // RGB (12-bit)
            (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
        case 6: // RGB (24-bit)
            (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
        case 8: // ARGB (32-bit)
            (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
        default:
            (a, r, g, b) = (1, 1, 1, 0)
        }

        self.init(
            .sRGB,
            red: Double(r) / 255,
            green: Double(g) / 255,
            blue:  Double(b) / 255,
            opacity: Double(a) / 255
        )
    }
    
    init(rgba: (Int, Int, Int, Double)) {
        self.init(
            .sRGB,
            red: Double(rgba.0) / 255,
            green: Double(rgba.1) / 255,
            blue: Double(rgba.2) / 255,
            opacity: rgba.3
        )
    }
}
