"""Install OpenCode commands, workflows, and all GSD resources.

Copies bundled resources to ~/.config/opencode/ for global access.

Requirements: GLOB-03 (OpenCode command files), GLOB-04 (bundled workflows)
"""

from __future__ import annotations

from importlib.resources import files
from pathlib import Path
from typing import Optional
import re

import typer


RESOURCE_TYPES = [
    ("commands", "commands/gsd-rlm", ["md"], False),
    ("workflows", "gsd-rlm/workflows", ["md"], False),
    ("references", "gsd-rlm/references", ["md"], False),
    ("templates", "gsd-rlm/templates", ["md", "json"], False),
    ("agents", "gsd-rlm/agents", ["md"], False),
    ("bin", "gsd-rlm/bin", ["cjs"], True),
]

PATH_REPLACEMENTS = [
    (r"~\\\.config\\opencode\\get-shit-done", "~/.config/opencode/gsd-rlm"),
    (r"~/.config/opencode/get-shit-done", "~/.config/opencode/gsd-rlm"),
]


def install_commands(
    opencode_dir: Optional[Path] = typer.Option(
        None,
        "--opencode-dir",
        "-o",
        help="Custom OpenCode config directory (default: ~/.config/opencode/)",
    ),
    force: bool = typer.Option(False, "--force", "-f", help="Overwrite existing files"),
) -> None:
    """Install all GSD-RLM resources to ~/.config/opencode/.

    Installs:
    - Commands to ~/.config/opencode/commands/gsd-rlm/
    - Workflows to ~/.config/opencode/gsd-rlm/workflows/
    - References to ~/.config/opencode/gsd-rlm/references/
    - Templates to ~/.config/opencode/gsd-rlm/templates/
    - Agents to ~/.config/opencode/gsd-rlm/agents/
    - Bin (gsd-tools.cjs) to ~/.config/opencode/gsd-rlm/bin/
    """
    if opencode_dir is None:
        opencode_dir = Path.home() / ".config" / "opencode"

    if not opencode_dir.exists():
        typer.secho(
            f"Error: OpenCode directory not found: {opencode_dir}", fg=typer.colors.RED
        )
        typer.echo("Please install OpenCode first: https://opencode.ai")
        raise typer.Exit(1)

    total_installed = 0

    for src_name, dest_rel, extensions, recursive in RESOURCE_TYPES:
        dest_dir = opencode_dir / dest_rel
        dest_dir.mkdir(parents=True, exist_ok=True)
        installed = _install_resources(src_name, dest_dir, force, extensions, recursive)
        total_installed += len(installed)

    typer.secho("\n[OK] Installation complete!", fg=typer.colors.GREEN, bold=True)
    typer.echo(f"\nTotal files installed: {total_installed}")

    commands_dir = opencode_dir / "commands" / "gsd-rlm"
    if commands_dir.exists():
        cmds = list(commands_dir.glob("*.md"))
        if cmds:
            typer.echo(f"\nAvailable commands ({len(cmds)}):")
            for cmd in sorted(cmds):
                typer.echo(f"  /{cmd.stem}")


def _install_resources(
    resource_type: str,
    target_dir: Path,
    force: bool,
    extensions: list[str],
    recursive: bool = False,
) -> list[str]:
    """Install bundled resources of a given type."""
    installed = []

    try:
        bundled = files("gsd_rlm.bundled").joinpath(resource_type)

        for resource in bundled.iterdir():
            if resource.name in [".gitkeep", "__init__.py"]:
                continue

            if resource.is_dir() and recursive:
                sub_dir = target_dir / resource.name
                sub_dir.mkdir(parents=True, exist_ok=True)
                sub_bundled = files("gsd_rlm.bundled").joinpath(
                    resource_type, resource.name
                )
                for sub_resource in sub_bundled.iterdir():
                    if sub_resource.name in [".gitkeep", "__init__.py"]:
                        continue
                    ext = (
                        sub_resource.name.split(".")[-1]
                        if "." in sub_resource.name
                        else ""
                    )
                    if ext not in extensions:
                        continue
                    sub_target = sub_dir / sub_resource.name
                    if sub_target.exists() and not force:
                        continue
                    content = sub_resource.read_text(encoding="utf-8")
                    sub_target.write_text(content, encoding="utf-8")
                    installed.append(f"{resource.name}/{sub_resource.name}")
                continue

            ext = resource.name.split(".")[-1] if "." in resource.name else ""
            if ext not in extensions:
                continue

            target = target_dir / resource.name

            if target.exists() and not force:
                continue

            content = resource.read_text(encoding="utf-8")

            if resource.name.endswith(".md"):
                content = _update_paths(content)

            target.write_text(content, encoding="utf-8")
            installed.append(resource.name)

        if installed:
            typer.secho(
                f"  {resource_type}: {len(installed)} files", fg=typer.colors.CYAN
            )

    except Exception as e:
        typer.secho(
            f"Warning: Could not install {resource_type}: {e}", fg=typer.colors.YELLOW
        )

    return installed


def _update_paths(content: str) -> str:
    """Update paths in content from get-shit-done to gsd-rlm."""
    for pattern, replacement in PATH_REPLACEMENTS:
        content = re.sub(pattern, replacement, content)
    return content
