from __future__ import annotations

import asyncio
from decimal import Decimal
from pathlib import Path
import pytest

from app.core.postgres.erp_client import ErpDatabaseClient
from app.modules.takeoff.application.service import get_drawing_takeoff_service
from app.modules.takeoff.application.tri_source_truth_grounding import TriSourceTruthGrounding

ONG_DEN_DIR = Path(r"C:\Projects\DSCons\HĐ-2026\Phòng KT xã Kiến Minh-2026\Cống hộp ông Đèn đến nhà bà Lanh")
DWG_PDF = ONG_DEN_DIR / "HSMT" / "Kenh Ong Den_ban ve.pdf"
HSMT_PDF = ONG_DEN_DIR / "HSMT" / "Biểu_mẫu_mời_thầu.pdf"
HSMT_XLSX = ONG_DEN_DIR / "Gói TCXL" / "phu luc 01&02.xlsx"


def test_ong_den_dataset_files_presence():
    """Verify that genuine design drawing and contract files for Ong Den culvert exist."""
    assert DWG_PDF.exists(), f"Design drawing PDF must exist at {DWG_PDF}"
    assert HSMT_PDF.exists(), f"HSMT PDF must exist at {HSMT_PDF}"
    assert HSMT_XLSX.exists(), f"HSMT Excel contract must exist at {HSMT_XLSX}"


def test_ong_den_drawing_sheets_structure():
    """Verify that the 28-sheet drawing book contains key geometric and rebar schedules."""
    import pymupdf

    assert DWG_PDF.exists(), f"Drawing PDF missing at {DWG_PDF}"
    doc = pymupdf.open(DWG_PDF)
    assert len(doc) == 28, f"Expected 28 sheets in drawing set, found {len(doc)}"

    # Sheet 1: Cover (Hồ sơ thiết kế bản vẽ thi công)
    assert doc[0].rect.width > doc[0].rect.height  # Landscape A3

    # All sheets are landscape drawings
    for i in range(len(doc)):
        assert doc[i].rect.width > doc[i].rect.height, f"Sheet {i+1} must be landscape A3/A4"


def test_ong_den_hsmt_pdf_extraction():
    """Verify statutory extraction of 66 items from Biểu_mẫu_mời_thầu.pdf."""
    service = get_drawing_takeoff_service()
    items = service.extract_hsmt_items_from_pdf(HSMT_PDF)

    assert len(items) == 66, f"Expected exactly 66 items in HSMT, got {len(items)}"
    # First item: Phát quang tạo mặt bằng (10.985 100m2)
    assert "Phát quang" in items[0]["item_name"]
    assert items[0]["quantity"] == 10.985
    # Cừ Larsen items
    larsen_items = [it for it in items if "larsen" in it["item_name"].lower()]
    assert len(larsen_items) >= 2


def test_ong_den_contract_excel_extraction():
    """Verify extraction of 66 items with authentic contract unit prices from phu luc 01&02.xlsx."""
    tri_engine = TriSourceTruthGrounding()
    excel_items = tri_engine.extract_hsmt_tender_items(HSMT_XLSX)

    assert len(excel_items) == 66, f"Expected 66 contract items, got {len(excel_items)}"
    # Verify first item (AA.11143)
    assert excel_items[0]["norm_code"] == "AA.11143"
    assert excel_items[0]["unit"] == "100m2"
    assert excel_items[0]["quantity"] == Decimal("10.9850")
    assert excel_items[0]["bid_rate"] > Decimal("700000.00")

    # Verify contract value sum matches official G_HD = 6,482,295,000 VND
    total_direct_cost = sum(it["total_amount"] for it in excel_items)
    assert abs(total_direct_cost - Decimal("6482295000.00")) < Decimal("1000.00")


@pytest.mark.anyio  # plugin anyio có sẵn; pytest-asyncio không được cài
async def test_ong_den_end_to_end_takeoff_pipeline():
    """Verify full end-to-end pipeline execution with clean DB teardown."""
    service = get_drawing_takeoff_service()
    db = ErpDatabaseClient()

    dwg_path = DWG_PDF

    result = await service.process_drawing_file(
        file_path=dwg_path,
        filename=dwg_path.name,
        drawing_hint="Cống hộp kênh ông Đèn đến nhà bà Lanh",
        attached_hsmt_path=HSMT_XLSX,
        attached_hsmt_filename="phu luc 01&02.xlsx",
    )

    assert result["status"] == "success"
    takeoff = result["takeoff"]
    items = result["items"]

    assert takeoff["confidence_score"] >= 98
    assert takeoff["confidence_level"] == "hsmt_verified"
    assert len(items) == 66
    assert takeoff["total_estimated_cost_vnd"] > 5_900_000_000.0

    # Clean teardown
    db.delete_drawing_takeoff(takeoff["id"])
