use std::collections::HashMap;

use ratatui::style::Color;
use ratatui::widgets::BorderType;

use crate::diff::TokenKind;
use crate::state::ThemeName;

/// Parse a user-supplied color string.
/// Supports `#RRGGBB`, `#RGB`, `rgb(r,g,b)`, and named colors (red, green, ...).
pub fn parse_color_spec(s: &str) -> Option<Color> {
    let s = s.trim();
    if let Some(hex) = s.strip_prefix('#') {
        return match hex.len() {
            6 => {
                let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
                let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
                let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
                Some(Color::Rgb(r, g, b))
            }
            3 => {
                let r = u8::from_str_radix(&hex[0..1], 16).ok()? * 17;
                let g = u8::from_str_radix(&hex[1..2], 16).ok()? * 17;
                let b = u8::from_str_radix(&hex[2..3], 16).ok()? * 17;
                Some(Color::Rgb(r, g, b))
            }
            _ => None,
        };
    }
    let lower = s.to_ascii_lowercase();
    if let Some(rest) = lower.strip_prefix("rgb(").and_then(|r| r.strip_suffix(')')) {
        let parts: Vec<&str> = rest.split(',').map(|p| p.trim()).collect();
        if parts.len() == 3 {
            let r = parts[0].parse::<u8>().ok()?;
            let g = parts[1].parse::<u8>().ok()?;
            let b = parts[2].parse::<u8>().ok()?;
            return Some(Color::Rgb(r, g, b));
        }
        return None;
    }
    match lower.as_str() {
        "black" => Some(Color::Black),
        "red" => Some(Color::Red),
        "green" => Some(Color::Green),
        "yellow" => Some(Color::Yellow),
        "blue" => Some(Color::Blue),
        "magenta" => Some(Color::Magenta),
        "cyan" => Some(Color::Cyan),
        "gray" | "grey" => Some(Color::Gray),
        "darkgray" | "darkgrey" => Some(Color::DarkGray),
        "lightred" => Some(Color::LightRed),
        "lightgreen" => Some(Color::LightGreen),
        "lightyellow" => Some(Color::LightYellow),
        "lightblue" => Some(Color::LightBlue),
        "lightmagenta" => Some(Color::LightMagenta),
        "lightcyan" => Some(Color::LightCyan),
        "white" => Some(Color::White),
        _ => None,
    }
}

/// Per-category foreground colors for syntax-highlighted source code.
/// Users can tweak these directly to customize the code palette.
pub struct SyntaxPalette {
    pub default: Color,
    pub keyword: Color,
    pub string: Color,
    pub comment: Color,
    pub number: Color,
    pub constant: Color,
    pub type_: Color,
    pub function: Color,
    pub variable: Color,
    pub operator: Color,
    pub punctuation: Color,
}

impl SyntaxPalette {
    pub fn color(&self, kind: TokenKind) -> Color {
        match kind {
            TokenKind::Default => self.default,
            TokenKind::Keyword => self.keyword,
            TokenKind::String => self.string,
            TokenKind::Comment => self.comment,
            TokenKind::Number => self.number,
            TokenKind::Constant => self.constant,
            TokenKind::Type => self.type_,
            TokenKind::Function => self.function,
            TokenKind::Variable => self.variable,
            TokenKind::Operator => self.operator,
            TokenKind::Punctuation => self.punctuation,
        }
    }
}

/// Visual chrome convention per theme (design.md §5).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChromeStyle {
    /// `┌ ┐ └ ┘ ─ │` — classic theme.
    Light,
    /// `╭ ╮ ╰ ╯ ─ │` — washi theme.
    Rounded,
    /// No borders — whitespace + heavy rule only (sumi theme).
    Sparse,
}

impl ChromeStyle {
    pub fn show_borders(self) -> bool {
        !matches!(self, ChromeStyle::Sparse)
    }
    pub fn top_left(self) -> char {
        match self {
            ChromeStyle::Light => '┌',
            ChromeStyle::Rounded => '╭',
            ChromeStyle::Sparse => ' ',
        }
    }
    pub fn top_right(self) -> char {
        match self {
            ChromeStyle::Light => '┐',
            ChromeStyle::Rounded => '╮',
            ChromeStyle::Sparse => ' ',
        }
    }
    /// Matching ratatui `BorderType` for `Block` widgets that should follow
    /// the theme's chrome convention. `Sparse` falls back to `Plain` for
    /// callers that need a visible frame regardless (e.g. popups).
    pub fn border_type(self) -> BorderType {
        match self {
            ChromeStyle::Light => BorderType::Plain,
            ChromeStyle::Rounded => BorderType::Rounded,
            ChromeStyle::Sparse => BorderType::Plain,
        }
    }
}

