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

# ====================================================
# Enum for Expense Types
# ====================================================
class ExpenseType(str, Enum):
    fuel = "fuel"             # Fuel expenses
    maintenance = "maintenance"  # Regular maintenance (oil change, service, etc.)
    toll = "toll"             # Toll charges
    repair = "repair"         # Repair costs
    insurance = "insurance"   # Insurance fees
    other = "other"           # Any other expense type

# ====================================================
# Base Model for Vehicle Expense Record
# ====================================================
class ExpenseRecordBase(BaseModel):
    vehicle_id: int = Field(..., description="Unique identifier for the vehicle related to the expense")
    expense_type: ExpenseType = Field(..., description="Type of expense (fuel, maintenance, toll, repair, insurance, other)")
    amount: float = Field(..., description="Expense amount in the appropriate currency")
    expense_date: datetime = Field(..., description="Date when the expense was incurred")
    description: Optional[str] = Field("", description="Detailed description or notes for the expense")
    receipt_url: Optional[str] = Field(None, description="URL or reference to the digital receipt/invoice")
    tags: List[str] = Field(default_factory=list, description="Optional tags to further categorize or group expenses")
    created_date: datetime = Field(default_factory=datetime.utcnow, description="Timestamp when the expense record was created")
    
    class Config:
        orm_mode = True

# ====================================================
# Model for Creating a New Expense Record
# ====================================================
class ExpenseRecordCreate(ExpenseRecordBase):
    pass

# ====================================================
# Model for Updating an Existing Expense Record
# ====================================================
class ExpenseRecordUpdate(BaseModel):
    vehicle_id: Optional[int] = Field(None, description="Updated vehicle identifier")
    expense_type: Optional[ExpenseType] = Field(None, description="Updated expense type")
    amount: Optional[float] = Field(None, description="Updated expense amount")
    expense_date: Optional[datetime] = Field(None, description="Updated expense date")
    description: Optional[str] = Field(None, description="Updated expense description or notes")
    receipt_url: Optional[str] = Field(None, description="Updated receipt URL")
    tags: Optional[List[str]] = Field(None, description="Updated tags for the expense")

# ====================================================
# Model for Reading an Expense Record (with unique ID)
# ====================================================
class ExpenseRecordRead(ExpenseRecordBase):
    expense_id: int = Field(..., description="Unique identifier for the expense record")

# ====================================================
# Model for Searching Expense Records
# ====================================================
class ExpenseRecordSearch(BaseModel):
    vehicle_id: Optional[int] = Field(None, description="Filter by vehicle identifier")
    expense_type: Optional[ExpenseType] = Field(None, description="Filter by expense type")
    expense_date_start: Optional[datetime] = Field(None, description="Filter expenses incurred after this date")
    expense_date_end: Optional[datetime] = Field(None, description="Filter expenses incurred before this date")
    min_amount: Optional[float] = Field(None, description="Minimum expense amount")
    max_amount: Optional[float] = Field(None, description="Maximum expense amount")
    tags: Optional[List[str]] = Field(None, description="Filter by associated tags")
