"""CLI entry point for reddit-mcp."""

from __future__ import annotations

import asyncio
import os
import subprocess
import sys
from pathlib import Path

from fivemghost_shared_client import TokenManager, run_oauth_flow
from fivemghost_shared_client.config_helpers import AUTH_URL, SHARED_AUTH_JSON
from fivemghost_shared_client.launcher import write_uvx_launcher
from fivemghost_shared_client.registration import install_skills, register_all
from fivemghost_shared_client.registration.openclaw import get_openclaw_config_path

from . import __version__
from .config import CONFIG_DIR, ENV_TOKEN

PACKAGE_NAME = "5mghost-rover"
EXECUTABLE_NAME = "reddit-mcp"
SKILL_NAME = "use-reddit-mcp"


def main() -> None:
    """Main CLI dispatcher."""
    args = sys.argv[1:]
    if not args or args[0] in {"help", "--help", "-h"} or any(arg in {"--help", "-h"} for arg in args[1:]):
        _print_help()
        return
    command = args[0] if args else "help"

    match command:
        case "serve":
            _cmd_serve()
        case "setup":
            _cmd_setup()
        case "setup-cookies":
            _cmd_setup_cookies()
        case "update":
            _cmd_update()
        case "install-skills":
            _cmd_install_skills()
        case "check":
            _cmd_check()
        case "uninstall":
            _cmd_uninstall()
        case "version" | "--version" | "-v":
            print(f"reddit-mcp {__version__}")
        case _:
            _print_help()


def _cmd_serve() -> None:
    """Start the MCP server (stdio transport)."""
    from .server import init_server, mcp

    asyncio.run(init_server())
    mcp.run()


def _cmd_setup() -> None:
    """Full setup: OAuth login + cookie setup."""
    asyncio.run(_async_setup())


async def _async_setup() -> None:
    from .cookie_manager import setup_cookies

    tm = TokenManager(AUTH_URL, auth_json_path=SHARED_AUTH_JSON, env_token_name=ENV_TOKEN)

    # Check if already authenticated
    token = await tm.get_valid_token()
    if token:
        print(f"✅ Shared auth already configured: {SHARED_AUTH_JSON}")
    else:
        print("🔑 Starting OAuth login flow...\n")
        try:
            tokens = await run_oauth_flow(AUTH_URL, client_name="reddit-mcp-cli")
            await tm.save_tokens(
                access_token=tokens["access_token"],
                refresh_token=tokens["refresh_token"],
                expires_in=tokens["expires_in"],
                client_id=tokens.get("client_id"),
            )
            print(f"✅ Auth tokens saved to shared auth: {SHARED_AUTH_JSON}\n")
            print("ℹ️  Other first-party local MCPs on this machine can reuse this login.\n")
        except Exception as e:
            print(f"❌ OAuth login failed: {e}")
            sys.exit(1)

    # Cookie setup
    print("🍪 Setting up Reddit cookies...\n")
    try:
        await setup_cookies()
    except Exception as e:
        print(f"❌ Cookie setup failed: {e}")
        sys.exit(1)

    # Launcher generation
    launcher_path = write_uvx_launcher(
        package_name=PACKAGE_NAME,
        executable_name=EXECUTABLE_NAME,
        config_dir=CONFIG_DIR,
    )
    print(f"\n📦 Launcher written to {launcher_path}")

    register_all(
        server_name=EXECUTABLE_NAME,
        runtime="python3",
        launcher_path=launcher_path,
    )
    _print_manual_configs(str(launcher_path))
    _install_bundled_skills()

    print("\n🎉 Setup complete! You can now use reddit-mcp.")


def _print_manual_configs(launcher: str) -> None:
    """Print manual MCP config snippets for clients without auto-registration."""
    print("\n📋 Manual MCP config (for Cursor, Windsurf, etc.):")
    print(f'''{{
  "mcpServers": {{
    "reddit-mcp": {{
      "command": "python3",
      "args": ["{launcher}", "serve"]
    }}
  }}
}}''')
    print(f"\n📋 Direct uvx config:")
    print(f'''{{
  "mcpServers": {{
    "{EXECUTABLE_NAME}": {{
      "command": "uvx",
      "args": ["--from", "{PACKAGE_NAME}", "{EXECUTABLE_NAME}", "serve"]
    }}
  }}
}}''')
    print(f"\n📋 OpenClaw config path: {get_openclaw_config_path()}")
    print(f'''{{
  "servers": {{
    "{EXECUTABLE_NAME}": {{
      "transport": "stdio",
      "command": "python3",
      "args": ["{launcher}", "serve"]
    }}
  }}
}}''')


def _install_bundled_skills() -> None:
    """Install bundled skill to detected AI clients."""
    skill_source = Path(__file__).resolve().parent / "skills" / SKILL_NAME
    include_openclaw = os.environ.get("REDDIT_MCP_INSTALL_OPENCLAW_SKILL") == "1"

    print("\n🧠 Installing bundled skill...")
    install_skills(
        skill_name=SKILL_NAME,
        source_dir=skill_source,
        include_openclaw=include_openclaw,
    )


def _cmd_setup_cookies() -> None:
    """Cookie-only setup (for users who already have a PAT)."""
    asyncio.run(_async_setup_cookies())


async def _async_setup_cookies() -> None:
    from .cookie_manager import setup_cookies

    print("🍪 Setting up Reddit cookies...\n")
    try:
        await setup_cookies()
    except Exception as e:
        print(f"❌ Cookie setup failed: {e}")
        sys.exit(1)

    print("\n✅ Cookies saved! Restart your MCP client to start using reddit-mcp.")


