"""Mtime-based marketplace synchronisation.

On every startup, compare bundled file mtimes with the recorded mtimes in
``.ievo/registry.yaml``.  Re-deploy any file whose mtime has changed.
First call (no registry file) deploys everything.
"""

from __future__ import annotations

import shutil
from pathlib import Path

import yaml

from ievo.core.config import IEVO_REGISTRY
from ievo.core.templates import TEMPLATE_MAP
from ievo.marketplace import (
    bundled_agent_path,
    bundled_skill_path,
    bundled_template_path,
    list_bundled_agents,
    list_bundled_skills,
)


def sync_marketplace(root: Path) -> list[str]:
    """Deploy or update bundled marketplace files based on file mtimes.

    Compares each bundled agent/skill/template mtime against the value
    recorded in ``.ievo/registry.yaml``.  Re-deploys files whose mtime
    changed and records the new mtimes.

    Returns a sorted list of names that were deployed or updated.
    First call (no registry file) deploys everything.
    """
    registry_path = root / IEVO_REGISTRY

    # Load stored mtimes
    stored: dict[str, dict[str, float]] = {"agents": {}, "skills": {}, "templates": {}}
    if registry_path.is_file():
        try:
            raw = yaml.safe_load(registry_path.read_text()) or {}
        except yaml.YAMLError:
            raw = {}
        for key in ("agents", "skills", "templates"):
            section = raw.get(key)
            if isinstance(section, dict):
                stored[key] = section

    updated: list[str] = []
    new_mtimes: dict[str, dict[str, float]] = {"agents": {}, "skills": {}, "templates": {}}

    # ── Agents ──────────────────────────────────────────────────
    agents_dir = root / ".claude" / "agents"
    agents_dir.mkdir(parents=True, exist_ok=True)
    for name in list_bundled_agents():
        src = bundled_agent_path(name)
        if src is None:
            continue
        mtime = src.stat().st_mtime
        new_mtimes["agents"][name] = mtime
        dest = agents_dir / f"{name}.md"
        if mtime != stored["agents"].get(name) or not dest.exists():
            shutil.copy2(src, dest)
            updated.append(name)

    # ── Skills ──────────────────────────────────────────────────
    skills_dir = root / ".claude" / "skills"
    skills_dir.mkdir(parents=True, exist_ok=True)
    for name in list_bundled_skills():
        src = bundled_skill_path(name)
        if src is None:
            continue
        mtime = src.stat().st_mtime
        new_mtimes["skills"][name] = mtime
        dest = skills_dir / name / "SKILL.md"
        if mtime != stored["skills"].get(name) or not dest.exists():
            dest.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dest)
            updated.append(name)

    # ── Templates ──────────────────────────────────────────────
    for bundled_name, dest_rel in TEMPLATE_MAP:
        src = bundled_template_path(bundled_name)
        if src is None:
            continue
        stem = Path(bundled_name).stem
        mtime = src.stat().st_mtime
        new_mtimes["templates"][stem] = mtime
        dest = root / dest_rel
        if mtime != stored["templates"].get(stem) or not dest.exists():
            dest.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(src, dest)
            updated.append(bundled_name)

    # ── Persist mtimes ──────────────────────────────────────────
    registry_path.parent.mkdir(parents=True, exist_ok=True)
    registry_path.write_text(yaml.dump(new_mtimes, default_flow_style=False))

    return sorted(updated)
