from __future__ import annotations

from datetime import datetime
from typing import Any

from pydantic import BaseModel, ConfigDict, Field, field_validator


def _blank_to_none(value: Any) -> Any:
    if value is None:
        return None
    if isinstance(value, str):
        normalized = value.strip()
        return normalized or None
    return value


class AgentFeedbackCreate(BaseModel):
    run_id: str | None = Field(default=None, max_length=50)
    conversation_id: str | None = Field(default=None, max_length=50)
    user_id: str | None = Field(default=None, max_length=100)
    agent: str | None = Field(default=None, max_length=30)
    source: str | None = Field(default=None, max_length=30)
    session_type: str | None = Field(default=None, max_length=30)
    operation_type: str | None = Field(default="assistant_round", max_length=50)
    operation_status: str | None = Field(default=None, max_length=20)
    rating: int = Field(ge=1, le=5)
    reason: str | None = Field(default=None, max_length=1000)
    context_json: dict[str, Any] = Field(default_factory=dict)

    @field_validator(
        "run_id",
        "conversation_id",
        "user_id",
        "agent",
        "source",
        "session_type",
        "operation_type",
        "operation_status",
        "reason",
        mode="before",
    )
    @classmethod
    def normalize_optional_text(cls, value: Any) -> Any:
        return _blank_to_none(value)


class AgentFeedbackRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: str
    feedback_id: str
    run_id: str | None
    conversation_id: str | None
    user_id: str | None
    agent: str
    source: str
    session_type: str
    operation_type: str
    operation_status: str
    rating: int
    reason: str | None
    context_json: dict[str, Any]
    created_at: datetime


class AgentFeedbackSummaryRead(BaseModel):
    window_limit: int
    total_feedback: int
    average_rating: float
    low_rating_count: int
    rating_distribution: dict[str, int] = Field(default_factory=dict)
    agents: dict[str, int] = Field(default_factory=dict)
    session_types: dict[str, int] = Field(default_factory=dict)
    recent_low_feedback: list[dict[str, Any]] = Field(default_factory=list)