def _cmd_update() -> None:
    """Check for updates and install latest version from PyPI."""
    print(f"Current version: {__version__}")
    print("Checking for updates...\n")

    try:
        result = subprocess.run(
            [sys.executable, "-m", "pip", "index", "versions", "5mghost-rover"],
            capture_output=True, text=True, timeout=15,
        )
        # pip index versions output: "5mghost-rover (x.y.z)"
        if result.returncode != 0:
            # Fallback: try pip install --dry-run
            result = subprocess.run(
                [sys.executable, "-m", "pip", "install", "--dry-run", "5mghost-rover==99999"],
                capture_output=True, text=True, timeout=15,
            )
            # Error message lists available versions
            import re
            m = re.search(r"from versions: (.+?)\)", result.stderr)
            if m:
                versions = [v.strip() for v in m.group(1).split(",")]
                latest = versions[-1] if versions else __version__
            else:
                print("❌ Could not determine latest version.")
                print("Try manually: pip install --upgrade 5mghost-rover")
                sys.exit(1)
        else:
            import re
            m = re.search(r"5mghost.rover \((.+?)\)", result.stdout)
            latest = m.group(1) if m else __version__

        if latest == __version__:
            print(f"✅ Already on the latest version ({__version__})")
        else:
            print(f"New version available: {latest}")
            print("Updating...\n")
            subprocess.run(
                [sys.executable, "-m", "pip", "install", "--upgrade", "5mghost-rover"],
                check=True,
            )
            print(f"\n✅ Updated to {latest}")
        _install_bundled_skills()

    except subprocess.TimeoutExpired:
        print("❌ Timed out checking for updates.")
        print("Try manually: pip install --upgrade 5mghost-rover")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Update failed: {e}")
        print("Try manually: pip install --upgrade 5mghost-rover")
        sys.exit(1)


def _cmd_install_skills() -> None:
    """Install or refresh bundled reddit-mcp skill in detected AI clients."""
    _install_bundled_skills()


def _cmd_check() -> None:
    """Check auth and cookie status."""
    asyncio.run(_async_check())


def _cmd_uninstall() -> None:
    """Remove local config and MCP registrations."""
    from .uninstall import run_uninstall

    run_uninstall()


async def _async_check() -> None:
    from .cookie_manager import (
        check_cookies_valid,
        cookies_age_warning,
        get_cookie_age_days,
        get_session_expiry_days,
        load_cookies,
    )

    print(f"reddit-mcp {__version__}\n")

    # Token check
    tm = TokenManager(AUTH_URL, auth_json_path=SHARED_AUTH_JSON, env_token_name=ENV_TOKEN)
    token = await tm.get_valid_token()
    if token:
        masked = token[:8] + "..." if len(token) > 8 else "***"
        print(f"🔑 Shared auth: ✅ present ({masked})")
        print(f"   Path: {SHARED_AUTH_JSON}")

        # Server-side verification
        verify = await tm.verify_token_with_server(token)
        if verify.get("active"):
            print("🔐 Server verification: ✅ active")
        else:
            error = verify.get("error")
            if error:
                print(f"🔐 Server verification: ❌ {error}")
            else:
                print("🔐 Server verification: ❌ token invalid or revoked")
            print("   Run `reddit-mcp setup` to re-authenticate.")
    else:
        print("🔑 Shared auth: ❌ not configured")
        print(f"   Path: {SHARED_AUTH_JSON}")
        print("   Run `reddit-mcp setup` or set REDDIT_MCP_TOKEN env var")

    # Cookie check
    cookies = load_cookies()
    if not cookies:
        print("🍪 Cookies: ❌ not found")
        print("   Run `reddit-mcp setup-cookies`")
        return

    age = get_cookie_age_days()
    age_str = f" ({age:.0f} days old)" if age else ""
    remaining = get_session_expiry_days()
    expiry_str = f", expires in {remaining:.0f} days" if remaining and remaining > 0 else ""
    valid = await check_cookies_valid(cookies)
    if valid:
        print(f"🍪 Cookies: ✅ valid{age_str}{expiry_str}")
    else:
        print(f"🍪 Cookies: ❌ expired or invalid{age_str}")
        print("   Run `reddit-mcp setup-cookies` to refresh")

    warning = cookies_age_warning()
    if warning:
        print(f"\n{warning}")


def _print_help() -> None:
    print(f"""reddit-mcp {__version__} — Reddit MCP server

Usage:
  reddit-mcp serve           Start MCP server (stdio)
  reddit-mcp setup           Full setup: OAuth login + Reddit cookies
  reddit-mcp setup-cookies   Cookie-only setup (if you already have a PAT)
  reddit-mcp uninstall       Remove MCP registrations and local config
  reddit-mcp update          Check for updates and install latest version
  reddit-mcp install-skills  Install/refresh bundled reddit-mcp skill
  reddit-mcp check           Check token & cookie status
  reddit-mcp version         Show version

Quick start:
  1. uvx --from {PACKAGE_NAME} {EXECUTABLE_NAME} setup   # Login once on this machine & get cookies
  2. Direct run: uvx --from {PACKAGE_NAME} {EXECUTABLE_NAME} serve
  3. Configure in your AI client:
     "command": "uvx", "args": ["--from", "{PACKAGE_NAME}", "{EXECUTABLE_NAME}", "serve"]
""")


if __name__ == "__main__":
    main()
