"""CLI dump mode for FM24 Database Searcher.

Outputs player data as plain text so LLMs can inspect
and verify extracted values.

Usage::

    python -m python_pkg.fm24_searcher --dump
    python -m python_pkg.fm24_searcher --dump --search Messi
    python -m python_pkg.fm24_searcher --dump --limit 20
    python -m python_pkg.fm24_searcher --dump --attrs
"""

from __future__ import annotations

import argparse
from pathlib import Path
from typing import TYPE_CHECKING

from python_pkg.fm24_searcher.binary_parser import (
    parse_people_db,
    search_players,
)
from python_pkg.fm24_searcher.models import ALL_VISIBLE_ATTRS, Player

if TYPE_CHECKING:
    from collections.abc import Sequence

# Default path to FM24 people database.
_DEFAULT_DB = (
    Path.home()
    / ".local/share/Steam/steamapps/common"
    / "Football Manager 2024/data/database/db"
    / "2400/2400_fm/people_db.dat"
)

_DEFAULT_LIMIT = 50


def _format_player_attrs(player: Player) -> list[str]:
    """Format the attributes section for a player."""
    if not player.attributes:
        return ["  (no attribute block found)"]
    lines = ["  Attributes:"]
    lines += [
        f"    {attr}: {val}"
        for attr in ALL_VISIBLE_ATTRS
        if (val := player.attributes.get(attr, 0)) > 0
    ]
    missing = [a for a in ALL_VISIBLE_ATTRS if a not in player.attributes]
    if missing:
        lines.append(f"  Missing attrs: {', '.join(missing)}")
    return lines


_OPTIONAL_FIELDS = [
    ("DOB", "date_of_birth"),
    ("CA", "current_ability"),
    ("PA", "potential_ability"),
    ("Nationality", "nationality"),
    ("Club", "club"),
    ("Position", "position"),
    ("Personality bytes", "personality"),
]


def _format_player(player: Player, *, show_attrs: bool = False) -> str:
    """Format one player as a multi-line text block."""
    lines = [f"=== {player.name} ==="]
    lines += [
        f"  {label}: {getattr(player, field)}"
        for label, field in _OPTIONAL_FIELDS
        if getattr(player, field)
    ]
    if show_attrs:
        lines.extend(_format_player_attrs(player))
    lines.append(f"  Source: {player.source}")
    lines.append(f"  UID (byte offset): {player.uid}")
    return "\n".join(lines)


def _format_tsv_header(*, show_attrs: bool) -> str:
    """Build TSV header line."""
    cols = ["Name", "DOB", "CA", "PA", "Personality", "UID"]
    if show_attrs:
        cols.extend(ALL_VISIBLE_ATTRS)
    return "\t".join(cols)


def _format_tsv_row(player: Player, *, show_attrs: bool) -> str:
    """Format one player as a TSV row."""
    cols = [
        player.name,
        player.date_of_birth,
        str(player.current_ability) if player.current_ability else "",
        str(player.potential_ability) if player.potential_ability else "",
        ",".join(str(p) for p in player.personality),
        str(player.uid),
    ]
    if show_attrs:
        for attr in ALL_VISIBLE_ATTRS:
            val = player.attributes.get(attr, 0)
            cols.append(str(val) if val > 0 else "")
    return "\t".join(cols)


def build_parser() -> argparse.ArgumentParser:
    """Build the argument parser for CLI mode."""
    parser = argparse.ArgumentParser(
        prog="fm24_searcher",
        description="FM24 Database Searcher — CLI dump mode",
    )
    parser.add_argument(
        "--dump",
        action="store_true",
        help="Enable CLI dump mode (text output, no GUI)",
    )
    parser.add_argument(
        "--search",
        type=str,
        default="",
        help="Filter players by name substring",
    )
    parser.add_argument(
        "--limit",
        type=int,
        default=_DEFAULT_LIMIT,
        help=f"Max number of players to show (default {_DEFAULT_LIMIT})",
    )
    parser.add_argument(
        "--attrs",
        action="store_true",
        help="Include all visible attributes in output",
    )
    parser.add_argument(
        "--tsv",
        action="store_true",
        help="Output as tab-separated values (machine-readable)",
    )
    parser.add_argument(
        "--db",
        type=str,
        default="",
        help="Path to people_db.dat (overrides default)",
    )
    parser.add_argument(
        "--with-attrs-only",
        action="store_true",
        help="Only show players that have attribute blocks",
    )
    parser.add_argument(
        "--stats",
        action="store_true",
        help="Show summary statistics about the loaded database",
    )
    return parser


def _print_stats(players: list[Player]) -> None:
    """Print summary statistics about loaded players."""
    total = len(players)
    sum(1 for p in players if p.date_of_birth)
    with_attrs = sum(1 for p in players if p.attributes)
    sum(1 for p in players if p.current_ability)
    if with_attrs > 0:
        sum(len(p.attributes) for p in players) / with_attrs
    if total == 0:
        return
    if with_attrs > 0:
        pass
    # Attribute coverage
    attr_counts: dict[str, int] = {}
    for p in players:
        for attr in p.attributes:
            attr_counts[attr] = attr_counts.get(attr, 0) + 1
    if attr_counts:
        for attr in ALL_VISIBLE_ATTRS:
            count = attr_counts.get(attr, 0)
            pct = 100 * count / with_attrs if with_attrs else 0
            "*" * int(pct / 5)


def run_dump(argv: Sequence[str] | None = None) -> int:
    """Execute CLI dump mode. Returns exit code."""
    parser = build_parser()
    args = parser.parse_args(argv)

    if not args.dump:
        return 1

    db_path = Path(args.db) if args.db else _DEFAULT_DB
    if not db_path.exists():
        return 2

    def progress(msg: str, pct: int) -> None:
        pass

    players = parse_people_db(db_path, progress_cb=progress)

    if args.search:
        players = search_players(players, args.search)

    if args.with_attrs_only:
        players = [p for p in players if p.attributes]

    if args.stats:
        _print_stats(players)
        return 0

    # Apply limit
    limited = players[: args.limit]

    # Output
    if args.tsv:
        for _p in limited:
            pass
    else:
        for _p in limited:
            pass

    return 0
