import json
from datetime import datetime

from fastapi import APIRouter, Depends
from sqlmodel import Session, select

from app.db import get_session
from app.models import ProjectStatus, SavedProject, UserAccount
from app.routers.auth import get_current_user
from app.schemas import SyncProjectsRequest, SyncProjectsResponse

router = APIRouter(prefix="/sync", tags=["sync"])


def parse_updated_at(value):
    if not value:
        return datetime.utcnow()
    try:
        return datetime.fromisoformat(str(value).replace("Z", "+00:00")).replace(tzinfo=None)
    except Exception:
        return datetime.utcnow()


def status_from_mobile(value):
    if value in ("draft", "Brouillon"):
        return ProjectStatus.DRAFT
    if value in ("simulation", "Simulation"):
        return ProjectStatus.SIMULATION
    if value in ("archived", "Archivé"):
        return ProjectStatus.ARCHIVED
    return ProjectStatus.PROJECT_SAVED


@router.post("/projects", response_model=SyncProjectsResponse)
def sync_projects(
    payload: SyncProjectsRequest,
    current_user: UserAccount = Depends(get_current_user),
    session: Session = Depends(get_session),
):
    synced = 0
    skipped = 0

    for mobile_project in payload.projects:
        if not mobile_project.id:
            skipped += 1
            continue

        snapshot = mobile_project.snapshot or {}
        estimate = mobile_project.estimate or {}
        updated_at = parse_updated_at(mobile_project.updatedAt)

        existing = session.exec(
            select(SavedProject).where(
                SavedProject.public_id == mobile_project.id,
                SavedProject.user_id == current_user.id,
            )
        ).first()

        project = existing or SavedProject(
            public_id=mobile_project.id,
            user_id=current_user.id,
            device_id=payload.device_id,
        )

        project.status = status_from_mobile(mobile_project.status)
        project.device_id = payload.device_id
        project.postal_code = snapshot.get("postalCode") or None
        project.commune = mobile_project.city or snapshot.get("city") or None
        project.work_type = snapshot.get("propertyType") or None
        project.estimated_amount_ht = estimate.get("worksHt")
        project.estimated_amount_ttc = estimate.get("worksTtc")
        project.source = "mobile-lite"
        project.payload_json = json.dumps(
            {
                "mobile_project": mobile_project.dict(),
                "synced_by_user_id": current_user.id,
            },
            ensure_ascii=False,
        )
        project.updated_at = updated_at

        session.add(project)
        synced += 1

    session.commit()
    return SyncProjectsResponse(synced=synced, skipped=skipped)
