// TerminalTheme.swift
// Defines color themes for the terminal view.
//
// SwiftTerm API notes (discovered during T-2.3):
//   • SwiftTerm.Color uses UInt16 components (0...65535).
//     Conversion from 8-bit: multiply by 257 (= 0x101), which maps 0→0 and 255→65535.
//   • installColors([SwiftTerm.Color]) installs the 16-color ANSI palette.
//   • nativeForegroundColor / nativeBackgroundColor accept UIColor.

import Foundation
import SwiftTerm

// MARK: - ThemeColor

/// A simple 8-bit RGB color that is Codable and Sendable.
public struct ThemeColor: Codable, Sendable, Equatable {
    public let r: UInt8
    public let g: UInt8
    public let b: UInt8

    public init(r: UInt8, g: UInt8, b: UInt8) {
        self.r = r; self.g = g; self.b = b
    }
}

// MARK: - TerminalTheme

/// A complete color theme for the terminal view.
///
/// `ansiColors` must contain exactly 16 entries (indices 0–15) representing
/// the standard ANSI palette: 0–7 normal, 8–15 bright.
public struct TerminalTheme: Codable, Identifiable, Sendable, Equatable {
    public let id: String
    public let name: String
    public let foreground: ThemeColor
    public let background: ThemeColor
    public let cursor: ThemeColor
    /// 16 ANSI colors: indices 0–7 are the standard colors, 8–15 are the bright variants.
    public let ansiColors: [ThemeColor]

    public init(
        id: String,
        name: String,
        foreground: ThemeColor,
        background: ThemeColor,
        cursor: ThemeColor,
        ansiColors: [ThemeColor]
    ) {
        precondition(ansiColors.count == 16, "ansiColors must contain exactly 16 entries")
        self.id = id
        self.name = name
        self.foreground = foreground
        self.background = background
        self.cursor = cursor
        self.ansiColors = ansiColors
    }

    // MARK: SwiftTerm conversion

    /// Converts a `ThemeColor` to a `SwiftTerm.Color`.
    ///
    /// SwiftTerm.Color uses UInt16 components (0–65535). Multiplying each 8-bit
    /// component by 257 (0x101) gives an exact linear mapping: 0→0, 255→65535.
    public func toSwiftTermColor(_ c: ThemeColor) -> SwiftTerm.Color {
        SwiftTerm.Color(
            red:   UInt16(c.r) * 257,
            green: UInt16(c.g) * 257,
            blue:  UInt16(c.b) * 257
        )
    }

    /// Returns all 16 ANSI entries as `SwiftTerm.Color` values.
    public var swiftTermAnsiColors: [SwiftTerm.Color] {
        ansiColors.map { toSwiftTermColor($0) }
    }
}

// MARK: - Built-in themes

public extension TerminalTheme {

    // MARK: dark — hacker/Matrix style: black bg, green fg

    static let dark = TerminalTheme(
        id: "dark",
        name: "Dark (Hacker)",
        foreground: ThemeColor(r: 0x33, g: 0xFF, b: 0x33),   // bright green
        background: ThemeColor(r: 0x00, g: 0x00, b: 0x00),   // pure black
        cursor:     ThemeColor(r: 0x33, g: 0xFF, b: 0x33),
        ansiColors: [
            // 0 – black (normal)
            ThemeColor(r: 0x00, g: 0x00, b: 0x00),
            // 1 – red
            ThemeColor(r: 0xCC, g: 0x00, b: 0x00),
            // 2 – green
            ThemeColor(r: 0x00, g: 0xCC, b: 0x00),
            // 3 – yellow
            ThemeColor(r: 0xCC, g: 0xCC, b: 0x00),
            // 4 – blue
            ThemeColor(r: 0x00, g: 0x00, b: 0xCC),
            // 5 – magenta
            ThemeColor(r: 0xCC, g: 0x00, b: 0xCC),
            // 6 – cyan
            ThemeColor(r: 0x00, g: 0xCC, b: 0xCC),
            // 7 – white (normal)
            ThemeColor(r: 0xCC, g: 0xCC, b: 0xCC),
            // 8 – bright black (dark gray)
            ThemeColor(r: 0x33, g: 0x33, b: 0x33),
            // 9 – bright red
            ThemeColor(r: 0xFF, g: 0x33, b: 0x33),
            // 10 – bright green
            ThemeColor(r: 0x33, g: 0xFF, b: 0x33),
            // 11 – bright yellow
            ThemeColor(r: 0xFF, g: 0xFF, b: 0x33),
            // 12 – bright blue
            ThemeColor(r: 0x33, g: 0x33, b: 0xFF),
            // 13 – bright magenta
            ThemeColor(r: 0xFF, g: 0x33, b: 0xFF),
            // 14 – bright cyan
            ThemeColor(r: 0x33, g: 0xFF, b: 0xFF),
            // 15 – bright white
            ThemeColor(r: 0xFF, g: 0xFF, b: 0xFF),
        ]
    )

    // MARK: github — GitHub Dark theme

    static let github = TerminalTheme(
        id: "github",
        name: "GitHub Dark",
        foreground: ThemeColor(r: 0xE6, g: 0xED, b: 0xF3),   // #e6edf3
        background: ThemeColor(r: 0x0D, g: 0x11, b: 0x17),   // #0d1117
        cursor:     ThemeColor(r: 0xE6, g: 0xED, b: 0xF3),
        ansiColors: [
            // 0 – black
            ThemeColor(r: 0x48, g: 0x4F, b: 0x58),
            // 1 – red
            ThemeColor(r: 0xFF, g: 0x77, b: 0x77),
            // 2 – green
            ThemeColor(r: 0x56, g: 0xD3, b: 0x64),
            // 3 – yellow
            ThemeColor(r: 0xE3, g: 0xB3, b: 0x41),
            // 4 – blue
            ThemeColor(r: 0x6C, g: 0xA4, b: 0xF8),
            // 5 – magenta
            ThemeColor(r: 0xBC, g: 0x8C, b: 0xFF),
            // 6 – cyan
            ThemeColor(r: 0x2B, g: 0x73, b: 0x89),   // #2b7389
            // 7 – white
            ThemeColor(r: 0xE6, g: 0xED, b: 0xF3),
            // 8 – bright black
            ThemeColor(r: 0x6E, g: 0x76, b: 0x81),
            // 9 – bright red
            ThemeColor(r: 0xFF, g: 0xA1, b: 0x98),
            // 10 – bright green
            ThemeColor(r: 0x3F, g: 0xB9, b: 0x50),
            // 11 – bright yellow
            ThemeColor(r: 0xD2, g: 0x9C, b: 0x22),
            // 12 – bright blue
            ThemeColor(r: 0x79, g: 0xC0, b: 0xFF),
            // 13 – bright magenta
            ThemeColor(r: 0xD2, g: 0xA8, b: 0xFF),
            // 14 – bright cyan
            ThemeColor(r: 0x39, g: 0xC5, b: 0xCF),
            // 15 – bright white
            ThemeColor(r: 0xFF, g: 0xFF, b: 0xFF),
        ]
    )
}
