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


class RouteStatus(str, Enum):
    ACTIVE = "Active"
    INACTIVE = "Inactive"


class AirportBase(BaseModel):
    code: str = Field(..., min_length=3, max_length=3)
    name: str
    city: str
    country: str
    timezone: str
    latitude: Optional[str] = None
    longitude: Optional[str] = None

    @field_validator("code")
    @classmethod
    def validate_code_uppercase(cls, v: str) -> str:
        if not v.isupper():
            raise ValueError("Airport code must be uppercase")
        if not v.isalpha():
            raise ValueError("Airport code must contain only letters")
        return v


class AirportCreate(AirportBase):
    pass


class AirportUpdate(BaseModel):
    code: Optional[str] = Field(None, min_length=3, max_length=3)
    name: Optional[str] = None
    city: Optional[str] = None
    country: Optional[str] = None
    timezone: Optional[str] = None
    latitude: Optional[str] = None
    longitude: Optional[str] = None

    @field_validator("code")
    @classmethod
    def validate_code_uppercase(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v.isupper():
                raise ValueError("Airport code must be uppercase")
            if not v.isalpha():
                raise ValueError("Airport code must contain only letters")
        return v


class AirportResponse(AirportBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class RouteBase(BaseModel):
    origin_airport_id: str
    destination_airport_id: str
    distance_km: int
    estimated_duration_minutes: int
    status: RouteStatus = RouteStatus.ACTIVE

    @field_validator("distance_km")
    @classmethod
    def validate_distance_positive(cls, v: int) -> int:
        if v <= 0:
            raise ValueError("Route distance_km must be greater than 0")
        return v

    @field_validator("estimated_duration_minutes")
    @classmethod
    def validate_duration_positive(cls, v: int) -> int:
        if v <= 0:
            raise ValueError("Route estimated_duration_minutes must be greater than 0")
        return v


class RouteCreate(RouteBase):
    pass


class RouteUpdate(BaseModel):
    origin_airport_id: Optional[str] = None
    destination_airport_id: Optional[str] = None
    distance_km: Optional[int] = None
    estimated_duration_minutes: Optional[int] = None
    status: Optional[RouteStatus] = None

    @field_validator("distance_km")
    @classmethod
    def validate_distance_positive(cls, v: Optional[int]) -> Optional[int]:
        if v is not None and v <= 0:
            raise ValueError("Route distance_km must be greater than 0")
        return v

    @field_validator("estimated_duration_minutes")
    @classmethod
    def validate_duration_positive(cls, v: Optional[int]) -> Optional[int]:
        if v is not None and v <= 0:
            raise ValueError("Route estimated_duration_minutes must be greater than 0")
        return v


class RouteResponse(RouteBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class RouteDetailResponse(BaseModel):
    id: str
    origin_airport_id: str
    destination_airport_id: str
    distance_km: int
    estimated_duration_minutes: int
    status: RouteStatus
    created_at: datetime
    updated_at: datetime
    origin_airport: AirportResponse
    destination_airport: AirportResponse

    model_config = ConfigDict(from_attributes=True)