"""Snapshot-Writer — JSON pro Tag in /var/lib/aria-radar/snapshots/.

Schema:
  {
    date: "YYYY-MM-DD",
    item_count: int,
    source_counts: {source: int, ...}    # aus items[] berechnet
    runs: [                              # eine Entry pro Lauf an diesem Tag
      {ts, fetched, new, errors},
      ...
    ],
    items: [...]
  }

Mehrfach-Läufe am selben Tag mergen Items additiv; Items werden über URL-Hash
in dedupe.py dedupliziert, hier kann es daher nicht zu Doppelten kommen.
"""
from __future__ import annotations

import datetime as dt
import json
import logging
import sys
from collections import Counter
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from aria_atomic_write import atomic_write_json, file_lock  # noqa: E402

log = logging.getLogger("snapshot")


def write_snapshot(
    *,
    path: Path,
    date: str,
    source_counts: dict[str, int],
    items: list[dict],
    errors: dict[str, str] | None = None,
) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    lock_path = path.with_suffix(".lock")

    with file_lock(lock_path):
        existing: dict | None = None
        if path.exists():
            try:
                existing = json.loads(path.read_text(encoding="utf-8"))
            except Exception as exc:  # noqa: BLE001
                log.warning("snapshot %s unreadable, will overwrite: %s", path, exc)
                existing = None

        if existing:
            merged_items = list(existing.get("items", [])) + list(items)
            runs = list(existing.get("runs", []))
        else:
            merged_items = list(items)
            runs = []

        runs.append({
            "ts": dt.datetime.now(dt.timezone.utc).isoformat(),
            "fetched": sum(source_counts.values()),
            "new": len(items),
            "errors": errors or {},
        })

        actual_source_counts = dict(Counter(item["source"] for item in merged_items))

        payload = {
            "date": date,
            "item_count": len(merged_items),
            "source_counts": actual_source_counts,
            "runs": runs,
            "items": merged_items,
        }
        atomic_write_json(path, payload)
        log.info("wrote %s (run #%d, %d items total)", path, len(runs), len(merged_items))
