"""Result dataclasses and helper functions for the CortexPlugin API."""
from __future__ import annotations

import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _now() -> str:
    return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S")


def _new_session_id() -> str:
    return str(uuid.uuid4())


# ---------------------------------------------------------------------------
# Result / report types
# ---------------------------------------------------------------------------

@dataclass
class RememberResult:
    """Result of the remember() pipeline (extract → reconcile → store).

    Attributes:
        session_id: Session this remember() call belongs to.
        claims_extracted: How many claims the LLM extracted from the conversation.
        claims_stored: How many claims were actually persisted (after dedup).
        entities_resolved: How many entity mentions were resolved to canonical IDs.
        noise_filtered: How many messages were dropped by the noise filter.
        errors: List of non-fatal error messages (module failures that didn't crash).
        ok: True if the pipeline completed without fatal errors.
    """
    session_id: str
    claims_extracted: int
    claims_stored: int
    entities_resolved: int
    noise_filtered: int
    errors: List[str] = field(default_factory=list)
    warnings: List[str] = field(default_factory=list)
    zero_claim_warning: bool = False
    ok: bool = True


@dataclass
class ForgetResult:
    """Result of the forget() operation.

    Attributes:
        memory_id: The claim ID that was targeted for deletion.
        deleted: True if the claim was successfully soft-deleted (archived).
                 False if the claim is a cornerstone (deletion blocked) or not found.
    """
    memory_id: str
    deleted: bool
    reason: str = ""
    errors: List[str] = field(default_factory=list)


@dataclass
class HealthReport:
    """Returned by health()."""
    ok: bool
    storage: str = "unknown"
    modules: Dict[str, str] = field(default_factory=dict)
    errors: List[str] = field(default_factory=list)
    timestamp: str = field(default_factory=lambda: _now())


@dataclass
class EvolutionProposalResult:
    """Returned by propose_cornerstone_evolution().

    Attributes:
        action: 'auto_applied' | 'queued'
        proposal_id: ID of the stored proposal.
        proposed_content: The LLM-generated revised golden copy.
        diff: Unified diff between original and proposed content.
        reasoning: LLM explanation for the proposed change.
        confidence: LLM-reported confidence (0.0–1.0).
        requires_operator_review: False only when auto-applied.
        cornerstone: Updated CornerstoneMemory (only when auto-applied).
        errors: Non-fatal errors encountered.
        ok: False if the operation failed entirely.
    """
    action: str
    proposal_id: str
    proposed_content: str
    diff: str
    reasoning: str
    confidence: float
    requires_operator_review: bool = True
    cornerstone: Any = None
    errors: List[str] = field(default_factory=list)
    ok: bool = True


@dataclass
class AskResult:
    """Returned by ask() — synthesised answer from retrieved memories.

    Attributes:
        answer:     LLM-generated answer grounded in stored memories.
        sources:    Memory dicts used to produce the answer.
        confidence: Mean retrieval score of the sources (0.0–1.0).
        reasoning:  Short note on how the answer was derived.
        errors:     Non-fatal errors (empty when everything worked).
        ok:         False only on hard failure (LLM unavailable, etc.).
    """

    answer: str
    sources: List[Dict[str, Any]] = field(default_factory=list)
    confidence: float = 0.0
    reasoning: str = ""
    errors: List[str] = field(default_factory=list)
    ok: bool = True


@dataclass
class WakeReport:
    """Returned by wake()."""
    session_id: str
    cornerstones_loaded: int = 0
    handoff_packet: Optional[Dict[str, Any]] = None
    due_commitments: int = 0
    open_loops: int = 0
    errors: List[str] = field(default_factory=list)


@dataclass
class SleepReport:
    """Returned by sleep()."""
    session_id: str
    memories_summarised: int = 0
    errors: List[str] = field(default_factory=list)
