
from pydantic import BaseModel, Field, validator
from bson import ObjectId
from datetime import datetime, date
from typing import Optional, List
from enum import Enum

class FleetStatus(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    MAINTENANCE = "maintenance"

class VehicleStatus(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    MAINTENANCE = "maintenance"

class VehicleBase(BaseModel):
    vehicle_id: str = Field(..., description="Unique vehicle identifier (string)")
    registration_number: str = Field(..., min_length=2, max_length=20)
    vin_number: str = Field(..., min_length=17, max_length=17)
    vehicle_model_id: str = Field(..., description="Reference to vehicle model")
    color: str = Field(..., min_length=2, max_length=30)
    year: int = Field(..., gt=1900, le=datetime.now().year + 1)
    vehicle_image: str = Field(..., description="Image URL or path")
    insurance_number: Optional[str] = None
    insurance_expiry: Optional[date] = None
    vendor_id: str = Field(...)
    vendor_name: str
    dealer_id: str = Field(...)
    status: VehicleStatus = Field(default=VehicleStatus.ACTIVE)

class FleetBase(BaseModel):
    fleet_name: str = Field(..., min_length=2, max_length=50)
    description: Optional[str] = Field(None, max_length=200)
    status: FleetStatus = Field(default=FleetStatus.ACTIVE)

    # Flat vehicle info fields
    vehicle_id: Optional[str] = None
    registration_number: Optional[str] = None
    vin_number: Optional[str] = None
    vehicle_model_id: Optional[str] = None
    color: Optional[str] = None
    year: Optional[int] = None
    vehicle_image: Optional[str] = None
    insurance_number: Optional[str] = None
    insurance_expiry: Optional[date] = None
    vendor_id: Optional[str] = None
    dealer_id: Optional[str] = None
    fuel_type: Optional[str] = None
    vehicle_type: Optional[str] = None
    capacity: Optional[str] = None
    vendor_name: str
    tag_name: Optional[str] = None
    fleets_id: int
    can_fly: Optional[bool] = Field(default=False, description="True if the vehicle can fly (e.g., drone capabilities)")

class FleetCreate(FleetBase):
    account_id: str = ""
    user_id: str = ""

class Fleet(FleetCreate):
    id: str = Field(default=None, alias="_id")
    created_date: datetime = Field(default_factory=datetime.utcnow)
    updated_date: datetime = Field(default_factory=datetime.utcnow)

    class Config:
        json_encoders = {ObjectId: str}
        populate_by_name = True

class FleetResponse(BaseModel):
    fleet_id: str
    fleets_id: int
    account_id: Optional[str] = ""
    user_id: Optional[str] = ""
    fleet_name: str
    description: Optional[str] = None
    status: str

    # Flat vehicle fields
    vehicle_id: Optional[str] = None
    registration_number: Optional[str] = None
    vin_number: Optional[str] = None
    vehicle_model_id: Optional[str] = None
    color: Optional[str] = None
    year: Optional[int] = None
    vehicle_image: Optional[str] = None  # This should be a string URL
    insurance_number: Optional[str] = None
    insurance_expiry: Optional[date] = None
    vendor_id: Optional[str] = None
    vendor_name: Optional[str] = None
    tag_name: Optional[str] = None
    dealer_id: Optional[str] = None
    fuel_type: Optional[str] = None
    vehicle_type: Optional[str] = None
    capacity: Optional[str] = None
    can_fly: Optional[bool] = Field(default=False)

    created_date: datetime
    updated_date: datetime

    @validator('fleet_id', pre=True)
    def convert_objectid(cls, v):
        if isinstance(v, ObjectId):
            return str(v)
        return v
    
    @validator('vehicle_image', pre=True)
    def validate_image_url(cls, v):
        if v and isinstance(v, bytes):
            # Don't try to include binary data in the response
            return None
        return v

class FleetResponseList(BaseModel):
    total_count: int
    fleets: List[FleetResponse]

class FleetUpdate(BaseModel):
    fleet_name: Optional[str] = Field(None, min_length=2, max_length=50)
    description: Optional[str] = Field(None, max_length=200)
    status: Optional[FleetStatus] = None
    vehicles: Optional[List[VehicleBase]] = None