"""Rich helpers for TTY vs non-TTY CLI output.

Uses the same ideas as the ``typer-and-rich`` skill (Rich + Typer non-TTY patterns):
``Measurement.get`` on a temporary wide ``Console``; for ``Panel``, set the real
``console.width`` to the measured width, then ``print`` with ``crop=False``,
``overflow="ignore"``, ``no_wrap=True``, ``soft_wrap=True``; non-TTY consoles use
``soft_wrap=True``; ``Progress`` should use ``disable=`` when the progress stream is
not a TTY (see that skill's non-TTY / Progress notes).

``make_console`` does not read ``COLUMNS`` or invent sink widths.

``stderr_interactive`` is the single check for whether Rich ``Progress`` / live UI
should run on stderr (TTY).
"""

from __future__ import annotations

import sys
from io import StringIO
from typing import TYPE_CHECKING

from rich.console import Console, RenderableType
from rich.measure import Measurement

if TYPE_CHECKING:
    from rich.panel import Panel

__all__ = ["get_rendered_width", "make_console", "print_measured_panel", "stderr_interactive"]

# Wide temporary console so ``Measurement.get`` is not capped at ~80.
# Rich: if only ``width=`` is set and ``TERM=dumb`` (common in CI), ``Console.size``
# short-circuits to 80x25 before honoring width — set both dimensions and a buffer file.
_MEASUREMENT_CONSOLE_WIDTH = 999_999
_MEASUREMENT_CONSOLE_HEIGHT = 999


def get_rendered_width(renderable: RenderableType) -> int:
    """Return the natural maximum width of a renderable (Panel, Table, etc.)."""
    temp = Console(width=_MEASUREMENT_CONSOLE_WIDTH, height=_MEASUREMENT_CONSOLE_HEIGHT, file=StringIO())
    measurement = Measurement.get(temp, temp.options, renderable)
    return int(measurement.maximum)


def stderr_interactive() -> bool:
    """True when stderr is a TTY (safe to use Rich ``Progress`` / spinners on stderr)."""
    return sys.stderr.isatty()


def make_console(*, stderr: bool = False) -> Console:
    """Return a console for the target stream; non-TTY enables soft wrap for log-style output."""
    is_tty = sys.stderr.isatty() if stderr else sys.stdout.isatty()
    if is_tty:
        return Console(stderr=stderr)
    return Console(stderr=stderr, soft_wrap=True)


def print_measured_panel(console: Console, panel: Panel) -> None:
    """Print a ``Panel`` in non-TTY contexts without wrapping at the default narrow width.

    Uses ``console.size`` (width + height): with ``TERM=dumb``, Rich ignores a lone
    ``width=`` assignment and keeps reporting 80 columns — setting both dimensions
    avoids that.
    """
    w = get_rendered_width(panel)
    prev = console.size
    console.size = (w, prev.height)
    try:
        console.print(panel, crop=False, overflow="ignore", no_wrap=True, soft_wrap=True)
    finally:
        console.size = (prev.width, prev.height)
