from pathlib import Path
import typer
from typing import Optional

from aye.controller import commands, repl
from aye.presenter import cli_ui
from aye.presenter.diff_presenter import show_diff
from aye.model.version_checker import check_version_and_print_warning
from aye.model.auth import set_user_config

# Check for newer version on startup
check_version_and_print_warning()

app = typer.Typer(help="Aye: AI‑powered coding assistant for the terminal")

# ----------------------------------------------------------------------
# Version callback
# ----------------------------------------------------------------------

def _get_package_version() -> str:
    """Get the version of the installed package (ayechat or ayechat-dev)."""
    from aye.model.version_checker import get_current_version
    return get_current_version()

def _version_callback(value: bool):
    if value:
        typer.echo(_get_package_version())
        raise typer.Exit()

@app.callback(invoke_without_command=True)
def main(
    ctx: typer.Context,
    version: bool = typer.Option(None, "--version", callback=_version_callback, is_eager=True, help="Show the version and exit."),
):
    if ctx.invoked_subcommand is None:
        typer.echo("Run 'aye --help' to see available commands.")

# ----------------------------------------------------------------------
# Auth commands
# ----------------------------------------------------------------------
auth_app = typer.Typer(help="Authentication commands")
app.add_typer(auth_app, name="auth")

@auth_app.command()
def login():
    """Configure personal access token for authenticating with the aye service."""
    try:
        commands.login_and_fetch_plugins()
    except Exception as e:
        cli_ui.print_generic_message(f"Login failed: {e}", is_error=True)

@auth_app.command()
def logout():
    """Remove the stored aye credentials."""
    commands.logout()
    cli_ui.print_generic_message("🔐 Token removed.")

@auth_app.command()
def status():
    """Show authentication status."""
    try:
        token = commands.get_auth_status_token()
        cli_ui.print_auth_status(token)
    except Exception as e:
        cli_ui.print_generic_message(f"Error checking auth status: {e}", is_error=True)

# ----------------------------------------------------------------------
# Chat (REPL) command
# ----------------------------------------------------------------------
@app.command()
def chat(
    root: Path = typer.Option(None, "--root", "-r", help="Root folder where source files are located."),
    file_mask: str = typer.Option(None, "--include", "-i", help="Include patterns for source files. Comma-separated globs."),
    ground_truth: str = typer.Option(None, "--ground-truth", "-g", hidden=True, help="Path to file containing custom system prompt"),
):
    """Start an interactive REPL."""
    # Centralized context and index preparation
    conf = commands.initialize_project_context(root, file_mask, ground_truth)
    repl.chat_repl(conf)

# ----------------------------------------------------------------------
# Snapshot commands
# ----------------------------------------------------------------------
snap_app = typer.Typer(help="Snapshot management commands")
app.add_typer(snap_app, name="snap")

@snap_app.command("history")
def history(file: Path = typer.Argument(None, help="File to list snapshots for")):
    """Show snapshot history for a file or all snapshots."""
    snapshots = commands.get_snapshot_history(file)
    cli_ui.print_snapshot_history(snapshots)

@snap_app.command("show")
def show_snap(file: Path = typer.Argument(..., help="File whose snapshot to show"), ordinal: str = typer.Argument(..., help="Snapshot ID (e.g., 001)")):
    """Print the contents of a specific snapshot."""
    content = commands.get_snapshot_content(file, ordinal)
    cli_ui.print_snapshot_content(content)

@snap_app.command("restore")
def restore(ordinal: str = typer.Argument(None, help="Snapshot ID to restore (default: latest)"), file_name: str = typer.Argument(None, help="Specific file to restore")):
    """Restore files from a snapshot."""
    try:
        commands.restore_from_snapshot(ordinal, file_name)
        cli_ui.print_restore_feedback(ordinal, file_name)

        # Persist a global flag so we stop showing the restore breadcrumb tip.
        # NOTE: tutorial restore does NOT hit this code path.
        set_user_config("has_used_restore", "on")
    except Exception as exc:
        cli_ui.print_generic_message(f"Error: {exc}", is_error=True)

@snap_app.command("keep")
def keep(num: int = typer.Option(10, "--num", "-n", help="Number of recent snapshots to keep")):
    """Delete all but the most recent N snapshots."""
    try:
        deleted_count = commands.prune_snapshots(num)
        cli_ui.print_prune_feedback(deleted_count, num)
    except Exception as e:
        cli_ui.print_generic_message(f"Error pruning snapshots: {e}", is_error=True)

@snap_app.command()
def cleanup(days: int = typer.Option(30, "--days", "-d", help="Delete snapshots older than N days")):
    """Delete snapshots older than N days."""
    try:
        deleted_count = commands.cleanup_old_snapshots(days)
        cli_ui.print_cleanup_feedback(deleted_count, days)
    except Exception as e:
        cli_ui.print_generic_message(f"Error cleaning up snapshots: {e}", is_error=True)

if __name__ == "__main__":
    app()
