# jobs.py (model file)
from enum import Enum
from datetime import datetime
from pydantic import BaseModel, Field
from typing import Optional, List, Dict

# ====================================================
# Enums for Job Stops, Job Status, and Job Types
# ====================================================
class JobStopType(str, Enum):
    pickup = "pickup"
    drop = "drop"

class JobStatus(str, Enum):
    pending = "pending"         # Job created, awaiting start
    active = "active"           # Job in progress
    completed = "completed"     # Job finished
    cancelled = "cancelled"     # Job aborted or not executed

# ====================================================
# Job Stop Model (represents a pickup or drop-off point)
# ====================================================
class JobStop(BaseModel):
    stop_type: JobStopType = Field(..., description="Indicates whether this stop is for pickup or drop-off")
    location: str = Field(..., description="Address or coordinates of the stop")
    sequence: int = Field(..., description="Order of the stop in the job")
    scheduled_time: Optional[datetime] = Field(None, description="Planned time for this stop")
    actual_time: Optional[datetime] = Field(None, description="Actual arrival time at this stop")

# ====================================================
# Job Model (represents a service task performed by workforce)
# ====================================================
class JobBase(BaseModel):
    service_id: int = Field(..., description="Reference to the service being provided")
    # Workforce and vehicle assignments are optional – some jobs might be self‑assigned or not require a vehicle.
    workforce_id: Optional[int] = Field(None, description="Assigned workforce member")
    vehicle_id: Optional[int] = Field(None, description="Assigned vehicle (if applicable)")
    customer_id: Optional[int] = Field(None, description="Customer booking the job (if applicable)")
    
    # A job can have multiple stops (e.g. multi‑pickup/drop scenarios)
    job_stops: List[JobStop] = Field(default_factory=list, description="List of stops (pickup/drop) for the job")
    
    # Timing fields: scheduled times versus actual times
    scheduled_start: Optional[datetime] = Field(None, description="Scheduled start time for the job")
    scheduled_end: Optional[datetime] = Field(None, description="Scheduled end time for the job")
    job_start: Optional[datetime] = Field(None, description="Actual start time of the job")
    job_end: Optional[datetime] = Field(None, description="Actual end time of the job")
    
    # Operational metrics
    distance_travelled: Optional[float] = Field(None, description="Distance traveled during the job (e.g. in kilometers)")
    cost: Optional[float] = Field(None, description="Cost of the job (computed from service pricing rules)")
    
    # Maximum capacity for the service – ensures that a workforce member does not accept more jobs than allowed concurrently
    capacity: Optional[int] = Field(None, description="Max capacity (number of simultaneous jobs) allowed for this service")
    
    status: JobStatus = Field(default=JobStatus.pending, description="Current status of the job")
    
    # A metadata field for additional customizable parameters (e.g. special instructions, extra details from the service model)
    metadata: Optional[Dict] = Field(default_factory=dict, description="Additional custom fields")
    
    created_date: datetime = Field(default_factory=datetime.utcnow, description="Timestamp when the job was created")
    
    class Config:
        orm_mode = True

class JobCreate(JobBase):
    pass

class JobUpdate(BaseModel):
    service_id: Optional[int] = Field(None)
    workforce_id: Optional[int] = Field(None)
    vehicle_id: Optional[int] = Field(None)
    customer_id: Optional[int] = Field(None)
    job_stops: Optional[List[JobStop]] = Field(None)
    scheduled_start: Optional[datetime] = Field(None)
    scheduled_end: Optional[datetime] = Field(None)
    job_start: Optional[datetime] = Field(None)
    job_end: Optional[datetime] = Field(None)
    distance_travelled: Optional[float] = Field(None)
    cost: Optional[float] = Field(None)
    capacity: Optional[int] = Field(None)
    status: Optional[JobStatus] = Field(None)
    metadata: Optional[Dict] = Field(None)

class JobRead(JobBase):
    job_id: int = Field(..., description="Unique identifier for the job")