"""Unit and Integration tests for the 4 Core Business Pillars of Cong ty TNHH Xay Dung Dinh Son (0202111150)."""

from __future__ import annotations

from decimal import Decimal

from fastapi.testclient import TestClient

from app.main import create_app
from app.models.four_pillars_schemas import (
    DispatchOrderCreateRequest,
    IPC03aExportRequest,
    ShiftLogVerificationStatus,
)
from app.modules.auth.application.auth_service import AuthService
from app.modules.financial.application.four_pillars_service import FourPillarsService


# --------------------------------------------------------------------------
# UNIT TESTS (DOMAIN SERVICE LEVEL)
# --------------------------------------------------------------------------
def test_pillar_1_ipc_03a_financial_precision():
    """Kiểm thử tính toán xuất hồ sơ IPC 03a chuẩn NĐ 206/2026/NĐ-CP với độ chính xác Decimal."""
    service = FourPillarsService()
    req = IPC03aExportRequest(
        project_code="DA-KM-BENKEM-2025-2026",
        period_number=3,
        advance_recovery_rate_pct=Decimal("10.0000"),
        retention_rate_pct=Decimal("5.0000"),
        vat_rate_pct=Decimal("8.0000"),
    )
    ipc = service.generate_ipc_document(req)

    assert ipc.contractor_tax_id == "0202111150"
    assert ipc.contractor_name == "CÔNG TY TNHH XÂY DỰNG ĐỊNH SƠN"
    assert ipc.period_number == 3
    assert len(ipc.items) == 4

    # Kiểm tra tổng giá trị hợp đồng và kỳ thanh toán
    assert ipc.total_contract_value > Decimal("5000000000.0000")
    assert ipc.period_work_value_pre_tax > Decimal("0.0000")

    # Kiểm tra khấu trừ tạm ứng (10%) và retention bảo hành (5%)
    expected_advance = (ipc.period_work_value_pre_tax * Decimal("0.1000")).quantize(
        Decimal("0.0001")
    )
    assert ipc.advance_recovery_amount == expected_advance

    expected_retention = (ipc.period_work_value_pre_tax * Decimal("0.0500")).quantize(
        Decimal("0.0001")
    )
    assert ipc.retention_deducted_amount == expected_retention

    # Kiểm tra giá trị thanh toán ròng và thuế VAT 8%
    expected_net = ipc.period_work_value_pre_tax - expected_advance - expected_retention
    assert ipc.net_payable_pre_tax == expected_net

    expected_vat = (expected_net * Decimal("0.0800")).quantize(Decimal("0.0001"))
    assert ipc.vat_amount == expected_vat
    assert ipc.total_net_payable_with_vat == (expected_net + expected_vat)


def test_pillar_1_3way_matching():
    """Kiểm thử đối chiếu 3 bên (BOQ vs Nghiệm thu A-B vs Hóa đơn)."""
    service = FourPillarsService()
    matches = service.get_3way_matching_details(project_code="DA-KM-BENKEM-2025-2026")

    assert len(matches) >= 3
    for m in matches:
        assert m.is_compliant is True
        assert m.status == "PERFECT_MATCH"
        assert m.amount_variance == Decimal("0.0000")


def test_pillar_2_fleet_logistics_thoat_nuoc_hp():
    """Kiểm thử Trụ cột 2: Vận tải xe ben Howo chở bùn đất Cty Thoát Nước Hải Phòng (0200149705)."""
    service = FourPillarsService()

    # 1. Tạo lệnh điều xe
    disp_req = DispatchOrderCreateRequest(
        truck_plate="15C-389.22",
        driver_name="Nguyễn Văn Hùng",
        partner_tax_id="0200149705",
        partner_name="Công ty TNHH MTV Thoát nước Hải Phòng",
        cargo_type="Bùn thải nạo vét cống ngầm",
        source_location="Mương An Kim Hải",
        dump_location="Bãi đổ Đình Vũ",
        scheduled_trips=4,
        estimated_volume_m3=Decimal("48.0000"),
    )
    order = service.create_dispatch_order(disp_req)

    assert order.partner_tax_id == "0200149705"
    assert order.fuel_standard_liters == Decimal("96.0000")  # 4 chuyến * 24L
    assert order.fuel_variance_pct == Decimal("2.0000")
    assert order.completed_trips == 4

    # 2. Đối soát vận chuyển bùn
    reconciliation = service.reconcile_sludge_transport(billing_period="2026-Q1")
    assert reconciliation.partner_tax_id == "0200149705"
    assert reconciliation.reconciliation_status == "MATCHED"
    assert reconciliation.amount_variance == Decimal("0.0000")
    assert reconciliation.total_volume_weighed_m3 == Decimal("4640.0000")


def test_pillar_3_equipment_rental_loan_khai():
    """Kiểm thử Trụ cột 3: Cho thuê máy đào Kobelco Cty Loan Khải (0201889988)."""
    service = FourPillarsService()
    reconciliation = service.reconcile_equipment_rental(equipment_code="EXC-KOBELCO-02")

    assert reconciliation.partner_tax_id == "0201889988"
    assert reconciliation.partner_name == "Công ty TNHH Vận tải và Thương mại Loan Khải"
    assert reconciliation.status == ShiftLogVerificationStatus.MATCHED
    assert reconciliation.total_shift_hours_logged == Decimal("160.0000")
    assert reconciliation.operator_timesheet_hours == Decimal("160.0000")
    assert reconciliation.invoiced_rental_hours == Decimal("160.0000")
    assert reconciliation.hours_discrepancy == Decimal("0.0000")
    assert reconciliation.oee_percentage > Decimal("80.0000")


