from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import Optional, Dict, Any, List
from datetime import datetime
from enum import Enum


class BusType(str, Enum):
    STANDARD = "standard"
    DELUXE = "deluxe"
    SLEEPER = "sleeper"
    SEMI_SLEEPER = "semi_sleeper"


class BusBase(BaseModel):
    bus_number: str = Field(..., min_length=1, max_length=50)
    bus_type: BusType
    total_seats: int = Field(..., gt=0)
    seat_layout_config: Dict[str, Any]
    amenities: Optional[Dict[str, Any]] = None
    is_active: bool = True

    @field_validator("bus_number")
    @classmethod
    def validate_bus_number(cls, v: str) -> str:
        if not v or not v.strip():
            raise ValueError("Bus number cannot be empty")
        return v.strip()

    @field_validator("total_seats")
    @classmethod
    def validate_total_seats(cls, v: int) -> int:
        if v <= 0:
            raise ValueError("Total seats must be a positive number")
        return v

    @field_validator("seat_layout_config")
    @classmethod
    def validate_seat_layout_config(cls, v: Dict[str, Any]) -> Dict[str, Any]:
        if not v:
            raise ValueError("Seat layout configuration cannot be empty")
        return v


class BusCreate(BusBase):
    pass


class BusUpdate(BaseModel):
    bus_number: Optional[str] = Field(None, min_length=1, max_length=50)
    bus_type: Optional[BusType] = None
    total_seats: Optional[int] = Field(None, gt=0)
    seat_layout_config: Optional[Dict[str, Any]] = None
    amenities: Optional[Dict[str, Any]] = None
    is_active: Optional[bool] = None

    @field_validator("bus_number")
    @classmethod
    def validate_bus_number(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v or not v.strip():
                raise ValueError("Bus number cannot be empty")
            return v.strip()
        return v

    @field_validator("total_seats")
    @classmethod
    def validate_total_seats(cls, v: Optional[int]) -> Optional[int]:
        if v is not None and v <= 0:
            raise ValueError("Total seats must be a positive number")
        return v

    @field_validator("seat_layout_config")
    @classmethod
    def validate_seat_layout_config(cls, v: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        if v is not None and not v:
            raise ValueError("Seat layout configuration cannot be empty")
        return v


class BusResponse(BusBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)