from datetime import datetime
from enum import Enum
from pydantic import BaseModel, Field
from typing import Optional, Dict

# ====================================================
# Enum for IoT Device Types
# ====================================================
class IoTDeviceType(str, Enum):
    obdii = "obdii"           # OBDII tracker for vehicle diagnostics
    gps = "gps"               # GPS tracking
    fuel = "fuel"             # Fuel tracking
    mobile = "mobile"         # Mobile phone tracking (e.g., workforce app)
    generic = "generic"       # Generic sensor

# ====================================================
# IoT Device / Sensor Models
# ====================================================
class IoTDeviceBase(BaseModel):
    device_name: str = Field(..., description="Name of the IoT device or sensor")
    device_type: IoTDeviceType = Field(..., description="Type of IoT device (e.g., obdii, gps, fuel, mobile)")
    installation_details: Optional[str] = Field("", description="Installation or mounting details")
    vehicle_id: Optional[int] = Field(None, description="Associated vehicle ID, if applicable")
    workforce_id: Optional[int] = Field(None, description="Associated workforce ID, if applicable")
    active: bool = Field(default=True, description="Device active status")
    
    class Config:
        orm_mode = True

class IoTDeviceCreate(IoTDeviceBase):
    pass

class IoTDeviceUpdate(BaseModel):
    device_name: Optional[str] = Field(None, description="Updated device name")
    device_type: Optional[IoTDeviceType] = Field(None, description="Updated device type")
    installation_details: Optional[str] = Field(None, description="Updated installation details")
    vehicle_id: Optional[int] = Field(None, description="Updated associated vehicle ID")
    workforce_id: Optional[int] = Field(None, description="Updated associated workforce ID")
    active: Optional[bool] = Field(None, description="Updated device active status")

class IoTDeviceRead(IoTDeviceBase):
    device_id: int = Field(..., description="Unique identifier for the IoT device")
    created_date: datetime = Field(default_factory=datetime.utcnow, description="Timestamp when the device was registered")

class IoTDeviceSearch(BaseModel):
    device_name: Optional[str] = Field(None, description="Search by device name")
    device_type: Optional[IoTDeviceType] = Field(None, description="Search by device type")
    vehicle_id: Optional[int] = Field(None, description="Filter by associated vehicle ID")
    workforce_id: Optional[int] = Field(None, description="Filter by associated workforce ID")
    active: Optional[bool] = Field(None, description="Filter by active status")

# ====================================================
# Telemetry Data Models
# ====================================================
class TelemetryDataBase(BaseModel):
    device_id: int = Field(..., description="ID of the IoT device sending the telemetry data")
    timestamp: datetime = Field(default_factory=datetime.utcnow, description="Timestamp for the telemetry data")
    # The payload can include any dynamic sensor data (GPS coordinates, fuel levels, idle time, etc.)
    payload: Dict[str, float] = Field(..., description="Dynamic sensor data (e.g., {'latitude': 40.7128, 'longitude': -74.0060, 'fuel_level': 75})")
    
    # Optionally relate telemetry data to higher-level entities:
    vehicle_id: Optional[int] = Field(None, description="Associated vehicle ID")
    job_id: Optional[int] = Field(None, description="Associated job ID")
    route_id: Optional[int] = Field(None, description="Associated route ID")
    service_id: Optional[int] = Field(None, description="Associated service ID")
    
    class Config:
        orm_mode = True

class TelemetryCreate(TelemetryDataBase):
    pass

class TelemetryRead(TelemetryDataBase):
    telemetry_id: int = Field(..., description="Unique telemetry record identifier")

class TelemetrySearch(BaseModel):
    device_id: Optional[int] = Field(None, description="Filter by IoT device ID")
    start_time: Optional[datetime] = Field(None, description="Filter records after this timestamp")
    end_time: Optional[datetime] = Field(None, description="Filter records before this timestamp")
    vehicle_id: Optional[int] = Field(None, description="Filter by associated vehicle ID")
