"""PUREFN CLI - main entry point.

Typer-based CLI for pure, stateless game operations.
Supports JSON in/out mode for agent integration.
"""

from __future__ import annotations

import sys

import typer

from purefn.cli.cards import cards_app
from purefn.cli.chess import app as chess_app
from purefn.cli.demo import demo_app
from purefn.cli.protocol import protocol_app
from purefn.core.registry import apply_envelope
from purefn.io.jsonio import read_json_stdin, write_json_stderr, write_json_stdout
from purefn.resources import load_text

app = typer.Typer(
    help=(
        "PUREFN - game engines for cards, chess, and protocol. "
        "Use 'purefn cards', 'purefn chess', or 'purefn protocol' to get started, "
        "or 'purefn run' for the JSON envelope API."
    ),
    add_completion=False,
    invoke_without_command=True,
)

app.add_typer(cards_app, name="cards")
app.add_typer(chess_app, name="chess")
app.add_typer(demo_app, name="demo")
app.add_typer(protocol_app, name="protocol")


@app.callback(invoke_without_command=True)
def main(ctx: typer.Context) -> None:
    """Show a friendly overview when no command is provided."""
    if ctx.invoked_subcommand is not None:
        return
    from purefn import __version__

    template = load_text("app_welcome.md")
    message = template.replace("{version}", __version__).strip()
    typer.echo(message)
    raise typer.Exit(code=0)


@app.command()
def run(
    human: bool = typer.Option(False, "--human", help="Human-readable output with colors"),
) -> None:
    """Read an action envelope from stdin JSON; write result to stdout JSON.

    Examples (JSON envelope API):

        # Create a new cards deck
        echo '{"game":"cards","op":"deck","args":{"seed":"demo"}}' | purefn run

        # Deal 5 cards to alice using the returned global token
        echo '{"game":"cards","op":"deal","global":"<DECK_TOKEN>",'
             '"args":{"player":"alice","num_cards":5}}' | purefn run
    """
    try:
        envelope = read_json_stdin()
        result = apply_envelope(envelope)

        if human:
            # Human-readable output
            import json

            print(json.dumps(result, indent=2))
        else:
            # Compact JSON for agents
            write_json_stdout(result)

        # Propagate failure via exit code while still returning JSON
        if not result.get("ok", True):
            sys.exit(1)

    except Exception as e:
        error_result = {"ok": False, "error": str(e)}
        if human:
            write_json_stderr(error_result)
        else:
            write_json_stdout(error_result)
        sys.exit(1)


@app.command()
def version() -> None:
    """Show PUREFN version."""
    from purefn import __version__

    print(f"PUREFN version {__version__}")


@app.command()
def games() -> None:
    """List available games."""
    from purefn.core.registry import list_games

    available = list_games()
    print("Available games:")
    for game in available:
        print(f"  - {game}")
