"""Migrate KB data between vault locations.

When the user switches from default home vault to an external vault
(e.g., Obsidian sync mode), KB data stays at ~/.agntspace/agnt-kb/ while
the vault reader/writer now points elsewhere. This module detects
orphaned KB data and migrates it to the active vault.
"""

from __future__ import annotations

import logging
import shutil
from pathlib import Path

log = logging.getLogger(__name__)


def migrate_kb_data(src: Path, dest: Path) -> int:
    """Migrate KB wiki/library data from src to dest vault dir.

    Only migrates content that exists in src but not in dest.
    Returns number of files migrated.
    """
    src_kb = src / "knowledge"
    dest_kb = dest / "knowledge"

    if not src_kb.is_dir():
        return 0

    # Find KB slugs that have wiki articles in src
    migrated = 0
    for kb_dir in src_kb.iterdir():
        if not kb_dir.is_dir():
            continue
        slug = kb_dir.name
        src_wiki = kb_dir / "wiki"
        dest_wiki = dest_kb / slug / "wiki"

        if not src_wiki.is_dir():
            continue

        # Count real articles in src (not just .index.md and .gitkeep)
        src_articles = [
            f for f in src_wiki.rglob("*.md")
            if not f.name.startswith(("_", ".")) and f.name != ".gitkeep"
        ]
        if not src_articles:
            continue

        # Count real articles in dest
        dest_articles = []
        if dest_wiki.is_dir():
            dest_articles = [
                f for f in dest_wiki.rglob("*.md")
                if not f.name.startswith(("_", ".")) and f.name != ".gitkeep"
            ]

        # Only migrate if dest is empty/missing but src has content
        if dest_articles:
            log.debug("KB %s: dest already has %d articles, skipping migration", slug, len(dest_articles))
            continue

        log.info(
            "Migrating KB '%s': %d articles from %s → %s",
            slug, len(src_articles), src_kb, dest_kb,
        )

        # Migrate wiki subdirectories (entities, concepts, sources, source_summary)
        for subdir in ("entities", "concepts", "sources", "source_summary"):
            src_sub = src_wiki / subdir
            dest_sub = dest_wiki / subdir
            if not src_sub.is_dir():
                continue
            dest_sub.mkdir(parents=True, exist_ok=True)
            for f in src_sub.iterdir():
                if f.is_file() and f.name != ".gitkeep":
                    dest_file = dest_sub / f.name
                    if not dest_file.exists():
                        shutil.copy2(str(f), str(dest_file))
                        migrated += 1

        # Migrate .concepts.md if it exists
        src_concepts = src_wiki / ".concepts.md"
        dest_concepts = dest_wiki / ".concepts.md"
        if src_concepts.is_file() and not dest_concepts.is_file():
            shutil.copy2(str(src_concepts), str(dest_concepts))
            migrated += 1

        # Migrate library (organized sources) — needed for image references etc.
        src_lib = kb_dir / "library"
        dest_lib = dest_kb / slug / "library"
        if src_lib.is_dir():
            for f in src_lib.rglob("*"):
                if f.is_file() and f.name != ".gitkeep":
                    rel = f.relative_to(src_lib)
                    dest_file = dest_lib / rel
                    if not dest_file.exists():
                        dest_file.parent.mkdir(parents=True, exist_ok=True)
                        shutil.copy2(str(f), str(dest_file))
                        migrated += 1

        # Copy compile state so we don't reprocess
        src_state = kb_dir / ".compile-state.json"
        dest_state = dest_kb / slug / ".compile-state.json"
        if src_state.is_file() and not dest_state.is_file():
            shutil.copy2(str(src_state), str(dest_state))

    if migrated:
        log.info("KB migration complete: %d files migrated", migrated)

    return migrated
