"""
cortex/hippo/compaction/types.py — Data types and type aliases for compaction.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Awaitable, Callable, Literal, Optional

from cortex.hippo.models import ContextItemRecord
from cortex.hippo.summarize import SummarizeOptions, SummarizeResult

CompactionLevel = Literal["normal", "aggressive", "fallback"]

# summarize(text, aggressive, options) -> SummarizeResult
SummarizeFn = Callable[
    [str, bool, Optional[SummarizeOptions]],
    Awaitable[SummarizeResult],
]

FALLBACK_MAX_CHARS = 512 * 4


@dataclass
class CompactionDecision:
    should_compact: bool
    reason: str
    current_tokens: int
    threshold: int


@dataclass
class PassResult:
    summary_id: str
    level: CompactionLevel
    content: str
    tokens_before: int = 0
    tokens_after: int = 0
    quality_score: float = 0.0


@dataclass
class CompactionResult:
    action_taken: bool = False
    tokens_before: int = 0
    tokens_after: int = 0
    created_summary_ids: list[str] = field(default_factory=list)
    messages_compacted: int = 0
    condensed: bool = False
    rounds: int = 0


@dataclass
class CompactionMetrics:
    """Structured observability metrics emitted after compaction (#1233)."""
    messages_processed: int = 0
    summaries_created: int = 0
    tokens_saved: int = 0
    rounds_executed: int = 0
    duration_ms: float = 0.0
    mode: str = "UNKNOWN"

    def to_dict(self) -> dict:
        return {
            "messages_processed": self.messages_processed,
            "summaries_created": self.summaries_created,
            "tokens_saved": self.tokens_saved,
            "rounds_executed": self.rounds_executed,
            "duration_ms": round(self.duration_ms, 2),
            "mode": self.mode,
        }


@dataclass
class LeafChunkSelection:
    items: list[ContextItemRecord]
    raw_tokens_outside_tail: int
    threshold: int


@dataclass
class CondensedChunkSelection:
    items: list[ContextItemRecord]
    summary_tokens: int


@dataclass
class CondensedPhaseCandidate:
    target_depth: int
    chunk: CondensedChunkSelection