pub struct Theme {
    pub syntax: SyntaxPalette,

    pub chrome: ChromeStyle,
    pub bg: Color,
    pub bg_alt: Color,
    pub shuire: Color,
    pub shuire_dim: Color,
    /// Background of the selected file-list row (design.md §6.3 — a cooler
    /// fill than `cursor_bg`, which is used for the diff cursor).
    pub selection: Color,

    pub border_focused: Color,
    pub border_unfocused: Color,

    pub gutter_fg: Color,

    pub added_fg: Color,
    pub added_bg: Color,
    pub added_word_bg: Color,
    pub removed_fg: Color,
    pub removed_bg: Color,
    pub removed_word_bg: Color,
    pub context_fg: Color,

    pub header_bg: Color,
    pub header_range_fg: Color,
    pub header_context_fg: Color,
    pub fold_fg: Color,

    pub comment_bg: Color,
    pub comment_fg: Color,
    pub comment_bar: Color,
    /// Muted variant of `comment_bar` used to underline lines that have a
    /// comment but are not the currently focused target.
    pub comment_bar_dim: Color,

    pub input_bg: Color,
    pub input_fg: Color,
    pub input_bar: Color,
    pub caret_fg: Color,
    pub caret_bg: Color,

    pub status_added: Color,
    pub status_modified: Color,
    pub status_deleted: Color,
    pub status_renamed: Color,

    pub dir_fg: Color,

    pub mode_normal_bg: Color,
    pub mode_insert_bg: Color,
    pub mode_comments_bg: Color,
    pub mode_search_bg: Color,
    pub mode_visual_bg: Color,
    pub mode_fg: Color,
    pub hint_fg: Color,
    pub hint_bg: Color,
    pub status_fg: Color,

    pub dialog_border: Color,
    pub dialog_location_fg: Color,
    pub dialog_body_fg: Color,

    pub cursor_bg: Color,

    pub dim_fg: Color,

    pub visual_bg: Color,
}

/// Mix two RGB colors. `t` is 0.0..1.0 where 0.0 = `a`, 1.0 = `b`.
pub fn mix_color(a: Color, b: Color, t: f32) -> Color {
    match (a, b) {
        (Color::Rgb(r1, g1, b1), Color::Rgb(r2, g2, b2)) => {
            let mix =
                |c1: u8, c2: u8| -> u8 { (c1 as f32 + (c2 as f32 - c1 as f32) * t).round() as u8 };
            Color::Rgb(mix(r1, r2), mix(g1, g2), mix(b1, b2))
        }
        _ => b,
    }
}

impl Theme {
    /// Return cursor_bg blended 50/50 with the given background color.
    pub fn cursor_blend(&self, bg: Color) -> Color {
        mix_color(bg, self.cursor_bg, 0.5)
    }

    pub fn for_name(name: ThemeName) -> Self {
        match name {
            ThemeName::Classic => Self::classic(),
            ThemeName::Washi => Self::washi(),
            ThemeName::Sumi => Self::sumi(),
            ThemeName::Dark => Self::github_dark(),
            ThemeName::Light => Self::github_light(),
            ThemeName::Deuteranopia => Self::deuteranopia(),
        }
    }

    pub fn for_name_with_overrides(name: ThemeName, overrides: &HashMap<String, Color>) -> Self {
        let mut theme = Self::for_name(name);
        theme.apply_overrides(overrides);
        theme
    }

