"""
Repos Manager — discovers all Kodara-indexed projects on this machine.

Scans common locations for .kodara/index.db:
  - Recent paths from ~/.kodara/repos.json (registry file we maintain)
  - Optionally: user-provided search paths
"""

from __future__ import annotations

import json
import os
import time
from dataclasses import dataclass
from pathlib import Path
from typing import Optional


# ── Registry helpers ──────────────────────────────────────────────────────────


def get_registry_path() -> Path:
    """Return Path to ~/.kodara/repos.json, creating ~/.kodara/ if needed."""
    registry_dir = Path.home() / ".kodara"
    registry_dir.mkdir(parents=True, exist_ok=True)
    return registry_dir / "repos.json"


def _read_registry() -> list[dict]:
    """Read the registry file, returning a list of repo dicts."""
    path = get_registry_path()
    if not path.exists():
        return []
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        return data.get("repos", [])
    except Exception:
        return []


def _write_registry(repos: list[dict]) -> None:
    """Atomically write the registry file."""
    path = get_registry_path()
    tmp = path.with_suffix(".json.tmp")
    data = {"repos": repos}
    tmp.write_text(json.dumps(data, indent=2), encoding="utf-8")
    tmp.replace(path)


# ── Public API ────────────────────────────────────────────────────────────────


@dataclass
class RepoEntry:
    path: str           # absolute path to project root
    display_name: str   # dirname
    file_count: int     # from index metadata
    indexed_at: float   # timestamp
    exists: bool        # True if path still exists on disk


def list_repos() -> list[RepoEntry]:
    """
    Read ~/.kodara/repos.json and build RepoEntry objects.

    For each path, check whether .kodara/index.db still exists and load
    metadata from MemoryStore if so. Returns entries sorted by indexed_at desc.
    """
    from kodara.memory.store import MemoryStore

    repos = _read_registry()
    entries: list[RepoEntry] = []

    for record in repos:
        abs_path = record.get("path", "")
        p = Path(abs_path)
        db_path = p / ".kodara" / "index.db"
        exists = db_path.exists()

        file_count = 0
        indexed_at = record.get("last_seen", 0.0)

        if exists:
            try:
                store = MemoryStore(p)
                idx = store.load()
                if idx is not None:
                    file_count = idx.file_count
                    indexed_at = idx.indexed_at
            except Exception:
                pass

        entries.append(RepoEntry(
            path=abs_path,
            display_name=p.name,
            file_count=file_count,
            indexed_at=indexed_at,
            exists=exists,
        ))

    entries.sort(key=lambda e: e.indexed_at, reverse=True)
    return entries


def register_repo(path: str) -> None:
    """
    Add or update a path in ~/.kodara/repos.json.

    If the path already exists in the registry, update last_seen.
    """
    abs_path = str(Path(path).resolve())
    repos = _read_registry()

    for record in repos:
        if record.get("path") == abs_path:
            record["last_seen"] = time.time()
            _write_registry(repos)
            return

    repos.append({"path": abs_path, "last_seen": time.time()})
    _write_registry(repos)


def clean_repos() -> list[str]:
    """
    Remove entries from ~/.kodara/repos.json where the path no longer exists.

    Returns a list of removed paths.
    """
    repos = _read_registry()
    removed: list[str] = []
    kept: list[dict] = []

    for record in repos:
        abs_path = record.get("path", "")
        db_path = Path(abs_path) / ".kodara" / "index.db"
        if db_path.exists():
            kept.append(record)
        else:
            removed.append(abs_path)

    if removed:
        _write_registry(kept)

    return removed
