"""Project initialization — scaffolds .memory/ directory."""

from __future__ import annotations

import shutil
from pathlib import Path

import yaml

from supermemory.config import detect_project_name


MEMORY_DIRS = ["systems", "decisions", "gotchas", "research", "people", "sessions", "scratch"]
GITIGNORE_ENTRIES = ["sessions/", "scratch/", ".me", ".obsidian/"]

TEMPLATE_MAP = {
    "systems": "system.md",
    "decisions": "decision.md",
    "gotchas": "gotcha.md",
    "research": "research.md",
    "people": "person.md",
    "sessions": "session.md",
}


_PACKAGE_DIR = Path(__file__).parent


def _read_template(name: str) -> str:
    """Read a template file bundled with the package."""
    return (_PACKAGE_DIR / "templates" / name).read_text()


def init_project(
    project: str | None = None,
    me: str | None = None,
    platform: str | None = None,
    tracker: str | None = None,
    obsidian: bool = False,
    auto_discover: bool = False,
    base: Path | None = None,
) -> Path:
    """Initialize .memory/ in the given base directory.

    Returns the .memory/ root path.
    """
    base = base or Path.cwd()
    root = base / ".memory"

    # 1. Create directories
    for d in MEMORY_DIRS:
        (root / d).mkdir(parents=True, exist_ok=True)

    # 2. Write config.yaml
    project_name = project or detect_project_name()
    config_text = _read_template("config.yaml").replace("{project_name}", project_name)
    config = yaml.safe_load(config_text)

    # Apply options to config
    if me:
        config.setdefault("team", {}).setdefault("members", [])
        config["team"]["members"].append({"id": me, "role": "", "areas": []})

    if tracker and tracker != "none":
        config.setdefault("integrations", {})[tracker] = True

    if platform and platform != "none":
        platform_key = platform.replace("-", "_")
        config.setdefault("integrations", {})[platform_key] = True

    if obsidian:
        config.setdefault("integrations", {})["obsidian"] = True

    config.setdefault("systems", {})["auto_discover"] = auto_discover

    with open(root / "config.yaml", "w") as f:
        yaml.dump(config, f, default_flow_style=False, sort_keys=False)

    # 3. Write AGENT_PROTOCOL.md
    (root / "AGENT_PROTOCOL.md").write_text(_read_template("AGENT_PROTOCOL.md"))

    # 4. Write _template.md into each subdirectory
    for dirname, template_name in TEMPLATE_MAP.items():
        dest = root / dirname / "_template.md"
        dest.write_text(_read_template(template_name))

    # 5. Write .me
    if me:
        (root / ".me").write_text(me + "\n")

    # 6. Create person file for me
    if me:
        person_content = _read_template("person.md")
        person_content = person_content.replace("{name}", me)
        (root / "people" / f"{me}.md").write_text(person_content)

    # 7. Write .gitignore
    gitignore_path = root / ".gitignore"
    existing = gitignore_path.read_text() if gitignore_path.exists() else ""
    entries_to_add = [e for e in GITIGNORE_ENTRIES if e not in existing]
    if entries_to_add:
        with open(gitignore_path, "a") as f:
            if existing and not existing.endswith("\n"):
                f.write("\n")
            f.write("\n".join(entries_to_add) + "\n")

    # 8. Write SUMMARY.md
    summary_text = _read_template("SUMMARY.md").replace("{project_name}", project_name)
    (root / "SUMMARY.md").write_text(summary_text)

    # Platform hooks
    if platform == "claude-code":
        _setup_claude_code(base)
    elif platform == "cursor":
        _setup_cursor(base, root)
    elif platform == "aider":
        _setup_aider(base)

    # Obsidian
    if obsidian:
        _setup_obsidian(root)

    # Auto-discover
    if auto_discover:
        from supermemory.discover import discover_systems

        discover_systems(root, base)

    return root


def _setup_claude_code(base: Path) -> None:
    """Append memory protocol reference to CLAUDE.md."""
    claude_md = base / "CLAUDE.md"
    marker = "## Project Memory"
    existing = claude_md.read_text() if claude_md.exists() else ""
    if marker in existing:
        return
    block = (
        "\n\n## Project Memory\n\n"
        "This project uses Super Memory (`.memory/`) for persistent shared knowledge.\n"
        "Read `.memory/AGENT_PROTOCOL.md` for the full protocol.\n\n"
        "On session start: read your person file and relevant system docs.\n"
        "On session end: update person file, write session summary, promote scratch.\n"
    )
    with open(claude_md, "a") as f:
        f.write(block)


def _setup_cursor(base: Path, root: Path) -> None:
    """Append agent protocol to .cursorrules."""
    cursorrules = base / ".cursorrules"
    marker = "# Super Memory"
    existing = cursorrules.read_text() if cursorrules.exists() else ""
    if marker in existing:
        return
    protocol = (root / "AGENT_PROTOCOL.md").read_text()
    with open(cursorrules, "a") as f:
        f.write("\n\n" + protocol)


def _setup_aider(base: Path) -> None:
    """Generate .aider.conf.yml referencing memory."""
    conf = base / ".aider.conf.yml"
    if conf.exists():
        return
    conf.write_text(
        "read:\n"
        "  - .memory/AGENT_PROTOCOL.md\n"
        "  - .memory/people/.me\n"
    )


def _setup_obsidian(root: Path) -> None:
    """Create .obsidian/ config directory."""
    obsidian_dir = root / ".obsidian"
    obsidian_dir.mkdir(exist_ok=True)

    templates_obsidian = _PACKAGE_DIR / "obsidian_config"
    for f in templates_obsidian.iterdir():
        if f.is_file():
            shutil.copy2(f, obsidian_dir / f.name)