    pub fn apply_overrides(&mut self, overrides: &HashMap<String, Color>) {
        for (key, color) in overrides {
            let c = *color;
            match key.as_str() {
                "bg" => self.bg = c,
                "bg_alt" => self.bg_alt = c,
                "shuire" => self.shuire = c,
                "shuire_dim" => self.shuire_dim = c,
                "selection" => self.selection = c,
                "border_focused" => self.border_focused = c,
                "border_unfocused" => self.border_unfocused = c,
                "gutter_fg" => self.gutter_fg = c,
                "added_fg" => self.added_fg = c,
                "added_bg" => self.added_bg = c,
                "added_word_bg" => self.added_word_bg = c,
                "removed_fg" => self.removed_fg = c,
                "removed_bg" => self.removed_bg = c,
                "removed_word_bg" => self.removed_word_bg = c,
                "context_fg" => self.context_fg = c,
                "header_bg" => self.header_bg = c,
                "header_range_fg" => self.header_range_fg = c,
                "header_context_fg" => self.header_context_fg = c,
                "fold_fg" => self.fold_fg = c,
                "comment_bg" => self.comment_bg = c,
                "comment_fg" => self.comment_fg = c,
                "comment_bar" => self.comment_bar = c,
                "comment_bar_dim" => self.comment_bar_dim = c,
                "input_bg" => self.input_bg = c,
                "input_fg" => self.input_fg = c,
                "input_bar" => self.input_bar = c,
                "caret_fg" => self.caret_fg = c,
                "caret_bg" => self.caret_bg = c,
                "status_added" => self.status_added = c,
                "status_modified" => self.status_modified = c,
                "status_deleted" => self.status_deleted = c,
                "status_renamed" => self.status_renamed = c,
                "dir_fg" => self.dir_fg = c,
                "mode_normal_bg" => self.mode_normal_bg = c,
                "mode_insert_bg" => self.mode_insert_bg = c,
                "mode_comments_bg" => self.mode_comments_bg = c,
                "mode_search_bg" => self.mode_search_bg = c,
                "mode_visual_bg" => self.mode_visual_bg = c,
                "mode_fg" => self.mode_fg = c,
                "hint_fg" => self.hint_fg = c,
                "hint_bg" => self.hint_bg = c,
                "status_fg" => self.status_fg = c,
                "dialog_border" => self.dialog_border = c,
                "dialog_location_fg" => self.dialog_location_fg = c,
                "dialog_body_fg" => self.dialog_body_fg = c,
                "cursor_bg" => self.cursor_bg = c,
                "dim_fg" => self.dim_fg = c,
                "visual_bg" => self.visual_bg = c,
                "syntax.default" => self.syntax.default = c,
                "syntax.keyword" => self.syntax.keyword = c,
                "syntax.string" => self.syntax.string = c,
                "syntax.comment" => self.syntax.comment = c,
                "syntax.number" => self.syntax.number = c,
                "syntax.constant" => self.syntax.constant = c,
                "syntax.type" => self.syntax.type_ = c,
                "syntax.function" => self.syntax.function = c,
                "syntax.variable" => self.syntax.variable = c,
                "syntax.operator" => self.syntax.operator = c,
                "syntax.punctuation" => self.syntax.punctuation = c,
                _ => {}
            }
        }
    }

    // Syntax palettes deliberately avoid the red/vermilion band because
    // `comment_fg` (shu) sits there — keeping keyword/operator clear of red
    // prevents review comments and code tokens from visually blending.
    pub fn dark_syntax() -> SyntaxPalette {
        SyntaxPalette {
            default: Color::Rgb(235, 240, 248),
            keyword: Color::Rgb(255, 215, 110),
            string: Color::Rgb(195, 230, 255),
            comment: Color::Rgb(170, 182, 196),
            number: Color::Rgb(150, 210, 255),
            constant: Color::Rgb(150, 210, 255),
            type_: Color::Rgb(255, 190, 130),
            function: Color::Rgb(225, 195, 255),
            variable: Color::Rgb(235, 240, 248),
            operator: Color::Rgb(195, 210, 230),
            punctuation: Color::Rgb(235, 240, 248),
        }
    }

    pub fn light_syntax() -> SyntaxPalette {
        SyntaxPalette {
            default: Color::Rgb(36, 41, 47),
            keyword: Color::Rgb(140, 90, 0),
            string: Color::Rgb(10, 48, 105),
            comment: Color::Rgb(110, 119, 129),
            number: Color::Rgb(5, 80, 174),
            constant: Color::Rgb(5, 80, 174),
            type_: Color::Rgb(149, 56, 0),
            function: Color::Rgb(130, 80, 223),
            variable: Color::Rgb(36, 41, 47),
            operator: Color::Rgb(90, 100, 115),
            punctuation: Color::Rgb(36, 41, 47),
        }
    }

