"""FastAPI router for Invoice Item Recognition & Inventory / Equipment Truth Management.
Adheres strictly to Enterprise AEC DDD Architecture & RBAC controls.
"""

import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field

from app.modules.auth.presentation.auth import get_current_user, require_role
from app.modules.invoices.application.invoice_truth_extraction_service import InvoiceTruthExtractionService
from app.modules.inventory.application.warehouse_dispatch_service import WarehouseDispatchService

logger = logging.getLogger("dscons.api.inventory_truth")

router = APIRouter(
    prefix="/v1/erp/inventory-truth",
    tags=["ERP - Inventory & Equipment Truth Extraction"],
)
service = InvoiceTruthExtractionService()
dispatch_service = WarehouseDispatchService()


class ExtractTruthRequest(BaseModel):
    company_id: str | None = None
    purge_drafts: bool = Field(
        default=True, description="Xóa các thiết bị nháp cũ không rõ nguồn gốc hóa đơn"
    )


@router.post(
    "/extract-from-invoices",
    summary="Quét & Trích xuất Dữ liệu Truth từ Hóa Đơn Mua Vào",
)
async def extract_truth_from_invoices(
    req: ExtractTruthRequest = ExtractTruthRequest(),
    current_user: dict = Depends(
        require_role(["superadmin", "director", "accountant"])
    ),
) -> dict[str, Any]:
    """Tự động nhận diện nội dung hàng hóa từ hóa đơn mua vào:
    - Máy móc thiết bị (ĐVT: Chiếc/Cái/Bộ) -> Nhập vào Danh mục Thiết bị Sở hữu (erp_equipment).
    - Thuê ca máy (ĐVT: Ca/Giờ/Ngày) -> Ghi nhận chi phí thuê ca máy, không thêm tài sản.
    - Hàng hóa vật tư khác (Thép, Xi măng, Bê tông, Cát đá, Xăng dầu...) -> Nhập kho chờ xuất (erp_warehouse_inventory).
    """
    try:
        res = service.extract_and_sync_all_truth(
            company_id=req.company_id, purge_drafts=req.purge_drafts
        )
        return res
    except Exception as e:
        logger.error(f"Error extracting truth from invoices: {e}", exc_info=True)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi trích xuất dữ liệu Truth: {e!s}"
        )


@router.get("/warehouse", summary="Danh Sách Kho Vật Tư Nhập Từ Hóa Đơn (Chờ Xuất)")
async def get_warehouse_inventory(
    material_group: str | None = Query(
        None,
        description="Lọc theo nhóm vật tư: STEEL, CEMENT, AGGREGATE, CONCRETE, BRICK, PIPES_FITTINGS, FINISHING_PAINT, FUEL_OIL, SAFETY_EQUIPMENT",
    ),
    status: str | None = Query(
        None, description="Trạng thái tồn kho: CHỜ_XUẤT_CÔNG_TRƯỜNG, ĐÃ_NHẬP_KHO..."
    ),
    search: str | None = Query(
        None, description="Tìm theo tên vật tư, mã hiệu, nhà cung cấp, số HĐ"
    ),
    limit: int = Query(50, ge=1, le=500),
    offset: int = Query(0, ge=0),
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "accountant", "site_engineer", "warehouse_keeper"])
    ),
) -> dict[str, Any]:
    """Lấy danh sách vật tư nhập kho đang chờ xuất / xử lý từ hóa đơn mua vào."""
    try:
        items, total_count = service.list_warehouse_inventory(
            material_group=material_group,
            status=status,
            search=search,
            limit=limit,
            offset=offset,
        )
        return {
            "status": "success",
            "items": items,
            "total_count": total_count,
            "limit": limit,
            "offset": offset,
        }
    except Exception as e:
        logger.error(f"Error listing warehouse inventory: {e}", exc_info=True)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi tải danh sách kho vật tư: {e!s}"
        )


@router.get(
    "/equipment-truth", summary="Danh Sách Thiết Bị Sở Hữu Trích Xuất Từ Hóa Đơn"
)
async def get_truth_equipment(
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "accountant", "site_engineer", "mechanic"])
    ),
) -> dict[str, Any]:
    """Lấy danh sách máy móc, xe máy công trình sở hữu thực tế có chứng từ hóa đơn."""
    try:
        equipment = service.list_truth_equipment()
        return {
            "status": "success",
            "equipment": equipment,
            "total_count": len(equipment),
        }
    except Exception as e:
        logger.error(f"Error fetching truth equipment: {e}", exc_info=True)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi tải danh mục thiết bị sở hữu: {e!s}"
        )


@router.get("/summary", summary="Tổng Hợp Thống Kê Tài Sản & Kho Vật Tư Truth")
async def get_inventory_truth_summary(
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "accountant", "site_engineer"])
    ),
) -> dict[str, Any]:
    """Thống kê tổng hợp số lượng thiết bị sở hữu, giá trị tồn kho theo nhóm vật tư."""
    try:
        summary = service.get_truth_summary()
        return {"status": "success", "summary": summary}
    except Exception as e:
        logger.error(f"Error fetching truth summary: {e}", exc_info=True)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi tổng hợp thống kê kho & thiết bị: {e!s}"
        )