def test_pillar_4_material_loss_and_quality_certs_trung_kien():
    """Kiểm thử Trụ cột 4: Hao hụt cát đá Cty Trung Kiên (0201805660) và kiểm toán CO/CQ."""
    service = FourPillarsService()

    # 1. Kiểm toán tỷ lệ hao hụt cát, đá
    loss_records = service.audit_material_loss(supplier_tax_id="0201805660")
    assert len(loss_records) == 2
    for rec in loss_records:
        assert rec.supplier_tax_id == "0201805660"
        assert rec.is_within_norm is True
        assert rec.actual_loss_rate_pct <= rec.standard_loss_norm_pct

    # 2. Rà soát chứng chỉ chất lượng CO/CQ & nén mẫu
    cert_audit = service.audit_quality_certificates()
    assert cert_audit.total_invoices_audited == 3
    assert cert_audit.fully_compliant_count == 2
    assert cert_audit.missing_lab_test_count >= 1
    assert cert_audit.held_payments_value_vnd > Decimal("0.0000")


# --------------------------------------------------------------------------
# INTEGRATION TESTS (API ROUTES & RBAC)
# --------------------------------------------------------------------------
def test_four_pillars_api_endpoints_authorized():
    """Kiểm thử toàn diện 7 REST API endpoints của 4 Trụ Cột qua TestClient."""
    app = create_app()
    app.dependency_overrides = {}
    client = TestClient(app)
    auth = AuthService()
    token = auth.create_jwt_token(
        {
            "id": "test-superadmin-id",
            "email": "son.dinhson@dscons.vn",
            "role": "superadmin",
            "full_name": "Nguyễn Sĩ Sơn",
            "company_id": "0202111150",
        }
    )
    headers = {"Authorization": f"Bearer {token}"}

    # 1. POST /v1/pillars/epc/ipc/export-03a
    res1 = client.post(
        "/v1/pillars/epc/ipc/export-03a",
        json={"project_code": "DA-KM-BENKEM-2025-2026", "period_number": 3},
        headers=headers,
    )
    assert res1.status_code == 200
    data1 = res1.json()
    assert data1["contractor_tax_id"] == "0202111150"
    assert "total_net_payable_with_vat" in data1

    # 2. GET /v1/pillars/epc/3-way-match/DA-KM-BENKEM-2025-2026
    res2 = client.get(
        "/v1/pillars/epc/3-way-match/DA-KM-BENKEM-2025-2026", headers=headers
    )
    assert res2.status_code == 200
    assert len(res2.json()) >= 3

    # 3. POST /v1/pillars/logistics/dispatch-orders
    res3 = client.post(
        "/v1/pillars/logistics/dispatch-orders",
        json={
            "truck_plate": "15C-389.22",
            "driver_name": "Lê Văn Tiến",
            "partner_tax_id": "0200149705",
            "partner_name": "Cty Thoát Nước Hải Phòng",
            "cargo_type": "Bùn cống ngầm",
            "source_location": "Lê Chân",
            "dump_location": "Đình Vũ",
            "scheduled_trips": 5,
            "estimated_volume_m3": "60.0000",
        },
        headers=headers,
    )
    assert res3.status_code == 200
    assert res3.json()["partner_tax_id"] == "0200149705"

    # 4. GET /v1/pillars/logistics/sludge-transport/reconcile
    res4 = client.get(
        "/v1/pillars/logistics/sludge-transport/reconcile?billing_period=2026-Q1",
        headers=headers,
    )
    assert res4.status_code == 200
    assert res4.json()["reconciliation_status"] == "MATCHED"

    # 5. GET /v1/pillars/equipment/rental-reconcile
    res5 = client.get(
        "/v1/pillars/equipment/rental-reconcile?equipment_code=EXC-KOBELCO-02",
        headers=headers,
    )
    assert res5.status_code == 200
    assert res5.json()["partner_tax_id"] == "0201889988"

    # 6. GET /v1/pillars/materials/loss-audit
    res6 = client.get(
        "/v1/pillars/materials/loss-audit?supplier_tax_id=0201805660", headers=headers
    )
    assert res6.status_code == 200
    assert len(res6.json()) >= 2

    # 7. GET /v1/pillars/materials/quality-certificates/audit
    res7 = client.get(
        "/v1/pillars/materials/quality-certificates/audit", headers=headers
    )
    assert res7.status_code == 200
    assert res7.json()["total_invoices_audited"] == 3


def test_four_pillars_api_unauthorized():
    """Kiểm thử từ chối truy cập 401 khi không truyền Token."""
    app = create_app()
    app.dependency_overrides = {}
    client = TestClient(app)
    res = client.get("/v1/pillars/materials/quality-certificates/audit")
    assert res.status_code == 401
