"""Unit and integration tests for Debt Ledgers (131, 331) and Fixed Assets (211/214) Source of Truth."""

from datetime import date
from decimal import Decimal
import os
import pytest
from fastapi.testclient import TestClient

from app.main import create_app
from app.modules.auth.presentation.auth import get_current_user
from app.modules.financial.application.debt_ledger_sync_service import (
    DEFAULT_FINANCE_FOLDER,
    DebtLedgerSyncService,
)


@pytest.fixture
def sync_service() -> DebtLedgerSyncService:
    return DebtLedgerSyncService()


@pytest.fixture
def auth_client() -> TestClient:
    app = create_app()
    app.dependency_overrides[get_current_user] = lambda: {
        "id": "director-test-id",
        "email": "director@dscons.vn",
        "role": "director",
        "full_name": "Nguyễn Sĩ Sơn",
    }
    return TestClient(app)


@pytest.fixture
def unauth_client() -> TestClient:
    app = create_app()
    return TestClient(app)


def test_excel_files_exist():
    """Đảm bảo thư mục và 3 file Excel sổ công nợ 2026 thực tế tồn tại đầy đủ."""
    assert os.path.isdir(DEFAULT_FINANCE_FOLDER)
    f_thu = os.path.join(DEFAULT_FINANCE_FOLDER, "Tong_hop_cong_no_phai_thu 31.3.2026.xls")
    f_tra = os.path.join(DEFAULT_FINANCE_FOLDER, "Tong_hop_cong_no_phai_tra 31.3.2026.xls")
    f_ts = os.path.join(DEFAULT_FINANCE_FOLDER, "So_tai_san_co_dinh Q1.2026.xls")

    assert os.path.exists(f_thu)
    assert os.path.exists(f_tra)
    assert os.path.exists(f_ts)


def test_sync_all_from_folder_integrity(sync_service: DebtLedgerSyncService):
    """Kiểm tra quá trình nạp toàn bộ 3 file Excel vào database và đối soát số dư."""
    res = sync_service.sync_all_from_folder()

    assert "receivables" in res
    assert "payables" in res
    assert "fixed_assets" in res

    # 1. Phải thu (131)
    rec = res["receivables"]
    assert rec["status"] == "success"
    assert rec["records_count"] == 26
    assert rec["total_closing_debit_vnd"] == Decimal("2289477746")
    assert rec["total_closing_credit_vnd"] == Decimal("1282283442")

    # 2. Phải trả (331)
    pay = res["payables"]
    assert pay["status"] == "success"
    assert pay["records_count"] == 35
    assert pay["total_closing_debit_vnd"] == Decimal("1112743700")
    assert pay["total_closing_credit_vnd"] == Decimal("2539165129")

    # 3. Tài sản cố định (211/214)
    fa = res["fixed_assets"]
    assert fa["status"] == "success"
    assert fa["assets_count"] == 11
    assert fa["total_original_cost_vnd"] == Decimal("8572332222")
    assert fa["total_net_book_value_vnd"] == Decimal("7911806062")


def test_consolidated_overview_calculation(sync_service: DebtLedgerSyncService):
    """Kiểm tra báo cáo hợp nhất công nợ và tài sản cố định."""
    overview = sync_service.get_consolidated_overview()

    assert overview.as_of_date == date(2026, 3, 31)
    assert overview.period_name == "Q1.2026"
    assert overview.receivables_summary.total_partners == 26
    assert overview.payables_summary.total_partners == 35
    assert overview.fixed_assets_summary.total_assets == 11

    # Kiểm tra tính toán vị thế công nợ thương mại ròng
    # Net phai thu: 2,289,477,746 - 1,282,283,442 = 1,007,194,304
    expected_net_rec = Decimal("2289477746.0000") - Decimal("1282283442.0000")
    assert overview.net_working_capital_receivable_vnd == expected_net_rec

    # Net phai tra: 2,539,165,129 - 1,112,743,700 = 1,426,421,429
    expected_net_pay = Decimal("2539165129.0000") - Decimal("1112743700.0000")
    assert overview.net_working_capital_payable_vnd == expected_net_pay

    # Net Trade Debt Position: 1,007,194,304 - 1,426,421,429 = -419,227,125
    expected_net_trade = expected_net_rec - expected_net_pay
    assert overview.net_trade_debt_balance_vnd == expected_net_trade


