"""FastAPI Router for Mobile Site Operations, MR, Telematics, 3-Way Matching, and IPC."""

from __future__ import annotations

from datetime import date

from fastapi import APIRouter, Depends, HTTPException, Query, status

from app.modules.auth.presentation.auth import require_role
from app.models.fuel_telematics_schemas import FuelTelematicsDashboardData
from app.models.ipc_export_schemas import IPCExport03aResponse
from app.models.matching_schemas import MatchingDashboardResponse
from app.models.site_operations_schemas import (
    MaterialRequisitionCreateRequest,
    MaterialRequisitionRecord,
    MRStatusEnum,
    SiteDiaryCreateRequest,
    SiteDiaryRecord,
)
from app.modules.operations.application.fuel_telematics_service import FuelTelematicsService
from app.modules.core.application.ipc_exporter_service import IPCExporterService
from app.modules.core.application.matching_service import ThreeWayMatchingService
from app.modules.operations.application.site_operations_service import SiteOperationsService

router = APIRouter(
    prefix="/v1", tags=["Site Operations & Advanced Construction Modules"]
)

site_service = SiteOperationsService()
fuel_service = FuelTelematicsService()
match_service = ThreeWayMatchingService()
ipc_service = IPCExporterService()


# --- Mobile Site Diary ---
@router.post(
    "/site/diaries",
    response_model=SiteDiaryRecord,
    status_code=status.HTTP_201_CREATED,
    dependencies=[
        Depends(require_role(["superadmin", "director", "pm", "site_engineer"]))
    ],
)
def create_site_diary(payload: SiteDiaryCreateRequest) -> SiteDiaryRecord:
    """Tạo nhật ký thi công hiện trường (Mobile PWA) kèm ảnh GPS và giờ máy."""
    return site_service.create_site_diary(payload)


@router.get(
    "/site/diaries",
    response_model=list[SiteDiaryRecord],
    dependencies=[
        Depends(require_role(["superadmin", "director", "pm", "site_engineer"]))
    ],
)
def list_site_diaries(
    project_code: str | None = Query(None, description="Lọc theo mã dự án"),
) -> list[SiteDiaryRecord]:
    """Danh sách nhật ký thi công hiện trường."""
    return site_service.list_site_diaries(project_code=project_code)


# --- Material Requisitions (MR) ---
@router.post(
    "/site/requisitions",
    response_model=MaterialRequisitionRecord,
    status_code=status.HTTP_201_CREATED,
    dependencies=[
        Depends(require_role(["superadmin", "director", "pm", "site_engineer"]))
    ],
)
def create_material_requisition(
    payload: MaterialRequisitionCreateRequest,
) -> MaterialRequisitionRecord:
    """Lập Phiếu Yêu Cầu Vật Tư (MR) trực tiếp từ công trường."""
    return site_service.create_material_requisition(payload)


@router.get(
    "/site/requisitions",
    response_model=list[MaterialRequisitionRecord],
    dependencies=[
        Depends(require_role(["superadmin", "director", "pm", "site_engineer"]))
    ],
)
def list_material_requisitions(
    project_code: str | None = Query(None, description="Lọc theo mã dự án"),
    status_filter: MRStatusEnum | None = Query(
        None, alias="status", description="Lọc theo trạng thái"
    ),
) -> list[MaterialRequisitionRecord]:
    """Danh sách Phiếu Yêu Cầu Cấp Vật Tư."""
    return site_service.list_requisitions(
        project_code=project_code, status=status_filter
    )


@router.patch(
    "/site/requisitions/{mr_id}/status",
    response_model=MaterialRequisitionRecord,
    dependencies=[Depends(require_role(["superadmin", "director", "pm"]))],
)
def update_requisition_status(
    mr_id: str,
    new_status: MRStatusEnum = Query(..., description="Trạng thái mới"),
    approver_name: str | None = Query(None, description="Người phê duyệt"),
) -> MaterialRequisitionRecord:
    """Phê duyệt hoặc từ chối Phiếu Yêu Cầu Vật Tư (MR)."""
    try:
        return site_service.update_mr_status(
            mr_id=mr_id, status=new_status, approver_name=approver_name
        )
    except KeyError:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Không tìm thấy phiếu MR {mr_id}",
        )


# --- Fuel Telematics & Equipment ---
@router.get(
    "/telematics/summary",
    response_model=FuelTelematicsDashboardData,
    dependencies=[
        Depends(
            require_role(["superadmin", "director", "pm", "mechanic", "accountant"])
        )
    ],
)
def get_fuel_telematics_summary(
    as_of_date: date | None = Query(None, description="Ngày chốt dữ liệu"),
) -> FuelTelematicsDashboardData:
    """Theo dõi định mức tiêu hao xăng dầu ca máy và lịch bảo dưỡng thiết bị."""
    return fuel_service.get_dashboard_summary(as_of_date=as_of_date)


# --- 3-Way Matching Engine ---
@router.get(
    "/matching/summary",
    response_model=MatchingDashboardResponse,
    dependencies=[Depends(require_role(["superadmin", "director", "accountant"]))],
)
def get_matching_summary(
    as_of_date: date | None = Query(None, description="Ngày chốt đối soát"),
) -> MatchingDashboardResponse:
    """Báo cáo đối soát 3 chiều: Đơn đặt hàng (PO) ⟷ Vé cân / Phiếu nhập kho (GRN) ⟷ Hóa đơn VAT."""
    return match_service.get_dashboard_summary(as_of_date=as_of_date)


# --- IPC Interim Payment Certificate (Mẫu 03a) ---
@router.get(
    "/ipc/03a",
    response_model=IPCExport03aResponse,
    dependencies=[
        Depends(require_role(["superadmin", "director", "pm", "accountant"]))
    ],
)
def generate_ipc_03a(
    project_code: str = Query(
        "DA-KM-BENKEM-2025-2026", description="Mã dự án xây dựng"
    ),
    period_number: int = Query(3, description="Đợt thanh toán số"),
    cutoff_date: date | None = Query(None, description="Ngày chốt khối lượng"),
) -> IPCExport03aResponse:
    """Xuất Bảng Xác Định Giá Trị Khối Lượng Hoàn Thành (Mẫu 03a theo NĐ 206/2026/NĐ-CP & FIDIC)."""
    return ipc_service.generate_ipc_03a(
        project_code=project_code, period_number=period_number, cutoff_date=cutoff_date
    )
