"""Gradient coloring for rendered block characters.

Provides left-to-right and complementary gradient effects for terminal display.
"""

from sideline.terminal import RST

# Left → right: white-hot leading edge fades to near-black
GRAD_COLS = [
    "\033[1;38;5;231m",  # white
    "\033[1;38;5;195m",  # pale cyan-white
    "\033[38;5;123m",  # bright cyan
    "\033[38;5;118m",  # bright lime
    "\033[38;5;82m",  # lime
    "\033[38;5;46m",  # bright green
    "\033[38;5;40m",  # green
    "\033[38;5;34m",  # medium green
    "\033[38;5;28m",  # dark green
    "\033[38;5;22m",  # deep green
    "\033[2;38;5;22m",  # dim deep green
    "\033[2;38;5;235m",  # near black
]

# Complementary sweep for queue messages (opposite hue family from ticker greens)
MSG_GRAD_COLS = [
    "\033[1;38;5;231m",  # white
    "\033[1;38;5;225m",  # pale pink-white
    "\033[38;5;219m",  # bright pink
    "\033[38;5;213m",  # hot pink
    "\033[38;5;207m",  # magenta
    "\033[38;5;201m",  # bright magenta
    "\033[38;5;165m",  # orchid-red
    "\033[38;5;161m",  # ruby-magenta
    "\033[38;5;125m",  # dark magenta
    "\033[38;5;89m",  # deep maroon-magenta
    "\033[2;38;5;89m",  # dim deep maroon-magenta
    "\033[2;38;5;235m",  # near black
]


def lr_gradient(rows, offset=0.0, grad_cols=None):
    """Color each non-space block character with a shifting left-to-right gradient.

    Args:
        rows: List of text lines with block characters
        offset: Gradient offset (0.0-1.0) for animation
        grad_cols: List of ANSI color codes (default: GRAD_COLS)

    Returns:
        List of lines with gradient coloring applied
    """
    cols = grad_cols or GRAD_COLS
    n = len(cols)
    max_x = max((len(r.rstrip()) for r in rows if r.strip()), default=1)
    out = []
    for row in rows:
        if not row.strip():
            out.append(row)
            continue
        buf = []
        for x, ch in enumerate(row):
            if ch == " ":
                buf.append(" ")
            else:
                shifted = (x / max(max_x - 1, 1) + offset) % 1.0
                idx = min(round(shifted * (n - 1)), n - 1)
                buf.append(f"{cols[idx]}{ch}{RST}")
        out.append("".join(buf))
    return out


def lr_gradient_opposite(rows, offset=0.0):
    """Complementary (opposite wheel) gradient used for queue message panels.

    Args:
        rows: List of text lines with block characters
        offset: Gradient offset (0.0-1.0) for animation

    Returns:
        List of lines with complementary gradient coloring applied
    """
    return lr_gradient(rows, offset, MSG_GRAD_COLS)


def msg_gradient(rows, offset):
    """Apply message (ntfy) gradient using theme complementary colors.

    Returns colored rows using ACTIVE_THEME.message_gradient if available,
    falling back to default magenta if no theme is set.

    Args:
        rows: List of text strings to colorize
        offset: Gradient offset (0.0-1.0) for animation

    Returns:
        List of rows with ANSI color codes applied
    """
    from engine import config

    # Check if theme is set and use it
    if config.ACTIVE_THEME:
        cols = _color_codes_to_ansi(config.ACTIVE_THEME.message_gradient)
    else:
        # Fallback to default magenta gradient
        cols = MSG_GRAD_COLS

    return lr_gradient(rows, offset, cols)


def _color_codes_to_ansi(color_codes):
    """Convert a list of 256-color codes to ANSI escape code strings.

    Pattern: first 2 are bold, middle 8 are normal, last 2 are dim.

    Args:
        color_codes: List of 12 integers (256-color palette codes)

    Returns:
        List of ANSI escape code strings
    """
    if not color_codes or len(color_codes) != 12:
        # Fallback to default green if invalid
        return GRAD_COLS

    result = []
    for i, code in enumerate(color_codes):
        if i < 2:
            # Bold for first 2 (bright leading edge)
            result.append(f"\033[1;38;5;{code}m")
        elif i < 10:
            # Normal for middle 8
            result.append(f"\033[38;5;{code}m")
        else:
            # Dim for last 2 (dark trailing edge)
            result.append(f"\033[2;38;5;{code}m")
    return result
