"""Unicode character lookup tables for box-drawing, block elements, braille, and indicators."""

from __future__ import annotations

from uframe.ir import BorderWeight

# ---------------------------------------------------------------------------
# Box-drawing characters by weight
# ---------------------------------------------------------------------------

# Keys: (weight) → dict of part names → char
BOX_CHARS: dict[BorderWeight, dict[str, str]] = {
    BorderWeight.LIGHT: {
        "tl": "┌", "tr": "┐", "bl": "└", "br": "┘",
        "h": "─", "v": "│",
        "t_down": "┬", "t_up": "┴", "t_right": "├", "t_left": "┤",
        "cross": "┼",
    },
    BorderWeight.HEAVY: {
        "tl": "┏", "tr": "┓", "bl": "┗", "br": "┛",
        "h": "━", "v": "┃",
        "t_down": "┳", "t_up": "┻", "t_right": "┣", "t_left": "┫",
        "cross": "╋",
    },
    BorderWeight.DOUBLE: {
        "tl": "╔", "tr": "╗", "bl": "╚", "br": "╝",
        "h": "═", "v": "║",
        "t_down": "╦", "t_up": "╩", "t_right": "╠", "t_left": "╣",
        "cross": "╬",
    },
    BorderWeight.ROUNDED: {
        "tl": "╭", "tr": "╮", "bl": "╰", "br": "╯",
        "h": "─", "v": "│",
        "t_down": "┬", "t_up": "┴", "t_right": "├", "t_left": "┤",
        "cross": "┼",
    },
}

# ---------------------------------------------------------------------------
# Block elements for gauges and bars
# ---------------------------------------------------------------------------

# Horizontal fill blocks: full → 1/8
HFILL = "█▉▊▋▌▍▎▏"

# Vertical fill blocks: 1/8 → full (bottom-up)
VFILL = "▁▂▃▄▅▆▇█"

# Shade blocks: 25% → 100%
SHADE = "░▒▓█"

# Gauge characters
GAUGE_FILLED = "█"
GAUGE_EMPTY = "░"

# ---------------------------------------------------------------------------
# Braille patterns for sparklines
# ---------------------------------------------------------------------------

# Braille base: U+2800. Each character is a 2×4 dot matrix.
# Dot positions (bit index):
#   0 3
#   1 4
#   2 5
#   6 7
BRAILLE_BASE = 0x2800

# Row dot bits for left column (bits 0,1,2,6) and right column (bits 3,4,5,7)
BRAILLE_LEFT = [0x01, 0x02, 0x04, 0x40]   # rows 0-3
BRAILLE_RIGHT = [0x08, 0x10, 0x20, 0x80]  # rows 0-3


def braille_char(dots: list[tuple[int, int]]) -> str:
    """Build a braille character from a list of (col, row) positions.

    col: 0 (left) or 1 (right)
    row: 0 (top) to 3 (bottom)
    """
    code = BRAILLE_BASE
    for col, row in dots:
        if 0 <= row <= 3:
            if col == 0:
                code |= BRAILLE_LEFT[row]
            else:
                code |= BRAILLE_RIGHT[row]
    return chr(code)


def sparkline_chars(values: list[float], width: int) -> list[str]:
    """Convert a list of values into braille sparkline characters.

    Each output character represents two consecutive values (left + right columns).
    Values are normalized to 0–7 (mapping to 4 braille rows × 2 resolution).
    """
    if not values:
        return []

    lo = min(values)
    hi = max(values)
    span = hi - lo if hi != lo else 1.0

    # Normalize to 0–7 range (8 vertical positions: 4 rows × 2 resolution)
    norm = [int((v - lo) / span * 7) for v in values]

    # Pad to even length
    if len(norm) % 2:
        norm.append(norm[-1])

    chars = []
    for i in range(0, min(len(norm), width * 2), 2):
        left_val = norm[i]
        right_val = norm[i + 1] if i + 1 < len(norm) else norm[i]

        dots = []
        # Fill dots from bottom up for each column
        for row in range(3, -1, -1):
            threshold = (3 - row) * 2  # row 3=0, row 2=2, row 1=4, row 0=6
            if left_val >= threshold:
                dots.append((0, row))
            if right_val >= threshold:
                dots.append((1, row))

        chars.append(braille_char(dots))

    return chars[:width]


# ---------------------------------------------------------------------------
# Status indicators
# ---------------------------------------------------------------------------

STATUS_CHARS: dict[str, str] = {
    "online": "●",
    "offline": "○",
    "degraded": "◐",
    "unknown": "◌",
    "alert": "⚠",
}

STATUS_COLORS: dict[str, str] = {
    "online": "0f0",
    "offline": "f00",
    "degraded": "ff0",
    "unknown": "888",
    "alert": "f00",
}

# ---------------------------------------------------------------------------
# Divider characters
# ---------------------------------------------------------------------------

DIVIDER_CHARS: dict[str, str] = {
    "light": "─",
    "heavy": "━",
    "double": "═",
    "dash": "╌",
    "dot": "┄",
}