def test_api_receivables_endpoint(auth_client: TestClient):
    """Kiểm tra API lấy danh sách 26 khách hàng nợ TK 131."""
    res = auth_client.get("/v1/erp/finance/receivables")
    assert res.status_code == 200
    data = res.json()
    assert data["account_code"] == "131"
    assert data["debt_type"] == "receivable"
    assert len(data["items"]) == 26
    assert data["summary"]["total_partners"] == 26

    partner_codes = [item["partner_code"] for item in data["items"]]
    assert "THỦY LỢI ĐA ĐỘ" in partner_codes
    assert "RANGDONG" in partner_codes
    assert "AVN" in partner_codes


def test_api_payables_endpoint(auth_client: TestClient):
    """Kiểm tra API lấy danh sách 35 nhà cung cấp nợ TK 331."""
    res = auth_client.get("/v1/erp/finance/payables")
    assert res.status_code == 200
    data = res.json()
    assert data["account_code"] == "331"
    assert data["debt_type"] == "payable"
    assert len(data["items"]) == 35
    assert data["summary"]["total_partners"] == 35

    partner_codes = [item["partner_code"] for item in data["items"]]
    assert "ANH QUANG" in partner_codes
    assert "THACO AUTO" in partner_codes
    assert "TRUNGKIEN" in partner_codes


def test_api_fixed_assets_endpoint(auth_client: TestClient):
    """Kiểm tra API lấy danh mục 11 tài sản cố định và hao mòn lũy kế."""
    res = auth_client.get("/v1/erp/finance/fixed-assets")
    assert res.status_code == 200
    data = res.json()
    assert len(data["items"]) == 11
    assert data["summary"]["total_assets"] == 11

    asset_codes = [item["asset_code"] for item in data["items"]]
    assert any("PC200-7" in c for c in asset_codes)
    assert any("15H-10624" in c for c in asset_codes)
    assert any("15H-28352" in c for c in asset_codes)
    assert any("PC300LC" in c for c in asset_codes)


def test_api_debt_ledger_validation(auth_client: TestClient):
    """Kiểm tra validation tài khoản hợp lệ."""
    # 131 và 331 hợp lệ
    assert auth_client.get("/v1/erp/finance/debt-ledger?account_code=131").status_code == 200
    assert auth_client.get("/v1/erp/finance/debt-ledger?account_code=331").status_code == 200

    # Tài khoản không hợp lệ -> 400
    bad_res = auth_client.get("/v1/erp/finance/debt-ledger?account_code=999")
    assert bad_res.status_code == 400


def test_api_unauthenticated_access_blocked(unauth_client: TestClient):
    """Kiểm tra chặn truy cập khi chưa xác thực."""
    res = unauth_client.get("/v1/erp/finance/consolidated-overview")
    assert res.status_code == 401


def test_q2_ledgers_and_api(auth_client: TestClient):
    """Kiểm tra sổ sách và API Quý 2/2026 (mốc 30/06/2026)."""
    q2_dir = os.path.join(DEFAULT_FINANCE_FOLDER, "Q2")
    assert os.path.isdir(q2_dir)
    assert os.path.exists(os.path.join(q2_dir, "Tong_hop_cong_no_phai_thu 30.6.2026.xlsx"))
    assert os.path.exists(os.path.join(q2_dir, "Tong_hop_cong_no_phai_tra 30.6.2026.xlsx"))
    assert os.path.exists(os.path.join(q2_dir, "So_tai_san_co_dinh Q2.2026.xlsx"))
    assert os.path.exists(os.path.join(q2_dir, "So_theo_doi_vay_ngan_hang_VPBank_Q2.2026.xlsx"))

    # Gọi API lấy hợp nhất Q2
    res = auth_client.get("/v1/erp/finance/consolidated-overview?as_of_date=2026-06-30")
    assert res.status_code == 200
    data = res.json()
    assert data["as_of_date"] == "2026-06-30"
    assert data["receivables_summary"]["total_partners"] == 33
    assert data["payables_summary"]["total_partners"] == 71
    assert data["fixed_assets_summary"]["total_assets"] == 13
    assert Decimal(str(data["fixed_assets_summary"]["total_original_cost_vnd"])) == Decimal("11433443334.0000")
    assert Decimal(str(data["net_trade_debt_balance_vnd"])) == Decimal("2092824005.0000")


