from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import Optional, List
from datetime import datetime


class ConversationBase(BaseModel):
    participant1_id: str = Field(..., min_length=36, max_length=36)
    participant2_id: str = Field(..., min_length=36, max_length=36)
    listing_id: Optional[str] = Field(None, min_length=36, max_length=36)
    order_id: Optional[str] = Field(None, min_length=36, max_length=36)
    last_message_at: Optional[datetime] = None

    @field_validator("participant1_id", "participant2_id")
    @classmethod
    def validate_participant_ids(cls, v: str) -> str:
        if not v or len(v.strip()) == 0:
            raise ValueError("Participant ID cannot be empty")
        return v


class ConversationCreate(ConversationBase):
    pass


class ConversationUpdate(BaseModel):
    participant1_id: Optional[str] = Field(None, min_length=36, max_length=36)
    participant2_id: Optional[str] = Field(None, min_length=36, max_length=36)
    listing_id: Optional[str] = Field(None, min_length=36, max_length=36)
    order_id: Optional[str] = Field(None, min_length=36, max_length=36)
    last_message_at: Optional[datetime] = None


class ConversationResponse(ConversationBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class MessageBase(BaseModel):
    conversation_id: str = Field(..., min_length=36, max_length=36)
    sender_id: str = Field(..., min_length=36, max_length=36)
    message_text: str = Field(..., min_length=1)
    is_read: bool = False
    read_at: Optional[datetime] = None

    @field_validator("message_text")
    @classmethod
    def validate_message_text(cls, v: str) -> str:
        if not v or len(v.strip()) == 0:
            raise ValueError("Message text cannot be empty")
        return v


class MessageCreate(BaseModel):
    conversation_id: str = Field(..., min_length=36, max_length=36)
    sender_id: str = Field(..., min_length=36, max_length=36)
    message_text: str = Field(..., min_length=1)

    @field_validator("message_text")
    @classmethod
    def validate_message_text(cls, v: str) -> str:
        if not v or len(v.strip()) == 0:
            raise ValueError("Message text cannot be empty")
        return v


class MessageUpdate(BaseModel):
    conversation_id: Optional[str] = Field(None, min_length=36, max_length=36)
    sender_id: Optional[str] = Field(None, min_length=36, max_length=36)
    message_text: Optional[str] = Field(None, min_length=1)
    is_read: Optional[bool] = None
    read_at: Optional[datetime] = None


class MessageResponse(MessageBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class UserBasicInfo(BaseModel):
    id: str
    email: str

    model_config = ConfigDict(from_attributes=True)


class ListingBasicInfo(BaseModel):
    id: str
    title: str

    model_config = ConfigDict(from_attributes=True)


class OrderBasicInfo(BaseModel):
    id: str
    order_number: str

    model_config = ConfigDict(from_attributes=True)


class MessageDetailResponse(BaseModel):
    id: str
    conversation_id: str
    sender: UserBasicInfo
    message_text: str
    is_read: bool
    read_at: Optional[datetime]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class ConversationDetailResponse(BaseModel):
    id: str
    participant1: UserBasicInfo
    participant2: UserBasicInfo
    listing: Optional[ListingBasicInfo]
    order: Optional[OrderBasicInfo]
    messages: List[MessageDetailResponse]
    last_message_at: Optional[datetime]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)