# services/external/app/schemas/traffic.py
"""
Traffic Service Pydantic Schemas
"""

from pydantic import BaseModel, Field, field_validator
from datetime import datetime
from typing import Optional, List
from uuid import UUID

class TrafficDataBase(BaseModel):
    """Base traffic data schema"""
    location_id: str = Field(..., max_length=100, description="Traffic monitoring location ID")
    date: datetime = Field(..., description="Date and time of traffic measurement")
    traffic_volume: Optional[int] = Field(None, ge=0, description="Vehicles per hour")
    pedestrian_count: Optional[int] = Field(None, ge=0, description="Pedestrians per hour")
    congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$", description="Traffic congestion level")
    average_speed: Optional[float] = Field(None, ge=0, le=200, description="Average speed in km/h")
    source: str = Field("madrid_opendata", max_length=50, description="Data source")
    raw_data: Optional[str] = Field(None, description="Raw data from source")

class TrafficDataCreate(TrafficDataBase):
    """Schema for creating traffic data"""
    pass

class TrafficDataUpdate(BaseModel):
    """Schema for updating traffic data"""
    traffic_volume: Optional[int] = Field(None, ge=0)
    pedestrian_count: Optional[int] = Field(None, ge=0)
    congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$")
    average_speed: Optional[float] = Field(None, ge=0, le=200)
    raw_data: Optional[str] = None

class TrafficDataResponseDB(TrafficDataBase):
    """Schema for traffic data responses from database"""
    id: str = Field(..., description="Unique identifier")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")

    @field_validator('id', mode='before')
    @classmethod
    def convert_uuid_to_string(cls, v):
        if isinstance(v, UUID):
            return str(v)
        return v

    class Config:
        from_attributes = True
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }

class TrafficDataList(BaseModel):
    """Schema for paginated traffic data responses"""
    data: List[TrafficDataResponseDB]
    total: int = Field(..., description="Total number of records")
    page: int = Field(..., description="Current page number")
    per_page: int = Field(..., description="Records per page")
    has_next: bool = Field(..., description="Whether there are more pages")
    has_prev: bool = Field(..., description="Whether there are previous pages")

class TrafficAnalytics(BaseModel):
    """Schema for traffic analytics"""
    location_id: str
    period_start: datetime
    period_end: datetime
    avg_traffic_volume: Optional[float] = None
    avg_pedestrian_count: Optional[float] = None
    peak_traffic_hour: Optional[int] = None
    peak_pedestrian_hour: Optional[int] = None
    congestion_distribution: dict = Field(default_factory=dict)
    avg_speed: Optional[float] = None
    
class TrafficDataResponse(BaseModel):
    """Schema for API traffic data responses"""
    date: datetime = Field(..., description="Date and time of traffic measurement")
    traffic_volume: Optional[int] = Field(None, ge=0, description="Vehicles per hour")
    pedestrian_count: Optional[int] = Field(None, ge=0, description="Pedestrians per hour")
    congestion_level: Optional[str] = Field(None, pattern="^(low|medium|high)$", description="Traffic congestion level")
    average_speed: Optional[float] = Field(None, ge=0, le=200, description="Average speed in km/h")
    source: str = Field(..., description="Data source")
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }

class LocationRequest(BaseModel):
    latitude: float
    longitude: float
    address: Optional[str] = None

class DateRangeRequest(BaseModel):
    start_date: datetime
    end_date: datetime

class HistoricalTrafficRequest(BaseModel):
    latitude: float
    longitude: float
    start_date: datetime
    end_date: datetime

class TrafficForecastRequest(BaseModel):
    latitude: float
    longitude: float
    hours: int = 24