import SwiftUI
import UIKit

// MARK: - Rosetta Color Tokens

enum RosettaColors {

    // MARK: Brand

    static let primaryBlue = Color(hex: 0x248AE6)
    static let primaryBlueDark = Color(hex: 0x238BE6)
    static let primaryBluePressed = Color(hex: 0x2B7CD3)
    static let primaryBlueDisabled = Color(hex: 0x9BCDFF)

    // MARK: Semantic

    static let error = Color(hex: 0xFF3B30)
    static let success = Color(hex: 0x34C759)
    static let warning = Color(hex: 0xFF9500)
    static let accent = Color(hex: 0xE91E63)
    static let online = Color(hex: 0x34C759)

    // MARK: Auth Backgrounds

    static let authBackground = RosettaColors.adaptive(light: Color.white, dark: Color.black)
    static let authSurface = RosettaColors.adaptive(light: Color(hex: 0xF2F2F7), dark: Color(hex: 0x2A2A2A))

    // MARK: Shared Neutral

    static let secondaryText = Color(hex: 0x8E8E93)
    static let tertiaryText = Color(hex: 0x666666)
    static let numberGray = Color(hex: 0x888888)
    static let hintText = Color(hex: 0x555555)
    static let subtleBorder = RosettaColors.adaptive(
        light: Color.black.opacity(0.12),
        dark: Color.white.opacity(0.15)
    )
    static let cardFill = RosettaColors.adaptive(
        light: Color.black.opacity(0.04),
        dark: Color.white.opacity(0.06)
    )

    // MARK: Chat-Specific (from Figma)

    /// Figma subtitle/time/icon color in light mode: #3C3C43 at ~60% opacity
    static let chatSubtitle = Color(hex: 0x3C3C43).opacity(0.6)
    /// Figma accent blue used for badges, delivery status: #008BFF
    static let figmaBlue = Color(hex: 0x008BFF)

    // MARK: Light Theme

    enum Light {
        static let background = Color.white
        static let backgroundSecondary = Color(hex: 0xF2F2F7) // iOS system grouped bg
        static let surface = Color(hex: 0xF5F5F5)
        static let text = Color.black
        static let textSecondary = Color(hex: 0x8E8E93) // Telegram: dateTextColor/messageTextColor
        static let textTertiary = Color(hex: 0x3C3C43).opacity(0.3) // Figma hint gray
        static let border = Color(hex: 0xE0E0E0)
        static let divider = Color(hex: 0xC8C7CC) // Telegram: itemSeparatorColor
        static let messageBubble = Color(hex: 0xF5F5F5)
        static let messageBubbleOwn = Color(hex: 0xDCF8C6)
        static let inputBackground = Color(hex: 0xF2F3F5)
    }

    // MARK: Dark Theme

    enum Dark {
        static let background = Color.black
        static let backgroundSecondary = Color(hex: 0x2A2A2A)
        /// Pinned chat section background (extends from toolbar to last pinned row)
        static let pinnedSectionBackground = Color(hex: 0x1C1C1D)
        static let surface = Color(hex: 0x242424)
        static let text = Color.white
        static let textSecondary = Color(hex: 0x8D8E93) // Telegram: dateTextColor/messageTextColor
        static let textTertiary = Color(hex: 0x666666)
        static let border = Color(hex: 0x2E2E2E)
        static let divider = Color(UIColor(red: 0x54/255, green: 0x54/255, blue: 0x58/255, alpha: 0.55)) // Telegram: 0x545458 @ 55%
        static let messageBubble = Color(hex: 0x2A2A2A)
        static let messageBubbleOwn = Color(hex: 0x263341)
        static let inputBackground = Color(hex: 0x2A2A2A)
    }

    // MARK: Adaptive Colors (light/dark based on system appearance)

    static func adaptive(light: Color, dark: Color) -> Color {
        Color(UIColor { traits in
            traits.userInterfaceStyle == .dark
                ? UIColor(dark)
                : UIColor(light)
        })
    }

