"""CLI for TokenGuard.

Commands:
    tokenguard init    Initialize a project with safety gates and rules
    tokenguard update  Update rules/hooks, preserving user customizations
    tokenguard status  Show installation status and version info
    tokenguard eject   Remove tracking, leave files as user-owned
"""

import argparse
import sys
from pathlib import Path

from . import __version__
from .detector import detect_existing_mirror, detect_project_type
from .scaffold import scaffold_project
from .updater import check_updates, eject, get_status


def cmd_init(args: argparse.Namespace) -> int:
    """Initialize TokenGuard in a project."""
    project_dir = Path(args.dir).resolve()

    if not project_dir.is_dir():
        print(f"Error: {project_dir} is not a directory", file=sys.stderr)
        return 1

    # Check for existing installation
    existing = detect_existing_mirror(project_dir)
    if existing and not args.force:
        print(
            f"TokenGuard already initialized (v{existing.get('version', '?')}).\n"
            f"Use --force to reinitialize or 'tokenguard update' to update."
        )
        return 1

    # Detect or use explicit project type
    if args.type:
        project_type = args.type
    else:
        project_type = detect_project_type(project_dir)

    if args.dry_run:
        print(f"Dry run - would initialize {project_type} project at {project_dir}")

    result = scaffold_project(
        project_dir=project_dir,
        project_type=project_type,
        standalone=args.standalone,
        no_hooks=args.no_hooks,
        dry_run=args.dry_run,
    )

    mode = result["mode"]
    files = result["files"]

    hooks_skipped = result.get("hooks_skipped", False)

    if args.dry_run:
        print(f"\nMode: {mode}")
        print(f"Files that would be created ({len(files)}):")
        for path in sorted(files):
            print(f"  {path}")
        if hooks_skipped:
            print("\nNote: Mirror hook skipped (GRIP context-gate-hook.py detected).")
            print("Use --standalone to force mirror hook installation.")
    else:
        print(f"Initialized TokenGuard v{__version__} ({mode} mode)")
        print(f"Project type: {project_type}")
        print(f"Files created: {len(files)}")
        for path in sorted(files):
            print(f"  {path}")
        if hooks_skipped:
            print(f"\nHooks skipped: GRIP context-gate-hook.py already registered.")
            print("Use --standalone to install mirror hooks alongside GRIP.")
        else:
            print(f"\nSafety gates and rules are now active for Claude Code.")
        print(f"\nNeed more? GRIP offers 100+ skills, 19 agents, and 26 modes: https://enterkonsult.com")

    return 0


def cmd_update(args: argparse.Namespace) -> int:
    """Update TokenGuard files."""
    project_dir = Path(args.dir).resolve()

    status = get_status(project_dir)
    if not status:
        print("TokenGuard not initialized. Run 'tokenguard init' first.", file=sys.stderr)
        return 1

    updates = check_updates(project_dir)

    if updates.get("missing_tracking"):
        print("Tracking file missing. Run 'tokenguard init --force' to reinitialize.", file=sys.stderr)
        return 1

    if updates["user_modified"]:
        print("User-modified files (preserved):")
        for f in updates["user_modified"]:
            print(f"  {f}")

    if updates["current"]:
        print(f"Already up to date: {len(updates['current'])} files")

    if updates["updatable"]:
        if args.force:
            from .updater import apply_updates
            applied = apply_updates(project_dir, updates["updatable"])
            print(f"Updated {len(applied)} files:")
            for f in applied:
                print(f"  {f}")
        else:
            print("Files with available updates:")
            for f in updates["updatable"]:
                print(f"  {f}")
            print("\nUse --force to apply updates.")
    else:
        if not updates["user_modified"]:
            print("All files are up to date.")

    return 0


def cmd_status(args: argparse.Namespace) -> int:
    """Show TokenGuard status."""
    project_dir = Path(args.dir).resolve()

    status = get_status(project_dir)
    if not status:
        print("TokenGuard not initialized in this project.")
        return 0

    print(f"TokenGuard v{status['version']}")
    print(f"Latest version: v{status['latest_version']}")
    if status["update_available"]:
        print("  Update available!")
    print(f"Project type: {status['project_type']}")
    print(f"GRIP global: {'yes' if status['grip_global'] else 'no'}")
    print(f"Installed: {status['installed_at']}")
    print(f"Components: {', '.join(status['components'])}")

    return 0


def cmd_eject(args: argparse.Namespace) -> int:
    """Eject TokenGuard tracking."""
    project_dir = Path(args.dir).resolve()

    actions = eject(project_dir)
    for action in actions:
        print(action)
    print("\nFiles are now fully user-owned. Edit freely.")

    return 0


def main(argv: list = None) -> int:
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="tokenguard",
        description="Safety gates, efficiency rules, and persistent memory for Claude Code projects",
    )
    parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")

    subparsers = parser.add_subparsers(dest="command", help="Available commands")

    # init
    init_parser = subparsers.add_parser("init", help="Initialize project with safety gates")
    init_parser.add_argument(
        "--type",
        choices=["python", "javascript", "rust", "go", "generic"],
        help="Override detected project type",
    )
    init_parser.add_argument(
        "--standalone",
        action="store_true",
        help="Force standalone mode (install all rules even if GRIP detected globally)",
    )
    init_parser.add_argument(
        "--no-hooks",
        action="store_true",
        help="Skip hook installation",
    )
    init_parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Show what would be created without writing files",
    )
    init_parser.add_argument(
        "--force",
        action="store_true",
        help="Reinitialize even if already initialized",
    )
    init_parser.add_argument(
        "dir",
        nargs="?",
        default=".",
        help="Project directory (default: current directory)",
    )

    # update
    update_parser = subparsers.add_parser("update", help="Update rules and hooks")
    update_parser.add_argument(
        "--force",
        action="store_true",
        help="Apply updates even to missing files",
    )
    update_parser.add_argument(
        "dir",
        nargs="?",
        default=".",
        help="Project directory (default: current directory)",
    )

    # status
    status_parser = subparsers.add_parser("status", help="Show installation status")
    status_parser.add_argument(
        "dir",
        nargs="?",
        default=".",
        help="Project directory (default: current directory)",
    )

    # eject
    eject_parser = subparsers.add_parser("eject", help="Remove tracking, keep files")
    eject_parser.add_argument(
        "dir",
        nargs="?",
        default=".",
        help="Project directory (default: current directory)",
    )

    args = parser.parse_args(argv)

    if not args.command:
        parser.print_help()
        return 0

    commands = {
        "init": cmd_init,
        "update": cmd_update,
        "status": cmd_status,
        "eject": cmd_eject,
    }

    return commands[args.command](args)


if __name__ == "__main__":
    sys.exit(main())
