"""Feedback and outcome capture Pydantic schemas."""
from __future__ import annotations

from typing import Any, Literal

from pydantic import BaseModel, model_validator


class FeedbackRequest(BaseModel):
    """Request body for feedback capture."""

    kind: Literal["thumbs_up", "thumbs_down", "numeric_rating", "edited_answer", "suggestion"]
    run_id: str | None = None
    trace_id: str | None = None
    rating: float | None = None
    suggestion_outcome: Literal["accepted", "rejected"] | None = None
    corrected_output: str | None = None
    correction_notes: str | None = None
    expected_output: str | None = None
    failure_types: list[str] | None = None
    metadata: dict[str, Any] | None = None

    @model_validator(mode="after")
    def validate_payload(self) -> "FeedbackRequest":
        """Validate feedback payload based on kind."""
        if self.run_id is None and self.trace_id is None:
            raise ValueError("run_id or trace_id is required")
        if self.kind == "numeric_rating" and self.rating is None:
            raise ValueError("rating is required for numeric_rating feedback")
        if self.kind == "suggestion" and self.suggestion_outcome is None:
            raise ValueError("suggestion_outcome is required for suggestion feedback")
        if self.kind == "edited_answer" and not self.corrected_output:
            raise ValueError("corrected_output is required for edited_answer feedback")
        return self


class FeedbackResponse(BaseModel):
    """Serialized feedback capture response."""

    id: str
    run_id: str | None = None
    trace_id: str
    kind: str
    session_id: str | None = None
    workspace_id: str | None = None
    prompt_version: str | None = None
    model: str | None = None
    config_fingerprint: str | None = None
    rating: float | None = None
    suggestion_outcome: str | None = None
    corrected_output: str | None = None
    correction_notes: str | None = None
    expected_output: str | None = None
    failure_types: list[str]
    metadata: dict[str, Any]
    created_at: str


class OutcomeRequest(BaseModel):
    """Request body for outcome capture."""

    kind: Literal["conversion", "resolution", "ctr", "reply_rate", "escalation", "human_takeover"]
    run_id: str | None = None
    trace_id: str | None = None
    value: float | int | bool | str | None = None
    metadata: dict[str, Any] | None = None

    @model_validator(mode="after")
    def validate_payload(self) -> "OutcomeRequest":
        """Validate outcome payload."""
        if self.run_id is None and self.trace_id is None:
            raise ValueError("run_id or trace_id is required")
        return self


class OutcomeResponse(BaseModel):
    """Serialized outcome capture response."""

    id: str
    run_id: str | None = None
    trace_id: str
    kind: str
    session_id: str | None = None
    workspace_id: str | None = None
    prompt_version: str | None = None
    model: str | None = None
    config_fingerprint: str | None = None
    value: float | int | bool | str | None = None
    metadata: dict[str, Any]
    created_at: str


__all__ = [
    "FeedbackRequest",
    "FeedbackResponse",
    "OutcomeRequest",
    "OutcomeResponse",
]
