import Foundation
import SwiftUI

public extension Color {
    internal static func dynamicColor(light: Color, dark: Color) -> Color {
        return Color(
            UIColor { traitCollection in
                traitCollection.userInterfaceStyle == .dark ? UIColor(dark) : UIColor(light)
            }
        )
    }

    init(light: UIColor, dark: UIColor) {
        self.init(
            UIColor { traitCollection in
                traitCollection.userInterfaceStyle == .dark ? dark : light
            }
        )
    }

    enum SemanticV1 {
        public static var backgroundPrimary = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.black1)
        public static var backgroundSecondary = dynamicColor(light: Color.PaletteV1.beige2, dark: Color.PaletteV1.grey3)
        public static var backgroundTertiary = dynamicColor(light: Color.PaletteV1.beige3, dark: Color.PaletteV1.grey4)
        public static var backgroundQuaternary = dynamicColor(light: Color.PaletteV1.beige4, dark: Color.PaletteV1.grey4)
        public static var backgroundBrand = dynamicColor(light: Color.PaletteV1.brown1, dark: Color.PaletteV1.beige1)
        public static var backgroundBrown = dynamicColor(light: Color.PaletteV1.brown1, dark: Color.PaletteV1.brown1)
        public static var backgroundInvert = dynamicColor(light: Color.PaletteV1.black1, dark: Color.PaletteV1.beige1)
        public static var backgroundBlockOverlay = Color.PaletteV1.black1

        public static var fieldBackground = dynamicColor(light: Color.PaletteV1.white5, dark: Color.PaletteV1.grey5)

        public static var textPrimary = dynamicColor(light: Color.PaletteV1.black1, dark: Color.PaletteV1.beige1)
        public static var textSecondary = dynamicColor(light: Color.PaletteV1.grey1, dark: Color.PaletteV1.beige5)
        public static var textTertiary = dynamicColor(light: Color.PaletteV1.grey2, dark: Color.PaletteV1.beige6)
        public static var textInvert = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.black1)
        public static var textBrand = dynamicColor(light: Color.PaletteV1.brown2, dark: Color.PaletteV1.beige1)
        public static var textOnBrand = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.black1)
        public static var textOnLight = dynamicColor(light: Color.PaletteV1.brown2, dark: Color.PaletteV1.brown2)
        public static var textOnDark = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.beige1)
        public static var textLink = dynamicColor(light: Color.PaletteV1.pink1, dark: Color.PaletteV1.pink1)
        public static var textWarning = dynamicColor(light: Color.PaletteV1.red1, dark: Color.PaletteV1.red1)

        public static var iconPrimary = dynamicColor(light: Color.PaletteV1.black1, dark: Color.PaletteV1.beige1)
        public static var iconSecondary = dynamicColor(light: Color.PaletteV1.grey1, dark: Color.PaletteV1.beige5)
        public static var iconTertiary = dynamicColor(light: Color.PaletteV1.grey2, dark: Color.PaletteV1.beige6)
        public static var iconInvert = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.black1)
        public static var iconBrand = dynamicColor(light: Color.PaletteV1.brown2, dark: Color.PaletteV1.beige1)
        public static var iconOnBrand = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.black1)
        public static var iconOnDark = dynamicColor(light: Color.PaletteV1.beige1, dark: Color.PaletteV1.beige1)
        public static var iconLink = dynamicColor(light: Color.PaletteV1.pink1, dark: Color.PaletteV1.pink1)
        public static var iconWarning = dynamicColor(light: Color.PaletteV1.red1, dark: Color.PaletteV1.red1)

        public static var borderPrimary = dynamicColor(light: Color.PaletteV1.black15, dark: Color.PaletteV1.white30)
        public static var borderSecondary = dynamicColor(light: Color.PaletteV1.black8, dark: Color.PaletteV1.white15)

        public static var alwaysBlack1 = Color.PaletteV1.black1
        public static let alwaysLighterBeige = Color.PaletteV1.beige1
        public static let alwaysDarkerBeige = Color.PaletteV1.beige6
        public static let alwaysGrey4 = Color.PaletteV1.grey4

        public static let auraPink = Color.PaletteV1.auraPink
        public static var likePink = Color.PaletteV1.pink2
        public static let v4Blue = Color.PaletteV1.v4Blue
        public static var v4Accent = Color.PaletteV1.v4Accent
        public static var discountAccent = Color.PaletteV1.discountHighlight
        public static var shimmerShade = Color.PaletteV1.shimmerShade
        public static let tabBarHairline = dynamicColor(light: Color.PaletteV1.beige6, dark: Color.PaletteV1.grey4)

        public static var foregroundInactive = dynamicColor(light: Color.PaletteV1.dumbo600, dark: Color.PaletteV1.gray450)
    }

    internal enum PaletteV1 {
        static let beige1 = Color(.beige1)
        static let beige2 = Color(.beige2)
        static let beige3 = Color(.beige3)
        static let beige4 = Color(.beige4)
        static let beige5 = Color(.beige5)
        static let beige6 = Color(.beige6)
        static let brown1 = Color(.brown1)
        static let brown2 = Color(.brown2)

        static let black1 = Color(.black1)
        static let grey1 = Color(.grey1)
        static let grey2 = Color(.grey2)
        static let grey3 = Color(.grey3)
        static let grey4 = Color(.grey4)
        static let grey5 = Color(.grey5)
        static let black8 = Color(.black8)
        static let black15 = Color(.black15)

        static let white5 = Color(.white5)
        static let white15 = Color(.white15)
        static let white30 = Color(.white30)

        static let pink1 = Color(.pink1)
        static let pink2 = Color(.pink2)

        static let auraPink = Color(.auraPink)
        static let red1 = Color(.red1)
        static let v4Blue = Color(.v4Blue)
        static let v4Accent = Color(.v4Accent)
        static let discountHighlight = Color(.discountHighlight)
        static let shimmerShade = dynamicColor(light: Color.PaletteV1.beige2, dark: Color.PaletteV1.grey1)

        enum BadgeBackground {
            static let gradientTop = Color(.gradientTop)
            static let gradientCenter = Color(.gradientCenter)
            static let gradientBottom = Color(.gradientBottom)
        }

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

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

    enum Utility {
        public static func dynamicBlackOrWhite(opacity: CGFloat = 1.0) -> Color {
            return dynamicColor(
                light: Color.black.opacity(opacity),
                dark: Color.white.opacity(opacity)
            )
        }
    }
}

