from __future__ import annotations

from datetime import datetime, timezone
from typing import Any, Literal

from pydantic import BaseModel, Field


LearningSignalType = Literal[
    "preference",
    "workflow",
    "decomposition",
    "tool_success",
    "correction",
]


class SessionRetrospective(BaseModel):
    retrospective_id: str | None = None
    user_id: str
    conversation_id: str
    request_message_id: str | None = None
    response_message_id: str | None = None
    query_text: str
    final_response: str | None = None
    summary: str
    task_type: str | None = None
    execution_mode: str | None = None
    primary_agent: str | None = None
    verification_status: str | None = None
    verification_summary: str | None = None
    used_skill_names: list[str] = Field(default_factory=list)
    evidence_refs: list[dict[str, Any]] = Field(default_factory=list)
    task_refs: list[dict[str, Any]] = Field(default_factory=list)
    event_refs: list[dict[str, Any]] = Field(default_factory=list)
    context_snapshot: dict[str, Any] = Field(default_factory=dict)
    learning_signals: list["LearningSignal"] = Field(default_factory=list)
    pattern_candidates: list["PatternCandidate"] = Field(default_factory=list)
    skill_candidates: list["SkillCandidate"] = Field(default_factory=list)
    learning_decision: "LearningDecision | None" = None
    outcome: Literal["completed", "partial", "failed"] = "completed"
    captured_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class LearningSignal(BaseModel):
    signal_type: LearningSignalType
    confidence: float = 0.0
    evidence_refs: list[dict[str, Any]] = Field(default_factory=list)
    explanation: str | None = None
    payload: dict[str, Any] = Field(default_factory=dict)


class PatternCandidate(BaseModel):
    pattern_id: str
    pattern_type: str
    description: str
    confidence: float = 0.0
    evidence_refs: list[dict[str, Any]] = Field(default_factory=list)


class SkillCandidate(BaseModel):
    candidate_id: str
    name: str
    summary: str
    candidate_type: Literal["workflow_skill", "preference_skill", "decomposition_skill"] = "workflow_skill"
    source_pattern_ids: list[str] = Field(default_factory=list)
    confidence: float = 0.0
    evidence_refs: list[dict[str, Any]] = Field(default_factory=list)
    recommended_status: Literal["candidate", "shadow"] = "candidate"


class LearningDecision(BaseModel):
    decision: Literal["reinforce_memory", "create_candidate", "promote_skill", "defer", "reject"]
    explanation: str
    evidence_refs: list[dict[str, Any]] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)
