"""KIT (Karlsruhe Institute of Technology) corporate design color palette.

Hex values for KIT green, KIT blue, black 70%, and the corporate accent
colors are taken verbatim from the KIT corporate design guide
(https://kit-cd.km.kit.edu/english/341.php) — do not hand-edit them without
checking that page.

The categorical *order* below is not arbitrary: it was chosen by running
every hue through the CVD-safety/contrast checks described in the `dataviz`
skill (fixed hue order, OKLab CVD separation under simulated color-vision
deficiency, a normal-vision separation floor, contrast vs. a white surface)
and keeping the ordering that clears the adjacent-pair checks. KIT yellow
(#FCE500) is the one hue that cannot pass on its own (too light on a white
surface, ~1.3:1 contrast) — that is a property of the hex value itself, not
the ordering, so it is placed last and should always be paired with a
visible direct label rather than relied on as a fill alone.
"""

from __future__ import annotations

from matplotlib.colors import LinearSegmentedColormap

# Fixed-order categorical hues (KIT primary + accent colors). Order is the
# CVD-safety mechanism: never reorder, and never cycle past the last slot
# (fold extra series into "Other").
CATEGORICAL = [
    "#009682",  # 0 KIT green (primary)
    "#DF9B1B",  # 1 orange
    "#4664AA",  # 2 KIT blue (primary)
    "#A78230",  # 3 brown
    "#23A1E0",  # 4 cyan
    "#A3107C",  # 5 purple
    "#8CB63C",  # 6 pea green
    "#A22223",  # 7 red
    "#FCE500",  # 8 yellow — low contrast on white; always pair with a direct label
]

# Single-hue (KIT blue) sequential ramp, steps 100..700. Step 700 is the exact
# brand hex (the high/saturated end); lighter steps are tints blended toward
# white in sRGB — there is no darker-than-brand shade.
SEQUENTIAL_STEPS = [
    "#e3e8f2",  # 100
    "#c9d2e6",  # 200
    "#afbcda",  # 300
    "#95a6ce",  # 400
    "#7a90c2",  # 500
    "#607ab6",  # 600
    "#4664AA",  # 700 (KIT blue)
]

# Diverging KIT blue <-> KIT red, neutral gray midpoint.
DIVERGING = {
    "low": "#4664AA",
    "mid": "#f7f7f7",
    "high": "#A22223",
}

# Fixed, reserved status scale — deliberately NOT re-themed to KIT colors:
# status is a small fixed scale with reserved meaning that must stay visually
# distinct from the categorical slots so it never impersonates a series.
# Never put these in the categorical cycle; always pair with an icon/label.
STATUS = {
    "good": "#0ca30c",
    "warning": "#fab219",
    "serious": "#ec835a",
    "critical": "#d03b3b",
}

# Chrome / ink roles, derived from KIT's specified "black 70%" (#404040,
# used by KIT for headings and continuous text) on a white surface.
INK = {
    "surface": "#ffffff",
    "primary": "#404040",  # KIT black 70% — headings, titles, continuous text
    "secondary": "#6a6a6a",
    "muted": "#969696",
    "gridline": "#ececec",
    "baseline": "#c2c2c2",
}


def get_color(index: int) -> str:
    """Return the categorical color for series `index` (0-based).

    Raises ValueError past the validated slots instead of silently wrapping
    back to slot 0, which would collide two series on the same hue.
    """
    if not 0 <= index < len(CATEGORICAL):
        raise ValueError(
            f"get_color({index}) out of range: only {len(CATEGORICAL)} validated categorical "
            "colors exist. Fold extra series into an 'Other' bucket or facet instead of cycling."
        )
    return CATEGORICAL[index]


def sequential_cmap(name: str = "ps_sequential") -> LinearSegmentedColormap:
    """Continuous KIT-blue sequential colormap for magnitude encoding."""
    return LinearSegmentedColormap.from_list(name, SEQUENTIAL_STEPS)


def diverging_cmap(name: str = "ps_diverging") -> LinearSegmentedColormap:
    """Continuous KIT blue-gray-red diverging colormap for polarity encoding."""
    return LinearSegmentedColormap.from_list(name, [DIVERGING["low"], DIVERGING["mid"], DIVERGING["high"]])
