"""
In-memory cache layer.

All read operations on SOAS and URD hit these structures only — zero network
on the hot path. Writes are write-through: in-memory first, then Postgres.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Optional


@dataclass
class SoasRow:
    id: int
    token: str
    encounter_count: int = 0
    saliency: float = 0.0
    novelty: float = 0.0
    first_seen_context: str = ""
    last_seen: Optional[datetime] = None


@dataclass
class UrdEdge:
    concept_id: int
    parent_id: int
    dim_id: int
    is_isa: bool
    confidence: float
    source: str
    parent_token: str = ""
    dim_token: str = ""


# ---------------------------------------------------------------------------
# Module-level cache dicts
# ---------------------------------------------------------------------------

# SOAS — primary lookup by token (mirrors UNIQUE index on token)
soas_by_token: dict[str, SoasRow] = {}

# SOAS — reverse lookup by id
soas_by_id: dict[int, str] = {}

# URD — recollection reads: concept_id → list of edges (tokens pre-joined)
urd_by_concept: dict[int, list[UrdEdge]] = {}

# URD — collision detection: (concept_id, dim_id) → edge
# Mirrors Postgres UNIQUE index on (id, dim_id) exactly
urd_by_concept_dim: dict[tuple[int, int], UrdEdge] = {}

# URD — reverse lookup: parent_id → list of edges where this id is a parent
# Used for bidirectional recollection (surface "gnommoweb is in omega13" when omega13 is mentioned)
urd_by_parent: dict[int, list[UrdEdge]] = {}

# Concepts with pending items in resolution_queue
pending_conflicts: set[int] = set()

# Batched encounter count deltas — flushed to Postgres every 30 s
_encounter_deltas: dict[int, int] = {}


def record_encounter(soas_id: int) -> None:
    """Increment in-memory encounter count and stage a flush delta."""
    _encounter_deltas[soas_id] = _encounter_deltas.get(soas_id, 0) + 1
    if soas_id in {row.id for row in soas_by_token.values()}:
        token = soas_by_id.get(soas_id)
        if token and token in soas_by_token:
            soas_by_token[token].encounter_count += 1


def drain_deltas() -> dict[int, int]:
    """Return and clear the accumulated encounter deltas for Postgres flush."""
    global _encounter_deltas
    batch = dict(_encounter_deltas)
    _encounter_deltas = {}
    return batch
