"""Text-to-ASCII art using pyfiglet — font picker, preview, export."""
from __future__ import annotations

import pyfiglet
from rich.console import Console
from rich.panel import Panel
from rich.columns import Columns
from rich.text import Text
from rich import box as rbox

console = Console()

# Curated font groups
FONT_GROUPS: dict[str, list[str]] = {
    "bold": ["banner", "banner3", "banner4", "block", "chunky", "colossal", "doom", "epic", "larry3d", "univers"],
    "slim": ["thin", "term", "morse", "digital", "ogre", "pepper", "shimrod"],
    "3d": ["3-d", "3d_diagonal", "3d-ascii", "larry3d", "nancyj-fancy", "trek"],
    "rounded": ["rounded", "soft", "smisome1", "smkeyboard", "smslant"],
    "fancy": ["alligator", "alligator2", "alpha", "broadway", "calgphy2", "catwalk", "crawford"],
    "retro": ["DOS Rebel", "acrobatic", "banner", "big", "bigchief", "binary", "c_ascii"],
    "small": ["mini", "small", "smscript", "smshadow", "smslant", "speed"],
    "shadow": ["shadow", "sblood", "smkeyboard"],
    "stars": ["starwars", "star_wars"],
    "default": ["slant", "big", "banner3-D", "doom", "isometric1", "lean"],
}

ALL_FONTS = sorted(pyfiglet.FigletFont.getFonts())

FAVORITE_FONTS = [
    "slant", "big", "doom", "banner3-D", "3d_diagonal", "larry3d",
    "block", "chunky", "colossal", "epic", "isometric1", "lean",
    "roman", "rounded", "shadow", "starwars", "alligator2",
    "stop", "univers", "standard",
]


def render(text: str, font: str = "slant", color: str = "cyan") -> str:
    """Render text as ASCII art, return the raw string."""
    try:
        result = pyfiglet.figlet_format(text, font=font)
    except pyfiglet.FontNotFound:
        result = pyfiglet.figlet_format(text, font="standard")
    return result


def preview_fonts(text: str, fonts: list[str] | None = None, limit: int = 20) -> None:
    """Preview text in multiple fonts side by side."""
    use_fonts = fonts or FAVORITE_FONTS
    for font in use_fonts[:limit]:
        try:
            art = pyfiglet.figlet_format(text, font=font)
            console.print(Panel(art.rstrip(), title=f"[yellow]{font}[/]", border_style="dim"))
        except Exception:
            pass


def interactive_font_picker(text: str) -> tuple[str, str]:
    """Interactive font + color picker. Returns (art_string, font_name)."""
    console.print("\n[bold cyan]── ASCII Text Art ──[/]")
    console.print(f"Text: [yellow]{text}[/]\n")

    # Show font groups
    console.print("[bold]Font groups:[/]")
    groups = list(FONT_GROUPS.keys())
    for i, g in enumerate(groups, 1):
        console.print(f"  [cyan]{i:2}[/] {g}")

    console.print("\n  [cyan] 0[/] Browse all fonts")
    console.print("  [cyan] f[/] Enter font name directly\n")

    choice = console.input("[bold]Pick group (1-{}) or 0/f: [/]".format(len(groups))).strip()

    if choice == "f":
        font = console.input("Font name: ").strip() or "slant"
        fonts_to_preview = [font]
    elif choice == "0":
        query = console.input("Filter fonts (leave blank for all): ").strip().lower()
        fonts_to_preview = [f for f in ALL_FONTS if query in f] if query else ALL_FONTS[:40]
    else:
        try:
            group = groups[int(choice) - 1]
            fonts_to_preview = FONT_GROUPS[group]
        except (ValueError, IndexError):
            fonts_to_preview = FAVORITE_FONTS

    # Preview
    console.print()
    for i, font in enumerate(fonts_to_preview, 1):
        try:
            art = pyfiglet.figlet_format(text, font=font)
            console.print(f"[dim]{i:3}. {font}[/]")
            console.print(art.rstrip())
            console.rule(style="dim")
        except Exception:
            pass

    idx = console.input(f"\n[bold]Pick font number (1-{len(fonts_to_preview)}) or name: [/]").strip()
    try:
        font = fonts_to_preview[int(idx) - 1]
    except (ValueError, IndexError):
        font = idx if idx else "slant"

    colors = ["cyan", "green", "yellow", "red", "magenta", "blue", "white", "bright_cyan", "bright_green"]
    console.print("\n[bold]Colors:[/] " + "  ".join(f"[{c}]{c}[/{c}]" for c in colors))
    color = console.input("[bold]Pick color (or hex #ff6600): [/]").strip() or "cyan"

    return render(text, font), font


def list_fonts(group: str | None = None) -> None:
    """Print available fonts, optionally filtered by group."""
    if group and group in FONT_GROUPS:
        fonts = FONT_GROUPS[group]
        console.print(f"\n[bold cyan]Fonts in '{group}':[/]")
    else:
        fonts = ALL_FONTS
        console.print(f"\n[bold cyan]All {len(fonts)} fonts:[/]")

    items = [Text(f, style="yellow") for f in fonts]
    console.print(Columns(items, equal=True, expand=False))
