"""ievo init — create a new iEvo project."""

from __future__ import annotations

from datetime import date
from pathlib import Path

import typer

from ievo.commands.init_templates import (
    ARCHITECT_WORKFLOW,
    CLAUDE_MD,
    CLAUDE_SETTINGS_LOCAL_JSON,
    CODER_AGENT_WORKFLOW,
    GITIGNORE,
    ISSUE_TEMPLATE_CHANGE,
    ISSUE_TEMPLATE_FEATURE,
    PRIORITY_MD,
    SPEC_CR_TEMPLATE,
    SPEC_INDEX_MD,
    SPEC_REQ_TEMPLATE,
    SPEC_WRITER_WORKFLOW,
)
from ievo.core.config import AGENTS_DIR, PLANS_DIR, SPEC_DIR, ensure_home
from ievo.core.project import ProjectManifest
from ievo.utils.console import error, info, step, success

# Directories that are expected to be empty at init time — need .gitkeep
_EMPTY_DIRS = {
    f"{SPEC_DIR}/requirements",
    f"{SPEC_DIR}/changes",
    f"{SPEC_DIR}/questions",
    PLANS_DIR,
    AGENTS_DIR,
}


def _write_if_missing(path: Path, content: str) -> bool:
    """Write file if it doesn't exist. Returns True if written."""
    if path.exists():
        return False
    path.write_text(content)
    return True


def init(
    name: str = typer.Argument(
        default=".",
        help="Project name or path. Use '.' for current directory.",
    ),
) -> None:
    """Create a new iEvo project with SDD structure."""
    if name == ".":
        root = Path.cwd()
        project_name = root.name
    else:
        root = Path.cwd() / name
        project_name = name

    # Check if already initialized
    if (root / "ievo.yaml").exists():
        error(f"Project already initialized in [bold]{root}[/bold]")
        raise typer.Exit(1)

    root.mkdir(parents=True, exist_ok=True)

    # ── Global ~/.ievo setup (keys, config) ──────────────────
    home = ensure_home()

    # GitHub auth (only on first init when ~/.ievo was just created)
    from ievo.core.global_config import get_config

    if get_config(home, "github_auth") is None:
        from ievo.core.github_auth import prompt_github_auth

        prompt_github_auth(home)

    info(f"Initializing [bold]{project_name}[/bold]...")

    # ── Directories ──────────────────────────────────────────
    dirs = [
        SPEC_DIR,
        f"{SPEC_DIR}/requirements",
        f"{SPEC_DIR}/changes",
        f"{SPEC_DIR}/questions",
        f"{SPEC_DIR}/templates",
        PLANS_DIR,
        AGENTS_DIR,
        ".github/workflows",
        ".github/ISSUE_TEMPLATE",
        ".claude/hooks",
    ]

    info("[bold]Directories[/bold]")
    for d in dirs:
        dir_path = root / d
        dir_path.mkdir(parents=True, exist_ok=True)
        step(d + "/")
        # Add .gitkeep to empty dirs
        if d in _EMPTY_DIRS:
            gitkeep = dir_path / ".gitkeep"
            if not gitkeep.exists():
                gitkeep.write_text("")

    # ── Project files ────────────────────────────────────────
    info("[bold]Project files[/bold]")

    manifest = ProjectManifest(
        project=project_name,
        version="0.1.0",
        created=str(date.today()),
    )
    manifest.save(root)
    step("ievo.yaml")

    if _write_if_missing(root / "CLAUDE.md", CLAUDE_MD.format(project_name=project_name)):
        step("CLAUDE.md")

    if _write_if_missing(root / "PRIORITY.md", PRIORITY_MD):
        step("PRIORITY.md")

    if _write_if_missing(root / ".gitignore", GITIGNORE):
        step(".gitignore")

    # ── Spec files ───────────────────────────────────────────
    info("[bold]Spec files[/bold]")

    if _write_if_missing(root / SPEC_DIR / "SPEC_INDEX.md", SPEC_INDEX_MD):
        step("spec/SPEC_INDEX.md")

    if _write_if_missing(root / SPEC_DIR / "templates" / "REQ_TEMPLATE.md", SPEC_REQ_TEMPLATE):
        step("spec/templates/REQ_TEMPLATE.md")

    if _write_if_missing(root / SPEC_DIR / "templates" / "CR_TEMPLATE.md", SPEC_CR_TEMPLATE):
        step("spec/templates/CR_TEMPLATE.md")

    # ── GitHub Actions ───────────────────────────────────────
    info("[bold]GitHub Actions[/bold]")

    wf_dir = root / ".github" / "workflows"
    if _write_if_missing(wf_dir / "spec-writer.yml", SPEC_WRITER_WORKFLOW):
        step(".github/workflows/spec-writer.yml")

    if _write_if_missing(wf_dir / "architect-agent.yml", ARCHITECT_WORKFLOW):
        step(".github/workflows/architect-agent.yml")

    if _write_if_missing(wf_dir / "coder-agent.yml", CODER_AGENT_WORKFLOW):
        step(".github/workflows/coder-agent.yml")

    # ── Issue templates ──────────────────────────────────────
    info("[bold]Issue templates[/bold]")

    it_dir = root / ".github" / "ISSUE_TEMPLATE"
    if _write_if_missing(it_dir / "feature.md", ISSUE_TEMPLATE_FEATURE):
        step(".github/ISSUE_TEMPLATE/feature.md")

    if _write_if_missing(it_dir / "change.md", ISSUE_TEMPLATE_CHANGE):
        step(".github/ISSUE_TEMPLATE/change.md")

    # ── Claude Code hooks ──────────────────────────────────────
    info("[bold]Claude Code hooks[/bold]")

    hook_source = Path(__file__).parent.parent / "hooks" / "precompact_save.py"
    hook_dest = root / ".claude" / "hooks" / "precompact_save.py"
    if _write_if_missing(hook_dest, hook_source.read_text()):
        step(".claude/hooks/precompact_save.py")

    settings_local = root / ".claude" / "settings.local.json"
    if _write_if_missing(settings_local, CLAUDE_SETTINGS_LOCAL_JSON):
        step(".claude/settings.local.json")

    # ── Done ─────────────────────────────────────────────────
    success(f"Project [bold]{project_name}[/bold] initialized.")
    info("Next: [bold]ievo add spec-writer architect coder[/bold]")
