"""
Data models for AI Service.
[AC-AISVC-02] Request/Response models aligned with OpenAPI contract.
[AC-AISVC-13] Entity models for database persistence.
"""

from enum import Enum
from typing import Any

from pydantic import BaseModel, Field


class ChannelType(str, Enum):
    WECHAT = "wechat"
    DOUYIN = "douyin"
    JD = "jd"


class Role(str, Enum):
    USER = "user"
    ASSISTANT = "assistant"


class ChatMessage(BaseModel):
    role: Role = Field(..., description="Message role: user or assistant")
    content: str = Field(..., description="Message content")


class ChatRequest(BaseModel):
    session_id: str = Field(..., alias="sessionId", description="Session ID for conversation tracking")
    current_message: str = Field(..., alias="currentMessage", description="Current user message")
    channel_type: ChannelType = Field(..., alias="channelType", description="Channel type: wechat, douyin, jd")
    history: list[ChatMessage] | None = Field(default=None, description="Optional conversation history")
    metadata: dict[str, Any] | None = Field(default=None, description="Optional metadata")

    model_config = {"populate_by_name": True}


class ChatResponse(BaseModel):
    reply: str = Field(..., description="AI generated reply content")
    confidence: float = Field(..., ge=0.0, le=1.0, description="Confidence score between 0.0 and 1.0")
    should_transfer: bool = Field(..., alias="shouldTransfer", description="Whether to suggest transfer to human agent")
    transfer_reason: str | None = Field(default=None, alias="transferReason", description="Reason for transfer suggestion")
    metadata: dict[str, Any] | None = Field(default=None, description="Response metadata")

    model_config = {"populate_by_name": True}


class ErrorCode(str, Enum):
    INVALID_REQUEST = "INVALID_REQUEST"
    MISSING_TENANT_ID = "MISSING_TENANT_ID"
    INVALID_TENANT_ID = "INVALID_TENANT_ID"
    UNAUTHORIZED = "UNAUTHORIZED"
    INTERNAL_ERROR = "INTERNAL_ERROR"
    SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
    TIMEOUT = "TIMEOUT"
    LLM_ERROR = "LLM_ERROR"
    RETRIEVAL_ERROR = "RETRIEVAL_ERROR"


class ErrorResponse(BaseModel):
    code: str = Field(..., description="Error code")
    message: str = Field(..., description="Error message")
    details: list[dict[str, Any]] | None = Field(default=None, description="Detailed error information")


class SSEEventType(str, Enum):
    MESSAGE = "message"
    FINAL = "final"
    ERROR = "error"


class SSEMessageEvent(BaseModel):
    delta: str = Field(..., description="Incremental text content")


class SSEFinalEvent(BaseModel):
    reply: str = Field(..., description="Complete AI reply")
    confidence: float = Field(..., ge=0.0, le=1.0, description="Confidence score")
    should_transfer: bool = Field(..., alias="shouldTransfer", description="Transfer suggestion")
    transfer_reason: str | None = Field(default=None, alias="transferReason", description="Transfer reason")
    metadata: dict[str, Any] | None = Field(default=None, description="Response metadata")

    model_config = {"populate_by_name": True}


class SSEErrorEvent(BaseModel):
    code: str = Field(..., description="Error code")
    message: str = Field(..., description="Error message")
    details: list[dict[str, Any]] | None = Field(default=None, description="Error details")
