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


class ReviewBase(BaseModel):
    booking_id: str = Field(..., min_length=36, max_length=36)
    customer_id: str = Field(..., min_length=36, max_length=36)
    tour_package_id: str = Field(..., min_length=36, max_length=36)
    tour_guide_id: Optional[str] = Field(None, min_length=36, max_length=36)
    overall_rating: int = Field(..., ge=1, le=5)
    guide_rating: Optional[int] = Field(None, ge=1, le=5)
    accommodation_rating: Optional[int] = Field(None, ge=1, le=5)
    transportation_rating: Optional[int] = Field(None, ge=1, le=5)
    value_for_money_rating: Optional[int] = Field(None, ge=1, le=5)
    title: Optional[str] = Field(None, max_length=255)
    comment: Optional[str] = None
    photos: Optional[List[str]] = None
    is_verified: bool = True
    is_published: bool = False
    management_response: Optional[str] = None
    response_date: Optional[datetime] = None

    @field_validator("overall_rating", "guide_rating", "accommodation_rating", "transportation_rating", "value_for_money_rating")
    @classmethod
    def validate_rating(cls, v):
        if v is not None and (v < 1 or v > 5):
            raise ValueError("Rating must be between 1 and 5")
        return v


class ReviewCreate(ReviewBase):
    pass


class ReviewUpdate(BaseModel):
    booking_id: Optional[str] = Field(None, min_length=36, max_length=36)
    customer_id: Optional[str] = Field(None, min_length=36, max_length=36)
    tour_package_id: Optional[str] = Field(None, min_length=36, max_length=36)
    tour_guide_id: Optional[str] = Field(None, min_length=36, max_length=36)
    overall_rating: Optional[int] = Field(None, ge=1, le=5)
    guide_rating: Optional[int] = Field(None, ge=1, le=5)
    accommodation_rating: Optional[int] = Field(None, ge=1, le=5)
    transportation_rating: Optional[int] = Field(None, ge=1, le=5)
    value_for_money_rating: Optional[int] = Field(None, ge=1, le=5)
    title: Optional[str] = Field(None, max_length=255)
    comment: Optional[str] = None
    photos: Optional[List[str]] = None
    is_verified: Optional[bool] = None
    is_published: Optional[bool] = None
    management_response: Optional[str] = None
    response_date: Optional[datetime] = None

    @field_validator("overall_rating", "guide_rating", "accommodation_rating", "transportation_rating", "value_for_money_rating")
    @classmethod
    def validate_rating(cls, v):
        if v is not None and (v < 1 or v > 5):
            raise ValueError("Rating must be between 1 and 5")
        return v


class ReviewResponse(ReviewBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class ReviewDetailResponse(BaseModel):
    id: str
    booking_id: str
    customer_id: str
    tour_package_id: str
    tour_guide_id: Optional[str]
    overall_rating: int
    guide_rating: Optional[int]
    accommodation_rating: Optional[int]
    transportation_rating: Optional[int]
    value_for_money_rating: Optional[int]
    title: Optional[str]
    comment: Optional[str]
    photos: Optional[List[str]]
    is_verified: bool
    is_published: bool
    management_response: Optional[str]
    response_date: Optional[datetime]
    created_at: datetime
    updated_at: datetime
    customer_first_name: str
    customer_last_name: str
    tour_package_name: str
    tour_guide_first_name: Optional[str]
    tour_guide_last_name: Optional[str]
    booking_number: str

    model_config = ConfigDict(from_attributes=True)