from datetime import datetime
from enum import Enum
from typing import Optional

from sqlmodel import Field, SQLModel


class ReferentialType(str, Enum):
    TARIFF = "tariff"
    SCALE = "scale"
    ELIGIBILITY_RULE = "eligibility_rule"
    MATERIAL = "material"
    WORK_TYPE = "work_type"


class ProjectStatus(str, Enum):
    DRAFT = "draft"
    SIMULATION = "simulation"
    PROJECT_SAVED = "project_saved"
    ARCHIVED = "archived"


class ReferentialItem(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    type: ReferentialType = Field(index=True)
    code: str = Field(index=True)
    label: str
    value_numeric: Optional[float] = None
    value_text: Optional[str] = None
    unit: Optional[str] = None
    active: bool = Field(default=True, index=True)
    version: str = Field(default="v1", index=True)
    created_at: datetime = Field(default_factory=datetime.utcnow)
    updated_at: datetime = Field(default_factory=datetime.utcnow)


class PostalCodeCommune(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    postal_code: str = Field(index=True)
    commune: str = Field(index=True)
    insee_code: Optional[str] = Field(default=None, index=True)
    department_code: Optional[str] = Field(default=None, index=True)
    region: Optional[str] = None
    active: bool = Field(default=True, index=True)
    updated_at: datetime = Field(default_factory=datetime.utcnow)


class SavedProject(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: Optional[int] = Field(default=None, index=True)
    device_id: Optional[str] = Field(default=None, index=True)
    public_id: str = Field(index=True, unique=True)
    status: ProjectStatus = Field(default=ProjectStatus.DRAFT, index=True)
    applicant_type: Optional[str] = Field(default=None, index=True)
    postal_code: Optional[str] = Field(default=None, index=True)
    commune: Optional[str] = Field(default=None, index=True)
    work_type: Optional[str] = Field(default=None, index=True)
    estimated_amount_ht: Optional[float] = None
    estimated_amount_ttc: Optional[float] = None
    aid_estimate: Optional[float] = None
    source: Optional[str] = Field(default="field", index=True)
    payload_json: str = Field(default="{}")
    created_at: datetime = Field(default_factory=datetime.utcnow, index=True)
    updated_at: datetime = Field(default_factory=datetime.utcnow, index=True)


class FieldInputEvent(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    project_public_id: Optional[str] = Field(default=None, index=True)
    field_name: str = Field(index=True)
    event_type: str = Field(index=True)
    value_length: Optional[int] = None
    error_code: Optional[str] = Field(default=None, index=True)
    step: Optional[str] = Field(default=None, index=True)
    source: Optional[str] = Field(default="field", index=True)
    created_at: datetime = Field(default_factory=datetime.utcnow, index=True)


class AuditLog(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    actor: str = Field(default="system", index=True)
    action: str = Field(index=True)
    entity_type: str = Field(index=True)
    entity_id: Optional[str] = Field(default=None, index=True)
    before_json: Optional[str] = None
    after_json: Optional[str] = None
    created_at: datetime = Field(default_factory=datetime.utcnow, index=True)
