from __future__ import annotations

import re
import shutil
from importlib.resources import files
from pathlib import Path
from typing import Any

import typer

skills_app = typer.Typer(help="Gerenciar skills do Aegro para AI assistants.")

SKILL_PREFIX = "aegro-"
TOOL_DIRS: dict[str, Path] = {
    "claude": Path.home() / ".claude" / "skills",
    "codex": Path.home() / ".codex" / "skills",
}


def _get_embedded_skills() -> dict[str, Any]:
    """Return dict of skill_name -> Traversable for all embedded skills."""
    skills_pkg = files("aegro").joinpath("_skills")
    result: dict[str, Any] = {}
    try:
        for item in skills_pkg.iterdir():
            if item.name.startswith(SKILL_PREFIX) and item.is_dir():
                skill_md = item.joinpath("SKILL.md")
                if skill_md.is_file():
                    result[item.name] = item
    except (FileNotFoundError, TypeError):
        pass
    return result


def _extract_version(content: str) -> str | None:
    """Extract version from YAML frontmatter."""
    match = re.search(r"^version:\s*(.+)$", content, re.MULTILINE)
    return match.group(1).strip() if match else None


def _get_target_dirs(tool: str) -> list[tuple[str, Path]]:
    """Get the skills directories for the given tool. Returns list of (name, path)."""
    if tool == "all":
        return list(TOOL_DIRS.items())
    target = TOOL_DIRS.get(tool)
    if target is None:
        typer.echo(
            f"Tool desconhecido: '{tool}'. Disponiveis: {', '.join(TOOL_DIRS.keys())}, all",
            err=True,
        )
        raise typer.Exit(1)
    return [(tool, target)]


@skills_app.command("list")
def list_skills() -> None:
    """Lista skills disponiveis no pacote.

    EXAMPLES:
      aegro skills list
    """
    embedded = _get_embedded_skills()
    if not embedded:
        typer.echo("Nenhuma skill encontrada no pacote.", err=True)
        raise typer.Exit(1)

    typer.echo(f"{len(embedded)} skills disponiveis:\n")
    for name in sorted(embedded):
        content = embedded[name].joinpath("SKILL.md").read_text(encoding="utf-8")
        version = _extract_version(content) or "?"
        desc_match = re.search(r"^description:\s*(.+)$", content, re.MULTILINE)
        desc = desc_match.group(1).strip() if desc_match else ""
        typer.echo(f"  {name} (v{version})")
        if desc:
            typer.echo(f"    {desc}")


@skills_app.command("status")
def status(
    tool: str = typer.Option("claude", "--tool", help="Tool alvo: claude, codex, all"),
) -> None:
    """Mostra skills instaladas vs disponiveis.

    EXAMPLES:
      aegro skills status
      aegro skills status --tool codex
    """
    targets = _get_target_dirs(tool)
    embedded = _get_embedded_skills()

    if not embedded:
        typer.echo("Nenhuma skill encontrada no pacote.", err=True)
        raise typer.Exit(1)

    for tool_name, target_dir in targets:
        typer.echo(f"Skills ({tool_name}) — diretorio: {target_dir}\n")
        for name in sorted(embedded):
            emb_content = embedded[name].joinpath("SKILL.md").read_text(encoding="utf-8")
            emb_version = _extract_version(emb_content) or "?"

            installed_md = target_dir / name / "SKILL.md"
            if installed_md.exists():
                inst_content = installed_md.read_text(encoding="utf-8")
                inst_version = _extract_version(inst_content) or "?"
                if emb_version == inst_version:
                    marker = "ok"
                else:
                    marker = f"update: {inst_version} -> {emb_version}"
            else:
                marker = "not installed"

            typer.echo(f"  {name}: {marker}")
        typer.echo()


@skills_app.command("install")
def install(
    name: str = typer.Argument(None, help="Nome da skill (ou omitir para instalar todas)."),
    tool: str = typer.Option("claude", "--tool", help="Tool alvo: claude, codex, all"),
    force: bool = typer.Option(False, "--force", help="Sobrescrever skills existentes."),
) -> None:
    """Instala skills do Aegro no diretorio do tool.

    EXAMPLES:
      aegro skills install
      aegro skills install aegro-visao-geral
      aegro skills install --tool codex
      aegro skills install --tool all
      aegro skills install --force
    """
    targets = _get_target_dirs(tool)
    embedded = _get_embedded_skills()

    if not embedded:
        typer.echo("Nenhuma skill encontrada no pacote.", err=True)
        raise typer.Exit(1)

    if name is not None:
        if name not in embedded:
            typer.echo(f"Skill '{name}' nao encontrada. Use 'aegro skills list'.", err=True)
            raise typer.Exit(1)
        to_install = {name: embedded[name]}
    else:
        to_install = embedded

    for tool_name, target_dir in targets:
        installed = 0
        skipped = 0
        for skill_name, skill_path in sorted(to_install.items()):
            dst = target_dir / skill_name
            if dst.exists() and not force:
                typer.echo(f"  {skill_name}: ja existe (use --force para sobrescrever)")
                skipped += 1
                continue

            dst.mkdir(parents=True, exist_ok=True)
            content = skill_path.joinpath("SKILL.md").read_text(encoding="utf-8")
            (dst / "SKILL.md").write_text(content, encoding="utf-8")
            typer.echo(f"  {skill_name}: instalada")
            installed += 1

        typer.echo(
            f"\n{tool_name}: {installed} instalada(s), {skipped} ja existente(s) em {target_dir}"
        )


@skills_app.command("uninstall")
def uninstall(
    name: str = typer.Argument(None, help="Nome da skill (ou omitir para remover todas)."),
    tool: str = typer.Option("claude", "--tool", help="Tool alvo: claude, codex, all"),
) -> None:
    """Remove skills do Aegro do diretorio do tool.

    EXAMPLES:
      aegro skills uninstall
      aegro skills uninstall aegro-visao-geral
      aegro skills uninstall --tool all
    """
    tool_targets = _get_target_dirs(tool)
    embedded = _get_embedded_skills()

    if name is not None:
        if name not in embedded:
            typer.echo(f"Skill '{name}' nao encontrada. Use 'aegro skills list'.", err=True)
            raise typer.Exit(1)
        skill_names = [name]
    else:
        skill_names = sorted(embedded.keys())

    for tool_name, target_dir in tool_targets:
        count = 0
        for skill_name in skill_names:
            dst = target_dir / skill_name
            if dst.exists():
                shutil.rmtree(dst)
                typer.echo(f"  {skill_name}: removida")
                count += 1

        if count == 0:
            typer.echo(f"{tool_name}: nenhuma skill aegro instalada.")
        else:
            typer.echo(f"\n{tool_name}: {count} skill(s) removida(s).")
