"""CLI utility functions for input validation and display helpers."""

from __future__ import annotations

import argparse
from typing import Any, Dict, List

from tokenmoulds.licensing import resolve_license_context, validate_or_exit


def _preview_sample(
    previews: Dict[str, List[str]], key: str, *, limit: int = 4, separator: str = ", "
) -> str:
    values = previews.get(key) or []
    if not values:
        return ""
    sample = separator.join(values[:limit])
    return sample


def _print_preview_samples(
    previews: Dict[str, List[str]],
    key: str,
    label: str,
    *,
    limit: int = 4,
    separator: str = ", ",
) -> None:
    sample = _preview_sample(previews, key, limit=limit, separator=separator)
    if sample:
        print(f"      {label}: {sample}")


def _render_preview_section(previews: Dict[str, List[str]]) -> str:
    lines: List[str] = []
    for label, key in (
        ("Lighten", "lighten"),
        ("Darken", "darken"),
        ("Saturate", "saturate"),
    ):
        sample = _preview_sample(previews, key, limit=6)
        if sample:
            lines.append(f"- **{label}:** {sample}")
    contrast_sample = _preview_sample(
        previews, "heading_contrast", limit=6, separator=" | "
    )
    if contrast_sample:
        lines.append(f"- **Heading vs Body contrast:** {contrast_sample}")
    for mode in ("protanopia", "deuteranopia", "tritanopia"):
        sample = _preview_sample(previews, f"color_blind_{mode}", limit=6)
        if sample:
            label = f"{mode.capitalize()} palette"
            lines.append(f"- **{label}:** {sample}")
    if not lines:
        return ""
    return "### Palette Previews\n" + "\n".join(lines) + "\n\n"


def _count_tokens(payload: Any) -> int:
    if isinstance(payload, dict):
        return sum(_count_tokens(value) for value in payload.values())
    if isinstance(payload, list):
        return sum(_count_tokens(value) for value in payload)
    return 1


def _resolve_license(args: argparse.Namespace) -> None:
    context = resolve_license_context(
        license_id=getattr(args, "license_id", None),
        license_repo=getattr(args, "license_repo", None),
        default_repo=f"tokenmoulds/{args.org_id}",
    )
    validate_or_exit(context)


def parse_font_pair(font_pair_str: str) -> Dict[str, str]:
    """Parse font pair string into sans/serif dictionary."""
    font_pairs = {
        "inter-roboto": {"sans": "Inter", "serif": "Roboto Slab"},
        "work-sans-source": {"sans": "Work Sans", "serif": "Source Serif Pro"},
        "public-sans-spectral": {"sans": "Public Sans", "serif": "Spectral"},
    }

    if font_pair_str not in font_pairs:
        available = ", ".join(font_pairs.keys())
        raise ValueError(f"Invalid font pair '{font_pair_str}'. Available: {available}")

    return font_pairs[font_pair_str]


def validate_hex_color(color: str) -> str:
    """Validate and normalize hex color."""
    if not color.startswith("#"):
        color = "#" + color

    if len(color) != 7:
        raise ValueError(f"Invalid hex color '{color}'. Must be 6 digits after #")

    try:
        int(color[1:], 16)
    except ValueError:
        raise ValueError(f"Invalid hex color '{color}'. Must contain only hex digits")

    return color.upper()


def validate_brand_tone(tone: float) -> float:
    """Validate brand tone range."""
    if not 0.0 <= tone <= 1.0:
        raise ValueError(f"Brand tone must be between 0.0 and 1.0, got {tone}")
    return tone


def validate_content_density(density: float) -> float:
    """Validate content density range."""
    if not 0.0 <= density <= 1.0:
        raise ValueError(f"Content density must be between 0.0 and 1.0, got {density}")
    return density
