import SwiftUI

public extension Color {
    // MARK: - Semantic V2

    enum SemanticV2 {
        // Background Colors
        public static var backgroundPrimary = dynamicColor(light: Color.PaletteV2.dumbo900, dark: Color.PaletteV2.gray50)
        public static var backgroundPrimaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite0, dark: Color.PaletteV2.opacityWhite0)

        // FIXME: Fix me after we figure out what we're doing with branding here. The trouble is that dark mode wants to get brighter in the secondary color, and it doesn't mesh for how light mode wants to get darker. For now, light mode will follow suit.
//        public static var backgroundSecondary = dynamicColor(light: Color.PaletteV2.dumbo850, dark: Color.PaletteV2.gray100)
        public static var backgroundSecondary = dynamicColor(light: Color.PaletteV2.dumbo950, dark: Color.PaletteV2.gray100)
        public static var backgroundSecondaryGlass = dynamicColor(light: Color.SemanticV2.backgroundFogThin, dark: Color.SemanticV2.backgroundFogThin)

        public static var backgroundTertiary = dynamicColor(light: Color.PaletteV2.dumbo800, dark: Color.PaletteV2.gray200)
        public static var backgroundTertiaryGlass = dynamicColor(light: Color.SemanticV2.backgroundFogThick, dark: Color.SemanticV2.backgroundFogThick)

        public static var backgroundLightOverlay = dynamicColor(light: Color.PaletteV2.opacityWhite90, dark: Color.PaletteV2.opacityWhite90)
        public static var backgroundDarkOverlay = dynamicColor(light: Color.PaletteV2.opacityBlack30, dark: Color.PaletteV2.opacityBlack30)

        public static var backgroundGlassThin = dynamicColor(light: Color.PaletteV2.opacityBlack4, dark: Color.PaletteV2.opacityWhite4)
        public static var backgroundGlassThick = dynamicColor(light: Color.PaletteV2.opacityBlack10, dark: Color.PaletteV2.opacityWhite10)
        public static var backgroundGlassDense = dynamicColor(light: Color.PaletteV2.opacityBlack20, dark: Color.PaletteV2.opacityWhite20)

        public static var backgroundFogThin = dynamicColor(light: Color.PaletteV2.opacityWhite4, dark: Color.PaletteV2.opacityWhite4)
        public static var backgroundFogThick = dynamicColor(light: Color.PaletteV2.opacityWhite10, dark: Color.PaletteV2.opacityWhite10)
        public static var backgroundFogDense = dynamicColor(light: Color.PaletteV2.opacityWhite20, dark: Color.PaletteV2.opacityWhite20)

        public static var backgroundSmokeThin = dynamicColor(light: Color.PaletteV2.opacityWhite4, dark: Color.PaletteV2.opacityBlack4)
        public static var backgroundSmokeThick = dynamicColor(light: Color.PaletteV2.opacityWhite10, dark: Color.PaletteV2.opacityBlack10)
        public static var backgroundSmokeDense = dynamicColor(light: Color.PaletteV2.opacityWhite20, dark: Color.PaletteV2.opacityBlack20)

