from pydantic import BaseModel, Field
from typing import Optional, Literal
from datetime import datetime
from enum import Enum
from bson import ObjectId


class DeviceStatus(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    FAULTY = "faulty"


class DeviceType(str, Enum):
    OBDII = "obdii"
    MOBILE = "mobile"
    DASHCAM = "dashcam"
    SEAT_SENSOR = "seat_sensor"
    HEAT_SENSOR = "heat_sensor"
    GPS = "gps"
    OTHERS = "others"


class AssociatedEntityType(str, Enum):
    VEHICLE = "vehicle"
    WORKFORCE = "workforce"


class IotDeviceBase(BaseModel):
    account_id: str
    user_id: Optional[str] = None
    associated_entity_type: AssociatedEntityType
    associated_entity_id: str
    device_type: DeviceType
    installation_details: str
    status: DeviceStatus
    last_updated: datetime = Field(default_factory=datetime.utcnow)
    model_name: Optional[str] = None
    uuid: Optional[str] = None


class IotDeviceCreate(IotDeviceBase):
    pass


class IotDeviceUpdate(BaseModel):
    user_id: Optional[str] = None
    associated_entity_type: Optional[AssociatedEntityType] = None
    associated_entity_id: Optional[str] = None
    device_type: Optional[DeviceType] = None
    installation_details: Optional[str] = None
    status: Optional[DeviceStatus] = None
    last_updated: Optional[datetime] = Field(default_factory=datetime.utcnow)


class IotDevice(IotDeviceBase):
    id: Optional[str] = None
    created_date: datetime = Field(default_factory=datetime.utcnow)

    class Config:
        json_encoders = {ObjectId: str}


class IotDeviceList(BaseModel):
    total_count: int
    users: list[IotDevice]

class FleetMappedDetails(BaseModel):
    type: Literal["fleet"]
    fleet_id: str
    fleet_name: Optional[str] = None
    registration_number: Optional[str] = None
    vehicle_type: Optional[str] = None
    status: Optional[str] = None


class WorkforceMappedDetails(BaseModel):
    type: Literal["workforce"]
    workforce_id: str
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    mobile_number: Optional[str] = None
    email_id: Optional[str] = None
    status: Optional[str] = None


class IotDeviceWithMapping(IotDevice):
    mapped_details: Optional[FleetMappedDetails | WorkforceMappedDetails] = None
    distance_km: Optional[float] = None   # ✅ add this

class IotDeviceWithMappingList(BaseModel):
    total_count: int
    devices: list[IotDeviceWithMapping]

class NearbyDevicesRequest(BaseModel):
    latitude: float
    longitude: float
    radius_km: float = 5.0
    skip: int = 0
    limit: int = 10
