from datetime import datetime
from typing import List, Optional

from pydantic import BaseModel

from app.models import ProjectStatus, ReferentialType


class ReferentialItemCreate(BaseModel):
    type: ReferentialType
    code: str
    label: str
    value_numeric: Optional[float] = None
    value_text: Optional[str] = None
    unit: Optional[str] = None
    active: bool = True
    version: str = "v1"


class ReferentialItemRead(ReferentialItemCreate):
    id: int
    created_at: datetime
    updated_at: datetime


class PostalCodeCreate(BaseModel):
    postal_code: str
    commune: str
    insee_code: Optional[str] = None
    department_code: Optional[str] = None
    region: Optional[str] = None
    active: bool = True


class PostalCodeRead(PostalCodeCreate):
    id: int
    updated_at: datetime


class SavedProjectCreate(BaseModel):
    public_id: str
    status: ProjectStatus = ProjectStatus.DRAFT
    applicant_type: Optional[str] = None
    postal_code: Optional[str] = None
    commune: Optional[str] = None
    work_type: Optional[str] = None
    estimated_amount_ht: Optional[float] = None
    estimated_amount_ttc: Optional[float] = None
    aid_estimate: Optional[float] = None
    source: Optional[str] = "field"
    payload_json: str = "{}"


class SavedProjectUpdate(BaseModel):
    status: Optional[ProjectStatus] = None
    applicant_type: Optional[str] = None
    postal_code: Optional[str] = None
    commune: Optional[str] = None
    work_type: Optional[str] = None
    estimated_amount_ht: Optional[float] = None
    estimated_amount_ttc: Optional[float] = None
    aid_estimate: Optional[float] = None
    source: Optional[str] = None
    payload_json: Optional[str] = None


class SavedProjectRead(SavedProjectCreate):
    id: int
    created_at: datetime
    updated_at: datetime


class FieldInputEventCreate(BaseModel):
    project_public_id: Optional[str] = None
    field_name: str
    event_type: str
    value_length: Optional[int] = None
    error_code: Optional[str] = None
    step: Optional[str] = None
    source: Optional[str] = "field"


class StatsSummary(BaseModel):
    total_projects: int
    drafts: int
    simulations: int
    saved_projects: int
    archived: int
    total_input_events: int
    top_error_field: Optional[str] = None


class UserCreate(BaseModel):
    email: str
    password: str
    full_name: Optional[str] = None


class UserLogin(BaseModel):
    email: str
    password: str
    device_id: Optional[str] = None


class UserRead(BaseModel):
    id: int
    email: str
    full_name: Optional[str] = None
    role: str
    is_active: bool
    created_at: datetime


class AuthToken(BaseModel):
    access_token: str
    token_type: str = "bearer"
    user: UserRead


class PasswordResetRequest(BaseModel):
    email: str


class PasswordResetConfirm(BaseModel):
    token: str
    new_password: str


class SyncProjectPayload(BaseModel):
    id: str
    status: Optional[str] = "project_saved"
    title: Optional[str] = None
    subtitle: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    updatedAt: Optional[str] = None
    estimate: dict = {}
    snapshot: dict = {}


class SyncProjectsRequest(BaseModel):
    device_id: Optional[str] = None
    projects: List[SyncProjectPayload]


class SyncProjectsResponse(BaseModel):
    synced: int
    skipped: int