    enum Adaptive {
        static let background = RosettaColors.adaptive(light: RosettaColors.Light.background, dark: RosettaColors.Dark.background)
        static let backgroundSecondary = RosettaColors.adaptive(light: RosettaColors.Light.backgroundSecondary, dark: RosettaColors.Dark.backgroundSecondary)
        static let surface = RosettaColors.adaptive(light: RosettaColors.Light.surface, dark: RosettaColors.Dark.surface)
        static let text = RosettaColors.adaptive(light: RosettaColors.Light.text, dark: RosettaColors.Dark.text)
        static let textSecondary = RosettaColors.adaptive(light: RosettaColors.Light.textSecondary, dark: RosettaColors.Dark.textSecondary)
        static let textTertiary = RosettaColors.adaptive(light: RosettaColors.Light.textTertiary, dark: RosettaColors.Dark.textTertiary)
        static let border = RosettaColors.adaptive(light: RosettaColors.Light.border, dark: RosettaColors.Dark.border)
        static let divider = RosettaColors.adaptive(light: RosettaColors.Light.divider, dark: RosettaColors.Dark.divider)
        static let messageBubble = RosettaColors.adaptive(light: RosettaColors.Light.messageBubble, dark: RosettaColors.Dark.messageBubble)
        static let messageBubbleOwn = RosettaColors.adaptive(light: RosettaColors.Light.messageBubbleOwn, dark: RosettaColors.Dark.messageBubbleOwn)
        static let inputBackground = RosettaColors.adaptive(light: RosettaColors.Light.inputBackground, dark: RosettaColors.Dark.inputBackground)
        static let pinnedSectionBackground = RosettaColors.adaptive(
            light: Color(hex: 0xF7F7F7), // Telegram: pinnedItemBackgroundColor
            dark: RosettaColors.Dark.pinnedSectionBackground
        )
        /// Muted badge background (Telegram: unreadBadgeInactiveBackgroundColor)
        static let badgeInactive = RosettaColors.adaptive(
            light: Color(hex: 0xB6B6BB),
            dark: Color(hex: 0x666666)
        )
        static let searchBarFill = RosettaColors.adaptive(
            light: Color.black.opacity(0.08),
            dark: Color.white.opacity(0.08)
        )
        static let searchBarBorder = RosettaColors.adaptive(
            light: Color.black.opacity(0.06),
            dark: Color.white.opacity(0.06)
        )
    }

    // MARK: Seed Word Colors (12 unique, matching Android)

    static let seedWordColors: [Color] = [
        Color(hex: 0x5E9FFF),
        Color(hex: 0xFF7EB3),
        Color(hex: 0x7B68EE),
        Color(hex: 0x50C878),
        Color(hex: 0xFF6B6B),
        Color(hex: 0x4ECDC4),
        Color(hex: 0xFFB347),
        Color(hex: 0xBA55D3),
        Color(hex: 0x87CEEB),
        Color(hex: 0xDDA0DD),
        Color(hex: 0x98D8C8),
        Color(hex: 0xF7DC6F),
    ]

    // MARK: Avatar Palette (Mantine v8 default, 11 colors)
    // tint = shade-6 (used at 15% opacity for dark bg, 10% for light bg)
    // text = shade-3 (dark mode text), shade-6 reused for light mode text

    static let avatarColors: [(tint: Color, text: Color)] = [
        (Color(hex: 0x228be6), Color(hex: 0x74c0fc)), // blue
        (Color(hex: 0x15aabf), Color(hex: 0x66d9e8)), // cyan
        (Color(hex: 0xbe4bdb), Color(hex: 0xe599f7)), // grape
        (Color(hex: 0x40c057), Color(hex: 0x8ce99a)), // green
        (Color(hex: 0x4c6ef5), Color(hex: 0x91a7ff)), // indigo
        (Color(hex: 0x82c91e), Color(hex: 0xc0eb75)), // lime
        (Color(hex: 0xfd7e14), Color(hex: 0xffc078)), // orange
        (Color(hex: 0xe64980), Color(hex: 0xfaa2c1)), // pink
        (Color(hex: 0xfa5252), Color(hex: 0xffa8a8)), // red
        (Color(hex: 0x12b886), Color(hex: 0x63e6be)), // teal
        (Color(hex: 0x7950f2), Color(hex: 0xb197fc)), // violet
    ]