    pub fn github_dark() -> Self {
        let accent = Color::Rgb(88, 166, 255);
        let golden = Color::Rgb(210, 153, 34);
        let purple = Color::Rgb(163, 113, 247);
        let shu = Color::Rgb(240, 96, 72);

        Self {
            syntax: Self::dark_syntax(),

            chrome: ChromeStyle::Light,
            bg: Color::Rgb(13, 17, 23),
            bg_alt: Color::Rgb(22, 27, 34),
            shuire: shu,
            shuire_dim: Color::Rgb(140, 68, 55),
            selection: Color::Rgb(47, 54, 64),

            border_focused: accent,
            border_unfocused: Color::Rgb(68, 76, 86),

            gutter_fg: Color::Rgb(95, 102, 112),

            added_fg: Color::Rgb(63, 185, 80),
            added_bg: Color::Rgb(26, 52, 32),
            added_word_bg: Color::Rgb(40, 110, 60),
            removed_fg: Color::Rgb(248, 81, 73),
            removed_bg: Color::Rgb(67, 26, 26),
            removed_word_bg: Color::Rgb(140, 40, 45),
            context_fg: Color::Rgb(201, 209, 217),

            header_bg: Color::Rgb(22, 27, 34),
            header_range_fg: Color::Rgb(110, 118, 129),
            header_context_fg: golden,
            fold_fg: accent,

            comment_bg: Color::Rgb(13, 17, 23),
            comment_fg: shu,
            comment_bar: shu,
            comment_bar_dim: Color::Rgb(140, 68, 55),

            input_bg: Color::Rgb(30, 33, 41),
            input_fg: Color::Rgb(201, 209, 217),
            input_bar: shu,
            caret_fg: Color::Rgb(22, 27, 34),
            caret_bg: accent,

            status_added: Color::Rgb(63, 185, 80),
            status_modified: golden,
            status_deleted: Color::Rgb(248, 81, 73),
            status_renamed: accent,

            dir_fg: Color::Rgb(150, 158, 168),

            mode_normal_bg: accent,
            mode_insert_bg: golden,
            mode_comments_bg: purple,
            mode_search_bg: Color::Rgb(218, 143, 65),
            mode_visual_bg: Color::Rgb(163, 113, 247),
            mode_fg: Color::Rgb(13, 17, 23),
            hint_fg: Color::Rgb(150, 158, 168),
            hint_bg: Color::Rgb(33, 38, 45),
            status_fg: Color::Rgb(130, 138, 149),

            dialog_border: purple,
            dialog_location_fg: golden,
            dialog_body_fg: Color::Rgb(201, 209, 217),

            cursor_bg: Color::Rgb(75, 88, 112),

            dim_fg: Color::Rgb(130, 138, 149),

            visual_bg: Color::Rgb(50, 50, 90),
        }
    }

    pub fn github_light() -> Self {
        let accent = Color::Rgb(9, 105, 218);
        let golden = Color::Rgb(155, 100, 0);
        let purple = Color::Rgb(130, 80, 223);
        let shu = Color::Rgb(198, 48, 30);

        Self {
            syntax: Self::light_syntax(),

            chrome: ChromeStyle::Light,
            bg: Color::Rgb(255, 255, 255),
            bg_alt: Color::Rgb(246, 248, 250),
            shuire: shu,
            shuire_dim: Color::Rgb(225, 165, 155),
            selection: Color::Rgb(218, 225, 255),

            border_focused: accent,
            border_unfocused: Color::Rgb(208, 215, 222),

            gutter_fg: Color::Rgb(175, 184, 193),

            added_fg: Color::Rgb(17, 109, 58),
            added_bg: Color::Rgb(218, 251, 225),
            added_word_bg: Color::Rgb(170, 240, 185),
            removed_fg: Color::Rgb(207, 34, 46),
            removed_bg: Color::Rgb(255, 235, 233),
            removed_word_bg: Color::Rgb(255, 190, 190),
            context_fg: Color::Rgb(36, 41, 47),

            header_bg: Color::Rgb(246, 248, 250),
            header_range_fg: Color::Rgb(110, 119, 129),
            header_context_fg: golden,
            fold_fg: accent,

            comment_bg: Color::Rgb(255, 255, 255),
            comment_fg: shu,
            comment_bar: shu,
            comment_bar_dim: Color::Rgb(225, 165, 155),

            input_bg: Color::Rgb(241, 243, 246),
            input_fg: Color::Rgb(36, 41, 47),
            input_bar: shu,
            caret_fg: Color::Rgb(255, 255, 255),
            caret_bg: accent,

            status_added: Color::Rgb(17, 109, 58),
            status_modified: golden,
            status_deleted: Color::Rgb(207, 34, 46),
            status_renamed: accent,

            dir_fg: Color::Rgb(87, 96, 106),

            mode_normal_bg: accent,
            mode_insert_bg: golden,
            mode_comments_bg: purple,
            mode_search_bg: Color::Rgb(180, 120, 30),
            mode_visual_bg: purple,
            mode_fg: Color::Rgb(255, 255, 255),
            hint_fg: Color::Rgb(87, 96, 106),
            hint_bg: Color::Rgb(234, 238, 242),
            status_fg: Color::Rgb(110, 119, 129),

            dialog_border: purple,
            dialog_location_fg: golden,
            dialog_body_fg: Color::Rgb(36, 41, 47),

            cursor_bg: Color::Rgb(155, 170, 188),

            dim_fg: Color::Rgb(148, 155, 163),

            visual_bg: Color::Rgb(218, 225, 255),
        }
    }

