"""Setup command for complete GSD-RLM environment configuration.

Checks and installs all dependencies for GSD-RLM to work.

Requirements: SETUP-01 (Python check), SETUP-02 (OpenCode check),
              SETUP-03 (install-commands), SETUP-04 (status report)
"""

from __future__ import annotations

import platform
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Optional

import typer

from gsd_rlm.cli.install import install_commands


# Minimum Python version
MIN_PYTHON_VERSION = (3, 10)

# OpenCode package name in npm
OPENCODE_NPM_PACKAGE = "opencode-ai"


def setup(
    skip_opencode: bool = typer.Option(
        False, "--skip-opencode", help="Skip OpenCode installation (CLI-only mode)"
    ),
    opencode_dir: Optional[Path] = typer.Option(
        None, "--opencode-dir", "-o", help="Custom OpenCode config directory"
    ),
) -> None:
    """Set up GSD-RLM environment with all dependencies.

    This command:
    1. Checks Python version (3.10+ required)
    2. Checks and optionally installs OpenCode
    3. Installs GSD-RLM commands for OpenCode
    4. Shows final status
    """
    typer.secho("\n=== GSD-RLM Setup ===\n", fg=typer.colors.CYAN, bold=True)

    results = []

    # Step 1: Check Python version
    python_ok = _check_python()
    results.append(("Python 3.10+", python_ok))

    if not python_ok:
        typer.secho("\n[ERROR] Python 3.10+ is required!", fg=typer.colors.RED)
        typer.echo(
            f"  Current version: {sys.version_info.major}.{sys.version_info.minor}"
        )
        typer.echo("  Download from: https://python.org/downloads/")
        raise typer.Exit(1)

    # Step 2: Check npm (needed for OpenCode)
    npm_ok = _check_npm()
    results.append(("npm (for OpenCode)", npm_ok))

    if not npm_ok and not skip_opencode:
        typer.secho("\n[WARNING] npm not found!", fg=typer.colors.YELLOW)
        typer.echo("  OpenCode requires Node.js/npm to install.")
        typer.echo("  Download from: https://nodejs.org/")
        typer.echo("  Or use --skip-opencode to skip OpenCode installation.")

    # Step 3: Check/install OpenCode
    if skip_opencode:
        results.append(("OpenCode", "skipped"))
        typer.echo("\n[SKIP] OpenCode installation (--skip-opencode)")
    elif not npm_ok:
        results.append(("OpenCode", "skipped (no npm)"))
        typer.echo("\n[SKIP] OpenCode installation (npm not available)")
    else:
        opencode_ok = _setup_opencode()
        results.append(("OpenCode", opencode_ok))

    # Step 4: Install GSD-RLM commands
    if skip_opencode:
        results.append(("GSD-RLM Commands", "skipped"))
    elif not npm_ok:
        results.append(("GSD-RLM Commands", "skipped"))
    else:
        typer.echo("\n[SETUP] Installing GSD-RLM commands...")
        try:
            # Call install_commands directly
            install_commands(opencode_dir=opencode_dir, force=True)
            results.append(("GSD-RLM Commands", True))
        except Exception as e:
            typer.secho(f"  [ERROR] {e}", fg=typer.colors.RED)
            results.append(("GSD-RLM Commands", False))

    # Step 5: Show summary
    _show_summary(results)


def _check_python() -> bool:
    """Check if Python version is 3.10 or higher."""
    typer.echo("[CHECK] Python version...")
    version = sys.version_info

    if version.major >= 3 and version.minor >= 10:
        typer.secho(
            f"  [OK] Python {version.major}.{version.minor}.{version.micro}",
            fg=typer.colors.GREEN,
        )
        return True
    else:
        typer.secho(
            f"  [FAIL] Python {version.major}.{version.minor}.{version.micro} (need 3.10+)",
            fg=typer.colors.RED,
        )
        return False


def _check_npm() -> bool:
    """Check if npm is available."""
    typer.echo("[CHECK] npm availability...")

    npm_path = shutil.which("npm")
    if npm_path:
        typer.secho(f"  [OK] npm found at {npm_path}", fg=typer.colors.GREEN)
        return True
    else:
        typer.secho("  [FAIL] npm not found in PATH", fg=typer.colors.YELLOW)
        return False


def _check_opencode() -> bool:
    """Check if OpenCode is installed."""
    opencode_path = shutil.which("opencode")
    return opencode_path is not None


def _setup_opencode() -> bool:
    """Check and install OpenCode if needed."""
    typer.echo("[CHECK] OpenCode installation...")

    if _check_opencode():
        opencode_path = shutil.which("opencode")
        typer.secho(f"  [OK] OpenCode found at {opencode_path}", fg=typer.colors.GREEN)
        return True

    # OpenCode not found, try to install
    typer.echo("  [INSTALL] OpenCode not found, installing via npm...")

    try:
        result = subprocess.run(
            ["npm", "install", "-g", OPENCODE_NPM_PACKAGE],
            capture_output=True,
            text=True,
            timeout=120,  # 2 minute timeout
        )

        if result.returncode == 0:
            typer.secho(
                "  [OK] OpenCode installed successfully!", fg=typer.colors.GREEN
            )
            return True
        else:
            typer.secho(
                f"  [FAIL] npm install failed: {result.stderr}", fg=typer.colors.RED
            )
            typer.echo("  Try manually: npm install -g opencode-ai")
            return False

    except subprocess.TimeoutExpired:
        typer.secho("  [FAIL] Installation timed out", fg=typer.colors.RED)
        return False
    except FileNotFoundError:
        typer.secho("  [FAIL] npm not found", fg=typer.colors.RED)
        return False
    except Exception as e:
        typer.secho(f"  [FAIL] Unexpected error: {e}", fg=typer.colors.RED)
        return False


def _show_summary(results: list) -> None:
    """Show setup summary."""
    typer.secho("\n=== Setup Summary ===\n", fg=typer.colors.CYAN, bold=True)

    all_ok = True

    for name, status in results:
        if status is True:
            typer.echo(f"  [OK] {name}")
        elif status is False:
            typer.secho(f"  [FAIL] {name}", fg=typer.colors.RED)
            all_ok = False
        else:
            typer.secho(f"  [SKIP] {name}", fg=typer.colors.YELLOW)

    typer.echo("")

    if all_ok:
        typer.secho("=== Setup Complete! ===", fg=typer.colors.GREEN, bold=True)
        typer.echo("\nYou can now use:")
        typer.echo("  gsd-rlm init          - Initialize a new project")
        typer.echo("  gsd-rlm status        - Show project status")
        typer.echo("  gsd-rlm version       - Show version info")
        typer.echo("\nIn OpenCode:")
        typer.echo("  /gsd-rlm-new-project  - Initialize via OpenCode")
        typer.echo("  /gsd-rlm-plan-phase   - Plan a phase")
        typer.echo("  /gsd-rlm-execute-phase - Execute a phase")
    else:
        typer.secho("=== Setup Incomplete ===", fg=typer.colors.YELLOW, bold=True)
        typer.echo("\nSome components failed to install.")
        typer.echo("Check the errors above and try manual installation.")
