"""资料库 unified lint。"""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Any

from niannian.vault.store import VaultStore


def _parse_dt(value: str) -> datetime | None:
    try:
        dt = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
    except ValueError:
        return None
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return dt


class VaultLintService:
    def __init__(self, store: VaultStore) -> None:
        self._store = store

    def run(self, *, pending_days: int = 7) -> dict[str, Any]:
        now = datetime.now(timezone.utc)
        pending: list[dict[str, str]] = []
        orphans: list[dict[str, str]] = []
        idx = self._store.load_index()
        entries = [e for e in (idx.get("entries") or []) if isinstance(e, dict)]
        indexed_paths = {str(e.get("rel_path") or "") for e in entries}
        for entry in entries:
            rel = str(entry.get("rel_path") or "")
            if not rel:
                continue
            try:
                doc = self._store.read_document(rel)
            except (FileNotFoundError, OSError):
                orphans.append({"vault_id": str(entry.get("vault_id") or ""), "rel_path": rel})
                continue
            fm = doc.get("frontmatter") or {}
            if str(fm.get("taxonomy_status") or "") == "pending":
                extracted = _parse_dt(str(fm.get("extracted_at") or entry.get("created_at") or ""))
                if extracted and (now - extracted).days >= pending_days:
                    pending.append(
                        {
                            "vault_id": str(entry.get("vault_id") or ""),
                            "rel_path": rel,
                            "title": str(entry.get("title") or ""),
                        }
                    )
        for md in self._store._root.rglob("*.md"):  # noqa: SLF001
            rel = str(md.relative_to(self._store._root))  # noqa: SLF001
            if rel.endswith("/_overview.md") or rel.endswith("_overview.md"):
                continue
            if rel not in indexed_paths and md.is_file():
                orphans.append({"rel_path": rel, "vault_id": ""})
        return {
            "pending_aging": pending,
            "orphan_index": orphans,
            "belief_conflicts": [],
            "generated_at": now.isoformat(),
        }