    /// Deuteranopia-friendly variant of github_dark: blue for added, orange for removed.
    pub fn deuteranopia() -> Self {
        Self {
            added_fg: Color::Rgb(88, 166, 255),
            added_bg: Color::Rgb(20, 40, 70),
            added_word_bg: Color::Rgb(40, 90, 160),
            removed_fg: Color::Rgb(218, 143, 65),
            removed_bg: Color::Rgb(70, 45, 20),
            removed_word_bg: Color::Rgb(160, 100, 40),
            status_added: Color::Rgb(88, 166, 255),
            status_deleted: Color::Rgb(218, 143, 65),
            mode_search_bg: Color::Rgb(218, 143, 65),
            ..Self::github_dark()
        }
    }

    // ── Shuire 朱入レ ─ canonical three palettes ─────────────────────────
    // Colour values are taken from the design prototype
    // (`Shuire TUI Design.html` → blob_8 / THEMES).

    fn shuire_classic_syntax() -> SyntaxPalette {
        SyntaxPalette {
            default: Color::Rgb(214, 211, 204),
            keyword: Color::Rgb(199, 146, 234),
            string: Color::Rgb(163, 197, 134),
            comment: Color::Rgb(115, 112, 122),
            number: Color::Rgb(247, 140, 108),
            constant: Color::Rgb(247, 140, 108),
            type_: Color::Rgb(255, 203, 107),
            function: Color::Rgb(130, 170, 255),
            variable: Color::Rgb(214, 211, 204),
            operator: Color::Rgb(180, 176, 190),
            punctuation: Color::Rgb(180, 176, 190),
        }
    }

    fn shuire_washi_syntax() -> SyntaxPalette {
        SyntaxPalette {
            default: Color::Rgb(42, 37, 32),
            keyword: Color::Rgb(122, 62, 122),
            string: Color::Rgb(74, 122, 61),
            comment: Color::Rgb(154, 140, 112),
            number: Color::Rgb(166, 83, 42),
            constant: Color::Rgb(166, 83, 42),
            type_: Color::Rgb(138, 106, 26),
            function: Color::Rgb(44, 95, 138),
            variable: Color::Rgb(42, 37, 32),
            operator: Color::Rgb(100, 90, 78),
            punctuation: Color::Rgb(100, 90, 78),
        }
    }

    fn shuire_sumi_syntax() -> SyntaxPalette {
        SyntaxPalette {
            default: Color::Rgb(240, 235, 224),
            keyword: Color::Rgb(214, 169, 224),
            string: Color::Rgb(176, 208, 152),
            comment: Color::Rgb(115, 112, 106),
            number: Color::Rgb(240, 160, 112),
            constant: Color::Rgb(240, 160, 112),
            type_: Color::Rgb(240, 208, 136),
            function: Color::Rgb(154, 192, 232),
            variable: Color::Rgb(240, 235, 224),
            operator: Color::Rgb(200, 194, 184),
            punctuation: Color::Rgb(200, 194, 184),
        }
    }