class CreateDispatchRequest(BaseModel):
    inventory_item_id: str
    quantity_dispatched: float = Field(..., gt=0, description="Khối lượng xuất kho")
    project_id: str | None = Field(default=None, description="ID Dự án nhận vật tư (Tùy chọn)")
    wbs_id: str | None = Field(default=None, description="ID Hạng mục WBS (Tùy chọn)")
    takeoff_item_id: str | None = Field(default=None, description="ID Công tác Dự toán bóc tách (Tùy chọn)")
    dispatch_date: str | None = Field(default=None, description="Ngày xuất kho (YYYY-MM-DD)")
    recipient_name: str | None = Field(default=None, description="Người nhận / Chỉ huy trưởng")
    transport_vehicle: str | None = Field(default=None, description="Biển số xe / Phương tiện")
    purpose: str | None = Field(default=None, description="Mục đích xuất kho")
    notes: str | None = Field(default=None, description="Ghi chú thêm")


@router.post("/dispatch", summary="Tạo Phiếu Xuất Kho Linh Hoạt (Công Trình / WBS / Dùng Chung)")
async def create_warehouse_dispatch(
    req: CreateDispatchRequest,
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "warehouse_keeper", "site_engineer"])
    ),
) -> dict[str, Any]:
    """Xuất kho vật tư linh hoạt ra công trường:
    - Không cứng nhắc: Hỗ trợ xuất theo dự án, theo WBS, hoặc xuất dùng chung/bảo dưỡng.
    - An toàn: Khóa dòng FOR UPDATE chống xuất âm, tự động trừ số lượng còn lại và cập nhật trạng thái.
    """
    try:
        res = dispatch_service.create_dispatch(
            inventory_item_id=req.inventory_item_id,
            quantity_dispatched=req.quantity_dispatched,
            project_id=req.project_id,
            wbs_id=req.wbs_id,
            takeoff_item_id=req.takeoff_item_id,
            dispatch_date=req.dispatch_date,
            recipient_name=req.recipient_name,
            transport_vehicle=req.transport_vehicle,
            purpose=req.purpose,
            notes=req.notes,
        )
        return {"status": "success", "dispatch": res}
    except ValueError as ve:
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error(f"Error creating warehouse dispatch: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Lỗi khi tạo phiếu xuất kho: {e!s}")


@router.get("/dispatches", summary="Lịch Sử Danh Sách Phiếu Xuất Kho")
async def list_warehouse_dispatches(
    project_id: str | None = Query(None, description="Lọc theo ID Dự án"),
    inventory_item_id: str | None = Query(None, description="Lọc theo Lô vật tư"),
    search: str | None = Query(None, description="Tìm theo mã phiếu, tên vật tư, người nhận..."),
    limit: int = Query(50, ge=1, le=500),
    offset: int = Query(0, ge=0),
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "accountant", "site_engineer", "warehouse_keeper"])
    ),
) -> dict[str, Any]:
    """Truy vấn lịch sử phiếu xuất kho vật tư kèm thông tin dự án và lô hóa đơn gốc."""
    try:
        items, total_count = dispatch_service.list_dispatches(
            project_id=project_id,
            inventory_item_id=inventory_item_id,
            search=search,
            limit=limit,
            offset=offset,
        )
        return {
            "status": "success",
            "items": items,
            "total_count": total_count,
            "limit": limit,
            "offset": offset,
        }
    except Exception as e:
        logger.error(f"Error listing warehouse dispatches: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Lỗi khi tải lịch sử xuất kho: {e!s}")


@router.get("/project-takeoffs", summary="Danh Sách Công Tác Dự Toán Của Dự Án Để Chọn Khi Xuất Kho")
async def get_project_takeoff_options(
    project_id: str = Query(..., description="ID Dự án"),
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "site_engineer", "qs"])
    ),
) -> dict[str, Any]:
    """Lấy danh sách các công tác bóc tách dự toán của dự án để hỗ trợ chọn nhanh khi lập phiếu xuất kho."""
    try:
        items = dispatch_service.get_project_takeoff_options(project_id=project_id)
        return {"status": "success", "items": items, "total_count": len(items)}
    except Exception as e:
        logger.error(f"Error getting project takeoff options: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Lỗi khi tải danh mục bóc tách dự án: {e!s}")


@router.get("/variance-report", summary="Báo Cáo Đối Chiếu Hao Hụt 3 Chiều: Dự Toán - Thực Xuất - Quyết Toán")
async def get_material_variance_report(
    project_id: str | None = Query(None, description="Lọc theo ID Dự án (Để trống để xem toàn công ty)"),
    current_user: dict = Depends(
        require_role(["superadmin", "director", "pm", "accountant", "qs"])
    ),
) -> dict[str, Any]:
    """Báo cáo đối chiếu 3 chiều giữa Khối lượng Dự toán bóc tách CAD (Q_đt), Thực xuất kho (Q_tx),
    và Nghiệm thu Quyết toán (Q_qt). Tính toán tỷ lệ hao hụt thực tế và so sánh với Định mức Thông tư 12/2021 & 2026.
    """
    try:
        report = dispatch_service.calculate_material_variance_report(project_id=project_id)
        return {"status": "success", "report": report}
    except Exception as e:
        logger.error(f"Error calculating material variance report: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Lỗi khi tính toán báo cáo hao hụt: {e!s}")
