from __future__ import annotations

import logging
from typing import Any

from fastapi import (
    APIRouter,
    BackgroundTasks,
    Depends,
    Form,
    HTTPException,
)

from app.modules.auth.presentation.auth import require_role
from app.core.postgres.erp_client import ErpDatabaseClient
from app.modules.takeoff.application.drawing_takeoff_service import get_drawing_takeoff_service

from .schemas import SyncWbsRequest

logger = logging.getLogger("dscons.api.takeoff.crud")
router = APIRouter()


@router.post(
    "/{takeoff_id}/analyze",
    summary="Kích hoạt Bóc tách Khối lượng AI Vision cho Bản vẽ đã tải lên",
)
async def analyze_existing_drawing(
    takeoff_id: str,
    background_tasks: BackgroundTasks,
    drawing_hint: str = Form(
        "", description="Ghi chú cấu kiện / loại móng / vị trí kênh kè"
    ),
    run_async: bool = Form(True, description="Chạy ngầm bất đồng bộ"),
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Kích hoạt hoặc chạy lại bóc tách AI cho hồ sơ bản vẽ mà không cần tải lại file."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(status_code=404, detail="Không tìm thấy hồ sơ bản vẽ")

    # Robust boolean parsing for form data
    if isinstance(run_async, str):
        is_async_mode = run_async.strip().lower() not in (
            "false",
            "0",
            "no",
            "f",
            "off",
        )
    else:
        is_async_mode = bool(run_async)

    service = get_drawing_takeoff_service()
    if is_async_mode:
        client.update_drawing_takeoff(
            takeoff_id,
            {
                "takeoff_status": "processing",
                "ai_analysis_notes": "Đã xếp hàng yêu cầu bóc tách AI Quỳnh QS...",
            },
        )
        background_tasks.add_task(
            service.run_takeoff_pipeline,
            takeoff_id=takeoff_id,
            drawing_hint=drawing_hint,
        )
        return {
            "status": "processing",
            "message": "Đã khởi động tiến trình AI Quỳnh bóc tách khối lượng trong nền.",
            "takeoff_id": takeoff_id,
        }

    # Synchronous mode
    pipeline_result = await service.run_takeoff_pipeline(
        takeoff_id=takeoff_id, drawing_hint=drawing_hint
    )
    if pipeline_result.get("status") == "error":
        return pipeline_result

    takeoff_record = client.get_drawing_takeoff(takeoff_id) or {}
    items = client.list_drawing_takeoff_items(takeoff_id) or []
    metrics = {
        "total_estimated_cost_vnd": float(
            takeoff_record.get("total_estimated_cost_vnd") or 0
        ),
        "total_concrete_volume_m3": float(
            takeoff_record.get("total_concrete_volume_m3") or 0
        ),
        "total_rebar_weight_tons": float(
            takeoff_record.get("total_rebar_weight_tons") or 0
        ),
        "total_formwork_area_m2": float(
            takeoff_record.get("total_formwork_area_m2") or 0
        ),
        "total_earthwork_volume_m3": float(
            takeoff_record.get("total_earthwork_volume_m3") or 0
        ),
    }
    return {
        "status": "success",
        "takeoff": takeoff_record,
        "items": items,
        "metrics": metrics,
    }


@router.get(
    "/list",
    summary="Lấy danh sách các hồ sơ bóc tách bản vẽ kỹ thuật",
)
def list_takeoffs(
    project_id: str | None = None,
    limit: int = 50,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Danh sách các hồ sơ bóc tách bản vẽ."""
    client = ErpDatabaseClient()
    takeoffs = client.list_drawing_takeoffs(project_id=project_id, limit=limit)
    for t in takeoffs:
        if isinstance(t.get("pages_data"), str):
            try:
                t["pages_data"] = json.loads(t["pages_data"])
            except Exception:
                t["pages_data"] = []
    return {
        "status": "success",
        "total": len(takeoffs),
        "data": takeoffs,
    }


@router.get(
    "/{takeoff_id}",
    summary="Xem chi tiết bảng bóc tách khối lượng và công thức đo tính",
)
def get_takeoff_detail(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Chi tiết hồ sơ bóc tách và toàn bộ danh mục công tác BoQ."""
    client = ErpDatabaseClient()
    takeoff = client.get_drawing_takeoff(takeoff_id)
    if not takeoff:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy hồ sơ bóc tách bản vẽ"
        )

    if isinstance(takeoff.get("pages_data"), str):
        try:
            takeoff["pages_data"] = json.loads(takeoff["pages_data"])
        except Exception:
            takeoff["pages_data"] = []

    items = client.list_drawing_takeoff_items(takeoff_id)
    return {
        "status": "success",
        "takeoff": takeoff,
        "items": items,
    }


@router.post(
    "/{takeoff_id}/sync-wbs",
    summary="1-Click Đồng Bộ Khối Lượng Bóc Tách Sang Cây WBS Dự Án",
)
def sync_takeoff_to_wbs(
    takeoff_id: str,
    req: SyncWbsRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Đẩy các đầu mục công việc bóc tách vào cây WBS của Dự án chỉ với 1 click."""
    client = ErpDatabaseClient()
    res = client.sync_takeoff_to_project_wbs(
        takeoff_id=takeoff_id, project_id=req.project_id
    )
    return res