    /// 朱入レ classic — dark, practical, vermilion-on-slate.
    pub fn classic() -> Self {
        let shuire = Color::Rgb(230, 57, 70);
        let shuire_dim = Color::Rgb(143, 42, 48);
        let fg = Color::Rgb(214, 211, 204);
        let fg_dim = Color::Rgb(155, 152, 162);
        let fg_muted = Color::Rgb(115, 112, 122);
        let add = Color::Rgb(107, 163, 104);
        let del = Color::Rgb(199, 84, 80);

        Self {
            syntax: Self::shuire_classic_syntax(),

            chrome: ChromeStyle::Light,
            bg: Color::Rgb(20, 19, 22),
            bg_alt: Color::Rgb(28, 27, 32),
            shuire,
            shuire_dim,
            selection: Color::Rgb(47, 54, 64),

            border_focused: shuire,
            border_unfocused: Color::Rgb(51, 49, 58),

            gutter_fg: fg_muted,

            added_fg: add,
            added_bg: Color::Rgb(28, 42, 29),
            added_word_bg: Color::Rgb(48, 95, 55),
            removed_fg: del,
            removed_bg: Color::Rgb(44, 25, 25),
            removed_word_bg: Color::Rgb(120, 45, 45),
            context_fg: fg,

            header_bg: Color::Rgb(28, 27, 32),
            header_range_fg: Color::Rgb(155, 124, 201),
            header_context_fg: fg_dim,
            fold_fg: fg_dim,

            comment_bg: Color::Rgb(20, 19, 22),
            comment_fg: fg,
            comment_bar: shuire,
            comment_bar_dim: shuire_dim,

            input_bg: Color::Rgb(30, 22, 24),
            input_fg: fg,
            input_bar: Color::Rgb(255, 138, 128),
            caret_fg: Color::Rgb(20, 19, 22),
            caret_bg: shuire,

            status_added: add,
            status_modified: Color::Rgb(212, 169, 92),
            status_deleted: del,
            status_renamed: Color::Rgb(110, 158, 207),

            dir_fg: fg_dim,

            mode_normal_bg: shuire,
            mode_insert_bg: Color::Rgb(212, 169, 92),
            mode_comments_bg: Color::Rgb(155, 124, 201),
            mode_search_bg: Color::Rgb(110, 158, 207),
            mode_visual_bg: Color::Rgb(155, 124, 201),
            mode_fg: Color::Rgb(20, 19, 22),
            hint_fg: fg_dim,
            hint_bg: Color::Rgb(36, 34, 42),
            status_fg: fg,

            dialog_border: shuire,
            dialog_location_fg: Color::Rgb(212, 169, 92),
            dialog_body_fg: fg,

            cursor_bg: Color::Rgb(47, 54, 64),

            dim_fg: fg_muted,

            visual_bg: Color::Rgb(66, 40, 52),
        }
    }