    /// Desktop parity: color is determined by the display name, NOT the public key.
    /// Server sends first 7 chars of publicKey as the default title; use that as fallback.
    static func avatarColorIndex(for name: String, publicKey: String = "") -> Int {
        let trimmed = name.trimmingCharacters(in: .whitespaces)
        let input = trimmed.isEmpty ? String(publicKey.prefix(7)) : trimmed
        var hash: Int32 = 0
        for char in input.unicodeScalars {
            // Desktop: hash = (hash << 5) - hash + char  ≡  hash * 31 + char
            hash = (hash &<< 5) &- hash &+ Int32(truncatingIfNeeded: char.value)
            // Desktop: hash |= 0  → force 32-bit signed (Int32 handles this natively)
        }
        let count = Int32(avatarColors.count)
        var index = abs(hash) % count
        if index < 0 { index += count } // guard for Int32.min edge case
        return Int(index)
    }

    /// Returns UIColor for a given avatar color index (for UIKit contexts).
    static func avatarColor(for index: Int) -> UIColor {
        let safeIndex = index % avatarColors.count
        return UIColor(avatarColors[safeIndex].tint)
    }

    /// Returns UIColor text variant for sender name labels in group chats (UIKit).
    static func avatarTextColor(for index: Int) -> UIColor {
        let safeIndex = index % avatarColors.count
        return UIColor(avatarColors[safeIndex].text)
    }

    // MARK: - Telegram PeerNameColors (group sender names)

    /// 7 Telegram-parity sender name colors for group chats.
    /// Light theme: original Telegram day colors. Dark theme: saturation ×0.7, brightness ×1.2.
    private static let peerNameColorsBase: [UIColor] = [
        UIColor(red: 0xcc/255, green: 0x50/255, blue: 0x49/255, alpha: 1), // red
        UIColor(red: 0xd6/255, green: 0x77/255, blue: 0x22/255, alpha: 1), // orange
        UIColor(red: 0x95/255, green: 0x5c/255, blue: 0xdb/255, alpha: 1), // purple
        UIColor(red: 0x40/255, green: 0xa9/255, blue: 0x20/255, alpha: 1), // green
        UIColor(red: 0x30/255, green: 0x9e/255, blue: 0xba/255, alpha: 1), // teal
        UIColor(red: 0x36/255, green: 0x8a/255, blue: 0xd1/255, alpha: 1), // blue
        UIColor(red: 0xc7/255, green: 0x50/255, blue: 0x8b/255, alpha: 1), // pink
    ]

    static let peerNameColors: [UIColor] = peerNameColorsBase.map { base in
        UIColor { traits in
            if traits.userInterfaceStyle == .dark {
                return adjustForDarkTheme(base)
            }
            return base
        }
    }

    /// Telegram dark theme brightness adjustment.
    private static func adjustForDarkTheme(_ color: UIColor) -> UIColor {
        var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getHue(&h, saturation: &s, brightness: &b, alpha: &a)
        return UIColor(hue: h, saturation: s * 0.7, brightness: min(1.0, b * 1.2), alpha: a)
    }

    /// Returns a Telegram PeerNameColor for a sender based on their public key.
    static func peerNameColor(forKey publicKey: String) -> UIColor {
        let index = avatarColorIndex(for: publicKey, publicKey: publicKey)
        return peerNameColors[index % peerNameColors.count]
    }

    static func avatarText(publicKey: String) -> String {
        String(publicKey.prefix(2)).uppercased()
    }

    /// Single-letter initial for group avatars (first letter of name, or first char of publicKey).
    static func groupInitial(name: String, publicKey: String) -> String {
        let trimmed = name.trimmingCharacters(in: .whitespaces)
        if let first = trimmed.first { return String(first).uppercased() }
        if !publicKey.isEmpty { return String(publicKey.prefix(1)).uppercased() }
        return "?"
    }

