"""Durable project notes: the context store behind ``remember`` and ``prime``."""

from __future__ import annotations

import time
import uuid
from datetime import datetime, timezone
from pathlib import Path

from . import store

SCHEMA_VERSION = 1
TYPES = ("decision", "task", "next", "fact", "blocker")
PRIME_WINDOW_SECONDS = 7 * 24 * 3600.0
MAX_ENTRIES = 2000


def _iso(epoch: float) -> str:
    return datetime.fromtimestamp(epoch, timezone.utc).isoformat().replace("+00:00", "Z")


def _parse_date(value: object) -> float:
    if isinstance(value, (int, float)):
        return float(value)
    if isinstance(value, str):
        try:
            return datetime.fromisoformat(value.replace("Z", "+00:00")).timestamp()
        except ValueError:
            return 0.0
    return 0.0


def load(root: Path) -> list[dict]:
    data = store.read_json(store.context_store_path(root))
    if data is None or data.get("schema_version") != SCHEMA_VERSION:
        return []
    entries = data.get("entries")
    if not isinstance(entries, list):
        return []
    return [entry for entry in entries if isinstance(entry, dict) and isinstance(entry.get("content"), str)]


def remember(
    root: Path,
    entry_type: str,
    content: str,
    tags: list[str] | None = None,
    files: list[str] | None = None,
) -> str:
    now = time.time()
    normalized = entry_type if entry_type in TYPES else "fact"
    record = {
        "id": uuid.uuid4().hex[:12],
        "type": normalized,
        "content": content,
        "tags": [str(tag) for tag in (tags or []) if str(tag)],
        "files": [store.to_rel(root, str(item)) for item in (files or []) if str(item)],
        "date": _iso(now),
    }
    entries = load(root)
    entries.append(record)
    entries.sort(key=lambda item: _parse_date(item.get("date")), reverse=True)
    del entries[MAX_ENTRIES:]
    store.write_json(
        store.context_store_path(root),
        {"schema_version": SCHEMA_VERSION, "updated_at": _iso(now), "entries": entries},
    )
    return record["id"]


def prime(root: Path, limit: int = 12) -> list[dict]:
    cutoff = time.time() - PRIME_WINDOW_SECONDS
    recent = [entry for entry in load(root) if _parse_date(entry.get("date")) >= cutoff]
    recent.sort(key=lambda entry: _parse_date(entry.get("date")), reverse=True)
    return [
        {
            "type": entry.get("type", "fact"),
            "content": entry.get("content", ""),
            "tags": entry.get("tags") or [],
            "files": entry.get("files") or [],
            "date": entry.get("date", ""),
        }
        for entry in recent[: max(0, int(limit))]
    ]