    /// 和紙 — warm paper, a proofreader's desk.
    pub fn washi() -> Self {
        let shuire = Color::Rgb(183, 49, 44);
        let shuire_dim = Color::Rgb(138, 37, 34);
        let fg = Color::Rgb(42, 37, 32);
        let fg_dim = Color::Rgb(122, 109, 88);
        let fg_muted = Color::Rgb(168, 155, 132);
        let add = Color::Rgb(74, 122, 61);
        let del = Color::Rgb(183, 49, 44);

        Self {
            syntax: Self::shuire_washi_syntax(),

            chrome: ChromeStyle::Rounded,
            bg: Color::Rgb(245, 239, 224),
            bg_alt: Color::Rgb(239, 232, 213),
            shuire,
            shuire_dim,
            selection: Color::Rgb(229, 216, 176),

            border_focused: shuire,
            border_unfocused: Color::Rgb(191, 174, 138),

            gutter_fg: fg_muted,

            added_fg: add,
            added_bg: Color::Rgb(223, 230, 200),
            added_word_bg: Color::Rgb(176, 202, 140),
            removed_fg: del,
            removed_bg: Color::Rgb(240, 217, 210),
            removed_word_bg: Color::Rgb(220, 170, 164),
            context_fg: fg,

            header_bg: Color::Rgb(239, 232, 213),
            header_range_fg: Color::Rgb(107, 76, 138),
            header_context_fg: fg_dim,
            fold_fg: fg_dim,

            comment_bg: Color::Rgb(245, 239, 224),
            comment_fg: fg,
            comment_bar: shuire,
            comment_bar_dim: shuire_dim,

            input_bg: Color::Rgb(248, 236, 222),
            input_fg: fg,
            input_bar: shuire,
            caret_fg: Color::Rgb(245, 239, 224),
            caret_bg: shuire,

            status_added: add,
            status_modified: Color::Rgb(166, 120, 41),
            status_deleted: del,
            status_renamed: Color::Rgb(60, 110, 162),

            dir_fg: fg_dim,

            mode_normal_bg: shuire,
            mode_insert_bg: Color::Rgb(166, 120, 41),
            mode_comments_bg: Color::Rgb(107, 76, 138),
            mode_search_bg: Color::Rgb(60, 110, 162),
            mode_visual_bg: Color::Rgb(107, 76, 138),
            mode_fg: Color::Rgb(245, 239, 224),
            hint_fg: fg_dim,
            hint_bg: Color::Rgb(229, 216, 176),
            status_fg: fg,

            dialog_border: shuire,
            dialog_location_fg: Color::Rgb(166, 120, 41),
            dialog_body_fg: fg,

            cursor_bg: Color::Rgb(229, 216, 176),

            dim_fg: fg_muted,

            visual_bg: Color::Rgb(229, 216, 176),
        }
    }

    /// 墨 — black ink, high contrast, calligraphic.
    pub fn sumi() -> Self {
        let shuire = Color::Rgb(214, 63, 52);
        let shuire_dim = Color::Rgb(143, 42, 34);
        let fg = Color::Rgb(240, 235, 224);
        let fg_dim = Color::Rgb(155, 148, 138);
        let fg_muted = Color::Rgb(100, 96, 90);
        let add = Color::Rgb(122, 163, 115);
        let del = Color::Rgb(209, 106, 96);

        Self {
            syntax: Self::shuire_sumi_syntax(),

            chrome: ChromeStyle::Sparse,
            bg: Color::Rgb(10, 9, 8),
            bg_alt: Color::Rgb(19, 18, 16),
            shuire,
            shuire_dim,
            selection: Color::Rgb(42, 39, 32),

            border_focused: shuire,
            border_unfocused: Color::Rgb(58, 53, 48),

            gutter_fg: fg_muted,

            added_fg: add,
            added_bg: Color::Rgb(26, 36, 24),
            added_word_bg: Color::Rgb(52, 96, 52),
            removed_fg: del,
            removed_bg: Color::Rgb(42, 24, 22),
            removed_word_bg: Color::Rgb(125, 55, 50),
            context_fg: fg,

            header_bg: Color::Rgb(19, 18, 16),
            header_range_fg: Color::Rgb(176, 144, 208),
            header_context_fg: fg_dim,
            fold_fg: fg_dim,

            comment_bg: Color::Rgb(10, 9, 8),
            comment_fg: fg,
            comment_bar: shuire,
            comment_bar_dim: shuire_dim,

            input_bg: Color::Rgb(30, 16, 14),
            input_fg: fg,
            input_bar: shuire,
            caret_fg: Color::Rgb(10, 9, 8),
            caret_bg: shuire,

            status_added: add,
            status_modified: Color::Rgb(212, 176, 96),
            status_deleted: del,
            status_renamed: Color::Rgb(130, 163, 201),

            dir_fg: fg_dim,

            mode_normal_bg: shuire,
            mode_insert_bg: Color::Rgb(212, 176, 96),
            mode_comments_bg: Color::Rgb(176, 144, 208),
            mode_search_bg: Color::Rgb(130, 163, 201),
            mode_visual_bg: Color::Rgb(176, 144, 208),
            mode_fg: Color::Rgb(10, 9, 8),
            hint_fg: fg_dim,
            hint_bg: Color::Rgb(24, 22, 20),
            status_fg: shuire,

            dialog_border: shuire,
            dialog_location_fg: Color::Rgb(212, 176, 96),
            dialog_body_fg: fg,

            cursor_bg: Color::Rgb(42, 39, 32),

            dim_fg: fg_muted,

            visual_bg: Color::Rgb(48, 26, 34),
        }
    }
}