    static func initials(name: String, publicKey: String) -> String {
        let words = name.trimmingCharacters(in: .whitespaces)
            .split(whereSeparator: { $0.isWhitespace })
            .filter { !$0.isEmpty }
        switch words.count {
        case 0:
            return publicKey.isEmpty ? "??" : String(publicKey.prefix(2)).uppercased()
        case 1:
            return String(words[0].prefix(2)).uppercased()
        default:
            let first = words[0].first.map(String.init) ?? ""
            let second = words[1].first.map(String.init) ?? ""
            return (first + second).uppercased()
        }
    }

    // MARK: - Voice Message Bubble Colors (Telegram exact, UIKit)
    // Source: DefaultDarkPresentationTheme.swift + DefaultDayPresentationTheme.swift

    enum Voice {
        /// Returns the full color set for a voice message bubble.
        static func colors(isOutgoing: Bool, isDark: Bool) -> VoiceColors {
            if isDark {
                return isOutgoing ? darkOutgoing : darkIncoming
            } else {
                return isOutgoing ? lightOutgoing : lightIncoming
            }
        }

        private static let darkIncoming = VoiceColors(
            playButtonBg: UIColor(white: 1, alpha: 1),                // #FFFFFF
            playButtonFg: UIColor(red: 0x26/255, green: 0x26/255, blue: 0x28/255, alpha: 1), // #262628
            waveformPlayed: UIColor(white: 1, alpha: 1),              // #FFFFFF
            waveformUnplayed: UIColor(white: 1, alpha: 0.4),          // #FFF 40%
            durationText: UIColor(white: 1, alpha: 0.5)               // #FFF 50%
        )
        private static let darkOutgoing = VoiceColors(
            playButtonBg: UIColor(white: 1, alpha: 1),                // #FFFFFF
            // Telegram uses .clear foreground (bubble color shows through cutout).
            // With Lottie we tint explicitly to bubble blue (#3390EC).
            playButtonFg: UIColor(red: 0x33/255, green: 0x90/255, blue: 0xEC/255, alpha: 1), // #3390EC
            waveformPlayed: UIColor(white: 1, alpha: 1),              // #FFFFFF
            waveformUnplayed: UIColor(white: 1, alpha: 0.5),          // #FFF 50%
            durationText: UIColor(white: 1, alpha: 0.5)               // #FFF 50%
        )
        private static let lightIncoming = VoiceColors(
            playButtonBg: UIColor(red: 0, green: 0x88/255, blue: 1, alpha: 1),     // #0088FF
            playButtonFg: UIColor.white,
            waveformPlayed: UIColor(red: 0, green: 0x88/255, blue: 1, alpha: 1),   // #0088FF
            waveformUnplayed: UIColor(red: 0xCA/255, green: 0xCA/255, blue: 0xCA/255, alpha: 1), // #CACACA
            durationText: UIColor(red: 0x52/255, green: 0x52/255, blue: 0x52/255, alpha: 0.6)    // #525252 60%
        )
        // Rosetta: outgoing bubble is always blue (#3390EC), so white elements (same as darkOutgoing)
        private static let lightOutgoing = VoiceColors(
            playButtonBg: UIColor(white: 1, alpha: 1),
            playButtonFg: UIColor(red: 0x33/255, green: 0x90/255, blue: 0xEC/255, alpha: 1), // #3390EC
            waveformPlayed: UIColor(white: 1, alpha: 1),
            waveformUnplayed: UIColor(white: 1, alpha: 0.5),
            durationText: UIColor(white: 1, alpha: 0.5)
        )
    }
}

struct VoiceColors {
    let playButtonBg: UIColor
    let playButtonFg: UIColor
    let waveformPlayed: UIColor
    let waveformUnplayed: UIColor
    let durationText: UIColor
}

// MARK: - Color Hex Initializer

extension Color {
    init(hex: UInt, alpha: Double = 1.0) {
        self.init(
            .sRGB,
            red: Double((hex >> 16) & 0xFF) / 255.0,
            green: Double((hex >> 8) & 0xFF) / 255.0,
            blue: Double(hex & 0xFF) / 255.0,
            opacity: alpha
        )
    }
}