        // Foreground Colors
        public static var foregroundPrimary = dynamicColor(light: Color.PaletteV2.dumbo50, dark: Color.PaletteV2.gray950)
        public static var foregroundPrimaryOnDark = dynamicColor(light: Color.PaletteV2.dumbo900, dark: Color.PaletteV2.gray950)
        public static var foregroundPrimaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite90, dark: Color.PaletteV2.opacityWhite90)
        public static var foregroundPrimaryOnLight = dynamicColor(light: Color.PaletteV2.dumbo50, dark: Color.PaletteV2.gray50)

        public static var foregroundSecondary = dynamicColor(light: Color.PaletteV2.dumbo400, dark: Color.PaletteV2.gray700)
        public static var foregroundSecondaryOnDark = dynamicColor(light: Color.PaletteV2.dumbo700, dark: Color.PaletteV2.gray700)
        public static var foregroundSecondaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite75, dark: Color.PaletteV2.opacityWhite75)
        public static var foregroundSecondaryOnLight = dynamicColor(light: Color.PaletteV2.dumbo400, dark: Color.PaletteV2.gray400)

        public static var foregroundTertiary = dynamicColor(light: Color.PaletteV2.dumbo500, dark: Color.PaletteV2.gray600)
        public static var foregroundTertiaryOnDark = dynamicColor(light: Color.PaletteV2.dumbo600, dark: Color.PaletteV2.gray600)
        public static var foregroundTertiaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite50, dark: Color.PaletteV2.opacityWhite50)
        public static var foregroundTertiaryOnLight = dynamicColor(light: Color.PaletteV2.dumbo500, dark: Color.PaletteV2.gray500)

        public static var foregroundInactive = dynamicColor(light: Color.PaletteV2.dumbo600, dark: Color.PaletteV2.gray450)
        public static var foregroundInactiveOnDark = dynamicColor(light: Color.PaletteV2.dumbo450, dark: Color.PaletteV2.gray450)
        public static var foregroundInactiveGlass = dynamicColor(light: Color.PaletteV2.opacityWhite30, dark: Color.PaletteV2.opacityWhite30)
        public static var foregroundInactiveOnLight = dynamicColor(light: Color.PaletteV2.dumbo600, dark: Color.PaletteV2.gray600)

        public static var foregroundOnError = dynamicColor(light: Color.PaletteV2.white, dark: Color.PaletteV2.white)

        // Border Colors
        public static var borderPrimary = dynamicColor(light: Color.PaletteV2.opacityBlack10, dark: Color.PaletteV2.opacityWhite10)
        public static var borderPrimaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite10, dark: Color.PaletteV2.opacityWhite10)

        public static var borderSecondary = dynamicColor(light: Color.PaletteV2.opacityBlack10, dark: Color.PaletteV2.opacityWhite15)
        public static var borderSecondaryGlass = dynamicColor(light: Color.PaletteV2.opacityWhite15, dark: Color.PaletteV2.opacityWhite10)

        // Overlay Colors
        public static var overlayOnPrimary = dynamicColor(light: Color.PaletteV2.opacityBlack4, dark: Color.PaletteV2.opacityWhite4)
        public static var overlayOnLight = dynamicColor(light: Color.PaletteV2.opacityBlack4, dark: Color.PaletteV2.opacityBlack4)
        public static var overlayOnDark = dynamicColor(light: Color.PaletteV2.opacityWhite4, dark: Color.PaletteV2.opacityWhite4)

        // Accent Colors
        public static var accentBrand = dynamicColor(light: Color.PaletteV2.pink600, dark: Color.PaletteV2.pink600)
        public static var accentError = dynamicColor(light: Color.PaletteV2.vermilion500, dark: Color.PaletteV2.vermilion500)
        public static var accentSuccess = dynamicColor(light: Color.PaletteV2.grass400, dark: Color.PaletteV2.grass400)
        public static var accentV4 = dynamicColor(light: Color.PaletteV2.green300, dark: Color.PaletteV2.green300)

        // Omniplayer
        public static var omniplayerWhite = dynamicColor(light: Color.PaletteV2.white, dark: Color.PaletteV2.white)
        public static var omniplayerBlack = dynamicColor(light: Color.PaletteV2.black, dark: Color.PaletteV2.black)

        // Accent Colors
        public static var accentYellow = dynamicColor(light: Color.PaletteV2.dandelion700, dark: Color.PaletteV2.dandelion700)
        public static var accentBlue = dynamicColor(light: Color.PaletteV2.dodgerBlue600, dark: Color.PaletteV2.dodgerBlue600)
        public static var accentOrange = dynamicColor(light: Color.PaletteV2.pumpkin500, dark: Color.PaletteV2.pumpkin500)
        public static var accentPurple = dynamicColor(light: Color.PaletteV2.amethyst100, dark: Color.PaletteV2.amethyst100)
        public static var accentGreen = dynamicColor(light: Color.PaletteV2.slime600, dark: Color.PaletteV2.slime600)
        public static var accentPink = dynamicColor(light: Color.PaletteV2.strawberry600, dark: Color.PaletteV2.strawberry600)
        public static var iconPrimary = dynamicColor(light: Color.PaletteV1.black1, dark: Color.PaletteV1.beige1)
    }

    // MARK: - Suno V2 Color Palette

    enum PaletteV2 {
        // Gray palette
        static let gray50 = Color(.gray50)
        static let gray100 = Color(.gray100)
        static let gray200 = Color(.gray200)
        static let gray300 = Color(.gray300)
        static let gray350 = Color(.gray350)
        static let gray400 = Color(.gray400)
        static let gray450 = Color(.gray450)
        static let gray500 = Color(.gray500)
        static let gray600 = Color(.gray600)
        static let gray700 = Color(.gray700)
        static let gray800 = Color(.gray800)
        static let gray850 = Color(.gray850)
        static let gray900 = Color(.gray900)
        static let gray950 = Color(.gray950)

        // Brown palette
        static let brown100 = Color(.brown100)
        static let brown200 = Color(.brown200)
        static let brown300 = Color(.brown300)
        static let brown400 = Color(.brown400)
        static let brown500 = Color(.brown500)
        static let brown600 = Color(.brown600)
        static let brown700 = Color(.brown700)
        static let brown800 = Color(.brown800)
        static let brown900 = Color(.brown900)

        // Colors
        static let pink500 = Color(.pink500)
        static let pink600 = Color(.pink600)
        static let red500 = Color(.red500)
        static let white = Color(.white)
        static let black = Color(.black)

        // Opacity White variants
        static let opacityWhite0 = Color(.opacityWhite0)
        static let opacityWhite4 = Color(.opacityWhite4)
        static let opacityWhite10 = Color(.opacityWhite10)
        static let opacityWhite15 = Color(.opacityWhite15)
        static let opacityWhite20 = Color(.opacityWhite20)
        static let opacityWhite30 = Color(.opacityWhite30)
        static let opacityWhite50 = Color(.opacityWhite50)
        static let opacityWhite75 = Color(.opacityWhite75)
        static let opacityWhite90 = Color(.opacityWhite90)

        // Opacity Black variants
        static let opacityBlack0 = Color(.opacityBlack0)
        static let opacityBlack4 = Color(.opacityBlack4)
        static let opacityBlack8 = Color(.opacityBlack8)
        static let opacityBlack10 = Color(.opacityBlack10)
        static let opacityBlack15 = Color(.opacityBlack15)
        static let opacityBlack20 = Color(.opacityBlack20)
        static let opacityBlack30 = Color(.opacityBlack30)
        static let opacityBlack40 = Color(.opacityBlack40)
        static let opacityBlack60 = Color(.opacityBlack60)
        static let opacityBlack90 = Color(.opacityBlack90)

        // Other color palettes
        static let green300 = Color(.green300)
        static let green500 = Color(.green500)
        static let blue500 = Color(.blue500)
        static let grape500 = Color(.grape500)
        static let purple500 = Color(.purple500)
        static let salmon500 = Color(.salmon500)

        // Strawberry palette
        static let strawberry100 = Color(.strawberry100)
        static let strawberry200 = Color(.strawberry200)
        static let strawberry300 = Color(.strawberry300)
        static let strawberry400 = Color(.strawberry400)
        static let strawberry500 = Color(.strawberry500)
        static let strawberry600 = Color(.strawberry600)
        static let strawberry700 = Color(.strawberry700)
        static let strawberry800 = Color(.strawberry800)
        static let strawberry900 = Color(.strawberry900)

        // Dodger Blue palette
        static let dodgerBlue100 = Color(.dodgerBlue100)
        static let dodgerBlue200 = Color(.dodgerBlue200)
        static let dodgerBlue300 = Color(.dodgerBlue300)
        static let dodgerBlue400 = Color(.dodgerBlue400)
        static let dodgerBlue500 = Color(.dodgerBlue500)
        static let dodgerBlue600 = Color(.dodgerBlue600)
        static let dodgerBlue700 = Color(.dodgerBlue700)
        static let dodgerBlue800 = Color(.dodgerBlue800)
        static let dodgerBlue900 = Color(.dodgerBlue900)

        // Pumpkin palette
        static let pumpkin100 = Color(.pumpkin100)
        static let pumpkin200 = Color(.pumpkin200)
        static let pumpkin300 = Color(.pumpkin300)
        static let pumpkin400 = Color(.pumpkin400)
        static let pumpkin500 = Color(.pumpkin500)
        static let pumpkin600 = Color(.pumpkin600)
        static let pumpkin700 = Color(.pumpkin700)
        static let pumpkin800 = Color(.pumpkin800)
        static let pumpkin900 = Color(.pumpkin900)

        // Slime palette
        static let slime100 = Color(.slime100)
        static let slime200 = Color(.slime200)
        static let slime300 = Color(.slime300)
        static let slime400 = Color(.slime400)
        static let slime500 = Color(.slime500)
        static let slime600 = Color(.slime600)
        static let slime700 = Color(.slime700)
        static let slime800 = Color(.slime800)
        static let slime900 = Color(.slime900)

        // Dandelion palette
        static let dandelion100 = Color(.dandelion100)
        static let dandelion200 = Color(.dandelion200)
        static let dandelion300 = Color(.dandelion300)
        static let dandelion400 = Color(.dandelion400)
        static let dandelion500 = Color(.dandelion500)
        static let dandelion600 = Color(.dandelion600)
        static let dandelion700 = Color(.dandelion700)
        static let dandelion800 = Color(.dandelion800)
        static let dandelion850 = Color(.dandelion850)
        static let dandelion900 = Color(.dandelion900)
        static let dandelion950 = Color(.dandelion950)

        // Amethyst palette
        static let amethyst100 = Color(.amethyst100)
        static let amethyst200 = Color(.amethyst200)
        static let amethyst300 = Color(.amethyst300)
        static let amethyst400 = Color(.amethyst400)
        static let amethyst500 = Color(.amethyst500)
        static let amethyst600 = Color(.amethyst600)
        static let amethyst700 = Color(.amethyst700)
        static let amethyst800 = Color(.amethyst800)
        static let amethyst900 = Color(.amethyst900)

        // Vermilion palette
        static let vermilion100 = Color(.vermilion100)
        static let vermilion200 = Color(.vermilion200)
        static let vermilion300 = Color(.vermilion300)
        static let vermilion400 = Color(.vermilion400)
        static let vermilion500 = Color(.vermilion500)
        static let vermilion600 = Color(.vermilion600)
        static let vermilion700 = Color(.vermilion700)
        static let vermilion800 = Color(.vermilion800)
        static let vermilion900 = Color(.vermilion900)

        // Grass palette
        static let grass100 = Color(.grass100)
        static let grass200 = Color(.grass200)
        static let grass300 = Color(.grass300)
        static let grass400 = Color(.grass400)
        static let grass500 = Color(.grass500)
        static let grass600 = Color(.grass600)
        static let grass700 = Color(.grass700)
        static let grass800 = Color(.grass800)
        static let grass900 = Color(.grass900)

        // Dumbo palette
        static let dumbo50 = Color(.dumbo50)
        static let dumbo100 = Color(.dumbo100)
        static let dumbo150 = Color(.dumbo150)
        static let dumbo200 = Color(.dumbo200)
        static let dumbo250 = Color(.dumbo250)
        static let dumbo300 = Color(.dumbo300)
        static let dumbo350 = Color(.dumbo350)
        static let dumbo400 = Color(.dumbo400)
        static let dumbo450 = Color(.dumbo450)
        static let dumbo500 = Color(.dumbo500)
        static let dumbo550 = Color(.dumbo550)
        static let dumbo600 = Color(.dumbo600)
        static let dumbo650 = Color(.dumbo650)
        static let dumbo700 = Color(.dumbo700)
        static let dumbo750 = Color(.dumbo750)
        static let dumbo800 = Color(.dumbo800)
        static let dumbo850 = Color(.dumbo850)
        static let dumbo900 = Color(.dumbo900)
        static let dumbo950 = Color(.dumbo950)
    }
}

public extension Color {
    enum Gradient {
        public static func clearToColorLinearGradient(baseColor: Color) -> [Color] {
            return [
                Color.clear,
                baseColor.opacity(0.025),
                baseColor.opacity(0.05),
                baseColor.opacity(0.1),
                baseColor.opacity(0.3),
                baseColor.opacity(0.5),
                baseColor.opacity(0.7),
                baseColor.opacity(0.9),
                baseColor,
            ]
        }
    }
}
