import SwiftUI

/// The colour and icon vocabulary `icon`, `iconColor`, and `background` are written in.
///
/// **Mirrors `Kanban/UI/Palette.swift` and `SymbolPickerCatalog`, not shared with them.**
/// `project.yml` excludes `Kanban/UI` from the phone target outright — it is AppKit-only — so this
/// is an independent copy of the same name→hex tables and the same curated symbol grid, kept as
/// pure data (no `NSColor`, no `AppKit`). The two pickers are free to diverge; nothing here reads
/// the Mac's file or vice versa.
enum CardPalette {

    struct Swatch: Identifiable, Sendable {
        /// Kebab-case, exactly as written to frontmatter (`iconColor`/`background`'s `color`
        /// subkey read this way — see `FrontmatterFields.swift`).
        let name: String
        let hex: String
        var id: String { name }
    }

    /// `iconColor`'s twelve wells.
    static let foregrounds: [Swatch] = [
        Swatch(name: "obsidian", hex: "#000000"),
        Swatch(name: "aluminum", hex: "#9B9B9B"),
        Swatch(name: "soapstone", hex: "#D5D5D5"),
        Swatch(name: "chalk", hex: "#FFFFFF"),
        Swatch(name: "carnation", hex: "#FF576C"),
        Swatch(name: "rich-grapefruit", hex: "#FF864C"),
        Swatch(name: "smokey-tangerine", hex: "#E5A334"),
        Swatch(name: "fern", hex: "#50B23D"),
        Swatch(name: "light-teal", hex: "#00B7B7"),
        Swatch(name: "deep-sky-blue", hex: "#0084E5"),
        Swatch(name: "pale-violet", hex: "#8C59C5"),
        Swatch(name: "deep-cool-granite", hex: "#597199"),
    ]

    /// `background`'s twelve wells — written into the mapping's `color` subkey
    /// (`FrontmatterDocument.setStyleValue`).
    static let backgrounds: [Swatch] = [
        Swatch(name: "obsidian", hex: "#000000"),
        Swatch(name: "shale", hex: "#5B5B5B"),
        Swatch(name: "aluminum", hex: "#9B9B9B"),
        Swatch(name: "chalk", hex: "#FFFFFF"),
        Swatch(name: "light-cayenne", hex: "#B6071E"),
        Swatch(name: "light-mocha", hex: "#B73C14"),
        Swatch(name: "smokey-mocha", hex: "#674611"),
        Swatch(name: "smokey-fern", hex: "#145312"),
        Swatch(name: "dark-teal", hex: "#005152"),
        Swatch(name: "smokey-ocean", hex: "#003168"),
        Swatch(name: "smokey-rich-eggplant", hex: "#290659"),
        Swatch(name: "intense-cool-shale", hex: "#1F2E45"),
    ]

    /// A general "boards and projects" grid — `SymbolPickerCatalog.defaultSet`, mirrored for the
    /// same reason as the colour tables above.
    static let icons: [String] = [
        "star", "flag", "heart", "bolt", "flame", "leaf", "drop", "sun.max", "moon", "sparkles",
        "tag", "bookmark", "pin", "bell", "paperplane", "tray", "folder", "archivebox", "doc.text",
        "list.bullet", "checklist", "calendar", "clock", "hammer", "wrench.and.screwdriver",
        "paintbrush", "lightbulb", "brain", "book", "graduationcap", "briefcase", "cart", "house",
        "airplane", "gamecontroller", "globe",
    ]

    /// Resolves a stored palette name to a colour, for rendering a well or a row accent.
    ///
    /// **Lenient, like the field itself** (`Kanban/UI/Palette.swift`'s own framing): an
    /// unrecognized name — a custom hex the field allows but this picker does not offer, a typo, a
    /// name from some future palette — answers `nil`, and every caller here falls back to its own
    /// default rather than guessing at a colour. Nothing on disk is affected either way.
    static func color(named name: String, in swatches: [Swatch]) -> Color? {
        guard let swatch = swatches.first(where: { $0.name == name }) else { return nil }
        return Color(paletteHex: swatch.hex)
    }
}

private extension Color {
    /// `#RRGGBB` or `#RRGGBBAA` — the two forms `CardPalette.Swatch.hex` uses. Malformed input
    /// answers `nil` rather than a guessed colour, matching `CardPalette.color(named:in:)`'s own
    /// contract.
    init?(paletteHex hex: String) {
        var value = hex
        if value.hasPrefix("#") { value.removeFirst() }
        guard value.count == 6 || value.count == 8, let intValue = UInt64(value, radix: 16) else { return nil }

        let r, g, b, a: Double
        if value.count == 8 {
            r = Double((intValue >> 24) & 0xFF) / 255
            g = Double((intValue >> 16) & 0xFF) / 255
            b = Double((intValue >> 8) & 0xFF) / 255
            a = Double(intValue & 0xFF) / 255
        } else {
            r = Double((intValue >> 16) & 0xFF) / 255
            g = Double((intValue >> 8) & 0xFF) / 255
            b = Double(intValue & 0xFF) / 255
            a = 1
        }
        self.init(red: r, green: g, blue: b, opacity: a)
    }
}