public extension Color {
    static func random() -> Color {
        Color(
            red: .random(in: 0 ... 1),
            green: .random(in: 0 ... 1),
            blue: .random(in: 0 ... 1)
        )
    }
}

extension UIColor {
    static func dynamicColor(light: UIColor, dark: UIColor) -> UIColor {
        return UIColor { traitCollection in
            traitCollection.userInterfaceStyle == .dark ? dark : light
        }
    }

    public enum SemanticV1 {
        public static var textPrimary = dynamicColor(light: UIColor.PaletteV1.black1, dark: UIColor.PaletteV1.beige1)
        public static var textSecondary = dynamicColor(light: UIColor.PaletteV1.grey1, dark: UIColor.PaletteV1.beige5)
        public static var iconSecondary = dynamicColor(light: UIColor.PaletteV1.grey1, dark: UIColor.PaletteV1.beige5)
        public static var backgroundPrimary = dynamicColor(light: UIColor.PaletteV1.beige1, dark: UIColor.PaletteV1.black1)
        public static var backgroundQuaternary = dynamicColor(light: UIColor.PaletteV1.beige4, dark: UIColor.PaletteV1.grey4)
        public static var textLink = dynamicColor(light: UIColor.PaletteV1.pink1, dark: UIColor.PaletteV1.pink1)
        public static var textInvert = dynamicColor(light: UIColor.PaletteV1.beige1, dark: UIColor.PaletteV1.black1)

        public static let auraPink = PaletteV1.auraPink
        public static let v4Blue = PaletteV1.v4Blue

        public static let alwaysLighterBeige = UIColor.PaletteV1.beige1
        public static let alwaysDarkerBeige = UIColor.PaletteV1.beige6
        public static let alwaysBlack1 = UIColor.PaletteV1.black1
    }

    enum PaletteV1 {
        static let black1 = UIColor(resource: .black1)
        static let beige1 = UIColor(resource: .beige1)
        static let beige4 = UIColor(resource: .beige4)
        static let beige5 = UIColor(resource: .beige5)
        static let beige6 = UIColor(resource: .beige6)
        static let grey1 = UIColor(resource: .grey1)
        static let grey4 = UIColor(resource: .grey4)
        static let pink1 = UIColor(resource: .pink1)

        static let auraPink = UIColor(resource: .auraPink)
        static let v4Blue = UIColor(resource: .v4Blue)
    }
}
