"""Logging formatters and helpers for colorized terminal output."""

import logging
import os
import sys
from typing import Optional, TextIO


RESET = "\033[0m"
DIM = "\033[2m"
BOLD = "\033[1m"
FG_BLUE = "\033[34m"
FG_CYAN = "\033[36m"
FG_GREEN = "\033[32m"
FG_MAGENTA = "\033[35m"
FG_YELLOW = "\033[33m"
FG_RED = "\033[31m"

LEVEL_COLORS = {
    logging.DEBUG: f"{DIM}{FG_CYAN}",
    logging.INFO: FG_GREEN,
    logging.WARNING: FG_YELLOW,
    logging.ERROR: FG_RED,
    logging.CRITICAL: f"{BOLD}{FG_RED}",
}


def should_use_color(stream: Optional[TextIO] = None, use_color: Optional[bool] = None) -> bool:
    """Return whether ANSI colors should be used for the given stream."""
    if use_color is not None:
        return use_color

    if os.getenv("NO_COLOR") is not None:
        return False

    force_color = os.getenv("FORCE_COLOR", "").strip().lower()
    if force_color and force_color not in {"0", "false", "no"}:
        return True

    if os.getenv("TERM", "").lower() == "dumb":
        return False

    target_stream = stream or sys.stderr
    is_tty = getattr(target_stream, "isatty", None)
    return bool(is_tty and is_tty())


def colorize(text: str, style: str, enabled: bool) -> str:
    """Apply ANSI style to text when enabled."""
    if not enabled or not style:
        return text
    return f"{style}{text}{RESET}"


class LevelColorFormatter(logging.Formatter):
    """Formatter that colors only the log level token."""

    def __init__(
        self,
        fmt: Optional[str] = None,
        datefmt: Optional[str] = None,
        style: str = "%",
        *,
        stream: Optional[TextIO] = None,
        use_color: Optional[bool] = None,
    ):
        super().__init__(fmt=fmt, datefmt=datefmt, style=style)
        self._use_color = should_use_color(stream=stream, use_color=use_color)

    def format(self, record: logging.LogRecord) -> str:
        if not self._use_color:
            return super().format(record)

        original_levelname = record.levelname
        record.levelname = colorize(
            original_levelname,
            LEVEL_COLORS.get(record.levelno, ""),
            enabled=True,
        )
        try:
            return super().format(record)
        finally:
            record.levelname = original_levelname
