"""Summary DAG and file reference data models."""

from __future__ import annotations

import time
from typing import Literal

from pydantic import BaseModel, Field


class SummaryNode(BaseModel):
    """
    A materialized summary of a contiguous span of messages.

    At MVP level (Phase 1) these are stored as assistant messages with
    ``is_summary=True`` in the ImmutableStore. The SummaryDAGStore adapts
    those messages into this model.

    Two kinds exist:

    - ``"leaf"`` — produced by summarising raw messages directly.
    - ``"condensed"`` — produced by condensing one or more existing summary
      nodes; ``parent_node_ids`` records all consumed node IDs.
    """

    id: str
    """Same as the corresponding message ID in the ImmutableStore."""
    session_id: str
    level: int = 0
    """DAG depth: 0 = covers raw messages directly, 1+ = covers other nodes."""
    kind: Literal["leaf", "condensed"] = "leaf"
    """'leaf' = summarised from raw messages; 'condensed' = merged from summary nodes."""
    span_start_message_id: str
    """ID of the first message in the summarized span."""
    span_end_message_id: str
    """ID of the last message in the summarized span (inclusive)."""
    content: str
    """The summary text that will be prepended to the active context."""
    token_count: int
    created_at: int = Field(default_factory=lambda: int(time.time() * 1000))
    parent_node_id: str | None = None
    """ID of the parent SummaryNode in a multi-level DAG (kept for backwards compat)."""
    parent_node_ids: list[str] = Field(default_factory=list)
    """All parent SummaryNode IDs consumed by this condensation (populated for 'condensed')."""
    model_id: str = ""
    provider_id: str = ""
    compaction_level: int = 1
    """Escalation level: 1 = selective, 2 = aggressive, 3 = deterministic (fallback)."""


class MessageSpan(BaseModel):
    """A contiguous span of messages not yet covered by any SummaryNode."""

    start_message_id: str
    end_message_id: str
    message_count: int
    estimated_tokens: int


class FileReference(BaseModel):
    """
    Content-addressed external file reference stored in the ``file_references`` table.

    Used by LargeFileHandler to avoid inlining large files into the context window.
    Keyed by content hash so identical files are deduplicated automatically.
    """

    content_id: str
    """SHA-256 hex digest of the file content."""
    path: str
    """Original file path as seen by the application."""
    file_type: str
    """Detected MIME type or language identifier."""
    token_count: int
    """Estimated token count of the full file."""
    exploration_summary: str
    """Compact structural description generated by LargeFileHandler."""
    created_at: int = Field(default_factory=lambda: int(time.time() * 1000))
