"""Script to generate Q2/2026 Accounting Ledgers (TK 131, TK 331, TK 211/214) with line-by-line bank reconciliation."""

from __future__ import annotations

import os
from datetime import date
from decimal import Decimal
from typing import Any
from uuid import UUID

import openpyxl
from openpyxl.styles import Alignment, Border, Font, PatternFill, Side

from app.core.postgres.base_pkg.base_client import BasePostgresClient
from app.modules.financial.application.debt_ledger_sync_service import DebtLedgerSyncService

OUTPUT_DIR = r"C:\Projects\DSCons\Finance\Sổ công nợ 2026\Q2"
os.makedirs(OUTPUT_DIR, exist_ok=True)


def format_excel_header(ws: Any, title: str, subtitle: str) -> None:
    font_bold = Font(name="Arial", size=10, bold=True)
    font_title = Font(name="Arial", size=14, bold=True)
    font_italic = Font(name="Arial", size=10, italic=True)

    ws.merge_cells("A1:G1")
    ws["A1"] = "CÔNG TY TNHH XÂY DỰNG ĐỊNH SƠN"
    ws["A1"].font = font_bold

    ws.merge_cells("A2:I2")
    ws["A2"] = "Thôn 1 (tại nhà ông Nguyễn Sĩ Định), Xã Nghi Dương, Thành phố Hải Phòng, Việt Nam"
    ws["A2"].font = Font(name="Arial", size=9)

    ws.merge_cells("A3:M3")
    ws["A3"] = title
    ws["A3"].font = font_title
    ws["A3"].alignment = Alignment(horizontal="center", vertical="center")

    ws.merge_cells("A4:M4")
    ws["A4"] = subtitle
    ws["A4"].font = font_italic
    ws["A4"].alignment = Alignment(horizontal="center", vertical="center")


def apply_table_styling(ws: Any, start_row: int, end_row: int, max_col: int) -> None:
    thin_border = Border(
        left=Side(style="thin", color="CCCCCC"),
        right=Side(style="thin", color="CCCCCC"),
        top=Side(style="thin", color="CCCCCC"),
        bottom=Side(style="thin", color="CCCCCC"),
    )
    num_format = "#,##0"

    for r in range(start_row, end_row + 1):
        for c in range(1, max_col + 1):
            cell = ws.cell(row=r, column=c)
            cell.border = thin_border
            if not cell.font or cell.font.name != "Arial":
                cell.font = Font(name="Arial", size=9)
            if isinstance(cell.value, (int, float, Decimal)):
                cell.number_format = num_format
                cell.alignment = Alignment(horizontal="right", vertical="center")


def generate_q2_fixed_assets(client: BasePostgresClient, company_id: UUID) -> dict[str, Any]:
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT asset_code, asset_name, asset_type, department,
                       increase_date, voucher_number, depreciation_start_date,
                       useful_life_months, remaining_life_months,
                       original_cost_vnd, depreciable_value_vnd,
                       period_depreciation_vnd, accumulated_depreciation_vnd,
                       net_book_value_vnd, monthly_depreciation_vnd,
                       cost_account, depreciation_account, matched_equipment_id
                FROM erp_fixed_assets
                WHERE as_of_date = '2026-03-31'
                ORDER BY increase_date ASC
                """
            )
            q1_assets = cur.fetchall()

    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "Page 1"

    format_excel_header(
        ws,
        title="SỔ TÀI SẢN CỐ ĐỊNH",
        subtitle="Quý 2 năm 2026 (Từ 01/04/2026 đến 30/06/2026)",
    )

    headers_row6 = [
        "Mã TSCĐ", "Tên TSCĐ", "Loại TSCĐ", "Đơn vị sử dụng", "Ngày ghi tăng",
        "Số CT ghi tăng", "Ngày bắt đầu tính KH", "Thời gian SD (tháng)",
        "Thời gian SD còn lại (tháng)", "Nguyên giá", "Giá trị tính KH",
        "Hao mòn trong kỳ", "Hao mòn lũy kế", "Giá trị còn lại",
        "Giá trị KH tháng", "TK nguyên giá", "TK khấu hao"
    ]

    header_font = Font(name="Arial", size=9, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="1E293B", end_color="1E293B", fill_type="solid")

    for col_idx, h in enumerate(headers_row6, start=1):
        cell = ws.cell(row=6, column=col_idx, value=h)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)

    row_idx = 7
    tot_orig = Decimal("0")
    tot_calc_kh = Decimal("0")
    tot_period_hm = Decimal("0")
    tot_acc_hm = Decimal("0")
    tot_net = Decimal("0")
    tot_month_kh = Decimal("0")
    tot_sd = 0
    tot_rem = 0

    q2_records = []
    for a in q1_assets:
        orig = a["original_cost_vnd"]
        m_kh = a["monthly_depreciation_vnd"]
        q2_hm = m_kh * Decimal("3")
        acc_hm = a["accumulated_depreciation_vnd"] + q2_hm
        net_val = orig - acc_hm
        rem_m = max(0, a["remaining_life_months"] - 3)

        tot_orig += orig
        tot_calc_kh += a["depreciable_value_vnd"]
        tot_period_hm += q2_hm
        tot_acc_hm += acc_hm
        tot_net += net_val
        tot_month_kh += m_kh
        tot_sd += a["useful_life_months"]
        tot_rem += rem_m

        row_vals = [
            a["asset_code"],
            a["asset_name"],
            a["asset_type"],
            a["department"],
            a["increase_date"].strftime("%d/%m/%Y") if a["increase_date"] else "",
            a["voucher_number"] or "",
            a["depreciation_start_date"].strftime("%d/%m/%Y") if a["depreciation_start_date"] else "",
            a["useful_life_months"],
            rem_m,
            orig,
            a["depreciable_value_vnd"],
            q2_hm,
            acc_hm,
            net_val,
            m_kh,
            a["cost_account"],
            a["depreciation_account"],
        ]

        for col_idx, val in enumerate(row_vals, start=1):
            ws.cell(row=row_idx, column=col_idx, value=val)

        q2_records.append({
            "asset_code": a["asset_code"],
            "asset_name": a["asset_name"],
            "asset_type": a["asset_type"],
            "department": a["department"],
            "increase_date": a["increase_date"],
            "voucher_number": a["voucher_number"],
            "depreciation_start_date": a["depreciation_start_date"],
            "useful_life_months": a["useful_life_months"],
            "remaining_life_months": rem_m,
            "original_cost_vnd": orig,
            "depreciable_value_vnd": a["depreciable_value_vnd"],
            "period_depreciation_vnd": q2_hm,
            "accumulated_depreciation_vnd": acc_hm,
            "net_book_value_vnd": net_val,
            "monthly_depreciation_vnd": m_kh,
            "cost_account": a["cost_account"],
            "depreciation_account": a["depreciation_account"],
            "matched_equipment_id": a["matched_equipment_id"],
        })
        row_idx += 1

    # Bổ sung 2 xe ben Howo CNHTC mua mới trong Quý 2/2026 (ngày 06/04/2026 theo HĐ C26TTK-00000022 và C26TTK-00000023, đăng kiểm 15H-288.44 và 34H-048.48)
    new_howo_trucks = [
        {
            "asset_code": "Xe ô tô tải 15H-28844",
            "asset_name": "Xe ô tô tải tự đổ BKS 15H-288.44",
            "asset_type": "Phương tiện vận tải",
            "department": "CÔNG TY TNHH XÂY DỰNG ĐỊNH SƠN",
            "increase_date": date(2026, 4, 6),
            "voucher_number": "C26TTK-00000022",
            "depreciation_start_date": date(2026, 4, 6),
            "useful_life_months": 84,
            "remaining_life_months": 81,
            "original_cost_vnd": Decimal("1430555556.0000"),
            "depreciable_value_vnd": Decimal("1430555556.0000"),
            "monthly_depreciation_vnd": Decimal("17030423.0000"),
            "period_depreciation_vnd": Decimal("51091269.0000"),
            "accumulated_depreciation_vnd": Decimal("51091269.0000"),
            "net_book_value_vnd": Decimal("1379464287.0000"),
            "cost_account": "2113",
            "depreciation_account": "2141",
            "equipment_code": "EQ-TRUTH-TRU-024",
            "license_plate": "15H-288.44",
        },
        {
            "asset_code": "Xe ô tô tải 34H-04848",
            "asset_name": "Xe ô tô tải tự đổ BKS 34H-048.48",
            "asset_type": "Phương tiện vận tải",
            "department": "CÔNG TY TNHH XÂY DỰNG ĐỊNH SƠN",
            "increase_date": date(2026, 4, 6),
            "voucher_number": "C26TTK-00000023",
            "depreciation_start_date": date(2026, 4, 6),
            "useful_life_months": 84,
            "remaining_life_months": 81,
            "original_cost_vnd": Decimal("1430555556.0000"),
            "depreciable_value_vnd": Decimal("1430555556.0000"),
            "monthly_depreciation_vnd": Decimal("17030423.0000"),
            "period_depreciation_vnd": Decimal("51091269.0000"),
            "accumulated_depreciation_vnd": Decimal("51091269.0000"),
            "net_book_value_vnd": Decimal("1379464287.0000"),
            "cost_account": "2113",
            "depreciation_account": "2141",
            "equipment_code": "EQ-TRUTH-TRU-025",
            "license_plate": "34H-048.48",
        },
    ]

    for truck in new_howo_trucks:
        orig = truck["original_cost_vnd"]
        m_kh = truck["monthly_depreciation_vnd"]
        q2_hm = truck["period_depreciation_vnd"]
        acc_hm = truck["accumulated_depreciation_vnd"]
        net_val = truck["net_book_value_vnd"]
        rem_m = truck["remaining_life_months"]

        tot_orig += orig
        tot_calc_kh += truck["depreciable_value_vnd"]
        tot_period_hm += q2_hm
        tot_acc_hm += acc_hm
        tot_net += net_val
        tot_month_kh += m_kh
        tot_sd += truck["useful_life_months"]
        tot_rem += rem_m

        row_vals = [
            truck["asset_code"],
            truck["asset_name"],
            truck["asset_type"],
            truck["department"],
            truck["increase_date"].strftime("%d/%m/%Y"),
            truck["voucher_number"],
            truck["depreciation_start_date"].strftime("%d/%m/%Y"),
            truck["useful_life_months"],
            rem_m,
            orig,
            truck["depreciable_value_vnd"],
            q2_hm,
            acc_hm,
            net_val,
            m_kh,
            truck["cost_account"],
            truck["depreciation_account"],
        ]

        for col_idx, val in enumerate(row_vals, start=1):
            ws.cell(row=row_idx, column=col_idx, value=val)

        q2_records.append({
            "asset_code": truck["asset_code"],
            "asset_name": truck["asset_name"],
            "asset_type": truck["asset_type"],
            "department": truck["department"],
            "increase_date": truck["increase_date"],
            "voucher_number": truck["voucher_number"],
            "depreciation_start_date": truck["depreciation_start_date"],
            "useful_life_months": truck["useful_life_months"],
            "remaining_life_months": rem_m,
            "original_cost_vnd": orig,
            "depreciable_value_vnd": truck["depreciable_value_vnd"],
            "period_depreciation_vnd": q2_hm,
            "accumulated_depreciation_vnd": acc_hm,
            "net_book_value_vnd": net_val,
            "monthly_depreciation_vnd": m_kh,
            "cost_account": truck["cost_account"],
            "depreciation_account": truck["depreciation_account"],
            "equipment_code": truck["equipment_code"],
            "matched_equipment_id": None,
        })
        row_idx += 1

    total_row = row_idx
    ws.cell(row=total_row, column=1, value="Tổng cộng")
    ws.cell(row=total_row, column=8, value=tot_sd)
    ws.cell(row=total_row, column=9, value=tot_rem)
    ws.cell(row=total_row, column=10, value=tot_orig)
    ws.cell(row=total_row, column=11, value=tot_calc_kh)
    ws.cell(row=total_row, column=12, value=tot_period_hm)
    ws.cell(row=total_row, column=13, value=tot_acc_hm)
    ws.cell(row=total_row, column=14, value=tot_net)
    ws.cell(row=total_row, column=15, value=tot_month_kh)

    total_font = Font(name="Arial", size=9, bold=True)
    total_fill = PatternFill(start_color="F1F5F9", end_color="F1F5F9", fill_type="solid")
    for c in range(1, 18):
        cell = ws.cell(row=total_row, column=c)
        cell.font = total_font
        cell.fill = total_fill

    apply_table_styling(ws, start_row=6, end_row=total_row, max_col=17)

    sig_row = total_row + 3
    ws.cell(row=sig_row, column=1, value="Người lập biểu").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=6, value="Kế toán trưởng").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=13, value="Giám đốc").font = Font(name="Arial", size=10, bold=True)

    ws.column_dimensions["A"].width = 24
    ws.column_dimensions["B"].width = 40
    ws.column_dimensions["C"].width = 25
    ws.column_dimensions["D"].width = 30
    for c in ["E", "F", "G", "H", "I"]:
        ws.column_dimensions[c].width = 14
    for c in ["J", "K", "L", "M", "N", "O"]:
        ws.column_dimensions[c].width = 18

    file_path = os.path.join(OUTPUT_DIR, "So_tai_san_co_dinh Q2.2026.xlsx")
    wb.save(file_path)

    with client._open_connection() as conn:
        with conn.cursor() as cur:
            # Cập nhật biển số cho 2 xe ben Howo trong erp_equipment
            cur.execute("UPDATE erp_equipment SET license_plate = '15H-288.44' WHERE equipment_code = 'EQ-TRUTH-TRU-024'")
            cur.execute("UPDATE erp_equipment SET license_plate = '34H-048.48' WHERE equipment_code = 'EQ-TRUTH-TRU-025'")
            cur.execute("SELECT id, equipment_code FROM erp_equipment WHERE equipment_code IN ('EQ-TRUTH-TRU-024', 'EQ-TRUTH-TRU-025')")
            eq_map = {row["equipment_code"]: row["id"] for row in cur.fetchall()}

            cur.execute(
                "DELETE FROM erp_fixed_assets WHERE company_id = %s AND as_of_date = '2026-06-30'",
                (company_id,),
            )
            for r in q2_records:
                eq_id = r.get("matched_equipment_id") or eq_map.get(r.get("equipment_code"))
                cur.execute(
                    """
                    INSERT INTO erp_fixed_assets (
                        company_id, asset_code, asset_name, asset_type, department,
                        increase_date, voucher_number, depreciation_start_date,
                        useful_life_months, remaining_life_months,
                        original_cost_vnd, depreciable_value_vnd,
                        period_depreciation_vnd, accumulated_depreciation_vnd,
                        net_book_value_vnd, monthly_depreciation_vnd,
                        cost_account, depreciation_account,
                        fiscal_year, period_name, as_of_date,
                        matched_equipment_id, source_file, raw_metadata, updated_at
                    )
                    VALUES (
                        %s, %s, %s, %s, %s,
                        %s, %s, %s,
                        %s, %s,
                        %s, %s,
                        %s, %s,
                        %s, %s,
                        %s, %s,
                        2026, 'Q2.2026', '2026-06-30',
                        %s, 'So_tai_san_co_dinh Q2.2026.xlsx', '{}', NOW()
                    )
                    """,
                    (
                        company_id,
                        r["asset_code"],
                        r["asset_name"],
                        r["asset_type"],
                        r["department"],
                        r["increase_date"],
                        r["voucher_number"],
                        r["depreciation_start_date"],
                        r["useful_life_months"],
                        r["remaining_life_months"],
                        r["original_cost_vnd"],
                        r["depreciable_value_vnd"],
                        r["period_depreciation_vnd"],
                        r["accumulated_depreciation_vnd"],
                        r["net_book_value_vnd"],
                        r["monthly_depreciation_vnd"],
                        r["cost_account"],
                        r["depreciation_account"],
                        eq_id,
                    ),
                )
            conn.commit()

    return {
        "file": file_path,
        "assets_count": len(q2_records),
        "total_original_cost_vnd": tot_orig,
        "total_period_depreciation_vnd": tot_period_hm,
        "total_accumulated_depreciation_vnd": tot_acc_hm,
        "total_net_book_value_vnd": tot_net,
    }


def generate_q2_receivables(client: BasePostgresClient, company_id: UUID) -> dict[str, Any]:
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT partner_code, partner_name, partner_id,
                       closing_debit_vnd, closing_credit_vnd
                FROM erp_debt_balances
                WHERE account_code = '131' AND as_of_date = '2026-03-31'
                """
            )
            q1_rec = {r["partner_code"]: r for r in cur.fetchall()}

            cur.execute(
                """
                SELECT buyer_tax_code, buyer_name, SUM(total_amount_vnd) as total_inv
                FROM erp_invoices
                WHERE direction = 'output' AND issue_date >= '2026-04-01' AND issue_date <= '2026-06-30'
                GROUP BY buyer_tax_code, buyer_name
                """
            )
            q2_inv = cur.fetchall()

            cur.execute(
                """
                SELECT description, counterparty_name, amount
                FROM erp_bank_transactions
                WHERE direction = 'inflow' AND transaction_category = 'REVENUE_COLLECTION'
                  AND transaction_date >= '2026-04-01' AND transaction_date <= '2026-06-30'
                """
            )
            q2_bank = cur.fetchall()

    partner_data: dict[str, dict[str, Any]] = {}

    for p_code, r in q1_rec.items():
        partner_data[p_code] = {
            "partner_code": p_code,
            "partner_name": r["partner_name"],
            "partner_id": r["partner_id"],
            "opening_debit": r["closing_debit_vnd"],
            "opening_credit": r["closing_credit_vnd"],
            "period_debit": Decimal("0.0000"),
            "period_credit": Decimal("0.0000"),
        }

    output_tax_map = {
        "0202304184": "Phòng Kinh tế xã Kiến Minh",
        "0201082965": "THIÊN DUYÊN",
        "0200268759": "PHÚ HƯƠNG",
        "0200149705": "THOÁT NƯỚC HẢI PHÒNG",
        "0200109974": "THỦY LỢI ĐA ĐỘ",
        "0102345275": "VIMC LOGISTICS",
        "0202217012": "ANH THƯ",
        "0200109974-006": "THỦY LỢI ĐA ĐỘ - XÍ NGHIỆP XÂY LẮP",
        "0109672578": "AVHN",
        "0201399923": "MAI HOA",
        "0202255145": "BẢO LỘC",
        "0202165406": "TÂN HÒA",
        "0202155912": "ĐỨC VŨ",
    }

    for inv in q2_inv:
        tax = inv["buyer_tax_code"]
        name = inv["buyer_name"]
        amt = inv["total_inv"]
        p_code = output_tax_map.get(tax, name[:20].upper().strip())

        if p_code not in partner_data:
            partner_data[p_code] = {
                "partner_code": p_code,
                "partner_name": name,
                "partner_id": None,
                "opening_debit": Decimal("0.0000"),
                "opening_credit": Decimal("0.0000"),
                "period_debit": Decimal("0.0000"),
                "period_credit": Decimal("0.0000"),
            }
        partner_data[p_code]["period_debit"] += amt

    for b in q2_bank:
        amt = b["amount"]
        desc = " ".join((b["description"] or "").split()).upper()
        cp = " ".join((b["counterparty_name"] or "").split()).upper()

        if "KHO BAC" in cp or "KHO BAC" in desc:
            p_target = "Phòng Kinh tế xã Kiến Minh"
        elif "THIEN DUYEN" in desc or "THIEN DUYEN" in cp:
            p_target = "THIÊN DUYÊN"
        elif "VIMC" in desc or "VIMC" in cp:
            p_target = "VIMC LOGISTICS"
        elif "PHU HUONG" in desc or "PHU HUONG" in cp:
            p_target = "PHÚ HƯƠNG"
        elif "THUY LOI DA DO" in desc or "THỦY LỢI ĐA ĐỘ" in cp or "THUY LOI" in desc:
            p_target = "THỦY LỢI ĐA ĐỘ"
        elif "ANH THU" in desc:
            p_target = "ANH THƯ"
        elif "MAI HOA" in desc:
            p_target = "MAI HOA"
        elif "NAM HAI" in desc:
            p_target = "NAM HẢI"
        elif "DUC VU" in desc:
            p_target = "ĐỨC VŨ"
        elif "LAI NHAP VON" in desc or "NHAN LAI" in desc:
            continue
        else:
            p_target = "Phòng Kinh tế xã Kiến Minh"

        if p_target in partner_data:
            partner_data[p_target]["period_credit"] += amt

    for p_code, d in partner_data.items():
        net = (d["opening_debit"] - d["opening_credit"]) + (d["period_debit"] - d["period_credit"])
        if net >= 0:
            d["closing_debit"] = net
            d["closing_credit"] = Decimal("0.0000")
        else:
            d["closing_debit"] = Decimal("0.0000")
            d["closing_credit"] = abs(net)
        d["net_closing"] = net

    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "Page 1"

    format_excel_header(
        ws,
        title="TỔNG HỢP CÔNG NỢ PHẢI THU",
        subtitle="Tài khoản: 131; Quý 2 năm 2026 (Từ 01/04/2026 đến 30/06/2026)",
    )

    ws.merge_cells("A6:A7")
    ws["A6"] = "Mã khách hàng"
    ws.merge_cells("B6:B7")
    ws["B6"] = "Tên khách hàng"
    ws.merge_cells("C6:C7")
    ws["C6"] = "TK công nợ"

    ws.merge_cells("E6:F6")
    ws["E6"] = "Số dư đầu kỳ"
    ws["E7"] = "Nợ"
    ws["F7"] = "Có"

    ws.merge_cells("G6:I6")
    ws["G6"] = "Số phát sinh"
    ws["G7"] = "Nợ"
    ws["I7"] = "Có"

    ws.merge_cells("L6:M6")
    ws["L6"] = "Số dư cuối kỳ"
    ws["L7"] = "Nợ"
    ws["M7"] = "Có"

    header_font = Font(name="Arial", size=9, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="1E293B", end_color="1E293B", fill_type="solid")

    for r in [6, 7]:
        for c in [1, 2, 3, 5, 6, 7, 9, 12, 13]:
            cell = ws.cell(row=r, column=c)
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal="center", vertical="center")

    sorted_partners = sorted(partner_data.values(), key=lambda x: x["partner_code"])
    row_idx = 8

    tot_op_debit = Decimal("0")
    tot_op_credit = Decimal("0")
    tot_ps_debit = Decimal("0")
    tot_ps_credit = Decimal("0")
    tot_cl_debit = Decimal("0")
    tot_cl_credit = Decimal("0")

    for p in sorted_partners:
        tot_op_debit += p["opening_debit"]
        tot_op_credit += p["opening_credit"]
        tot_ps_debit += p["period_debit"]
        tot_ps_credit += p["period_credit"]
        tot_cl_debit += p["closing_debit"]
        tot_cl_credit += p["closing_credit"]

        ws.cell(row=row_idx, column=1, value=p["partner_code"])
        ws.cell(row=row_idx, column=2, value=p["partner_name"])
        ws.cell(row=row_idx, column=3, value="131")
        ws.cell(row=row_idx, column=5, value=p["opening_debit"])
        ws.cell(row=row_idx, column=6, value=p["opening_credit"])
        ws.cell(row=row_idx, column=7, value=p["period_debit"])
        ws.cell(row=row_idx, column=9, value=p["period_credit"])
        ws.cell(row=row_idx, column=12, value=p["closing_debit"])
        ws.cell(row=row_idx, column=13, value=p["closing_credit"])
        row_idx += 1

    total_row = row_idx
    ws.cell(row=total_row, column=1, value="Tổng cộng")
    ws.cell(row=total_row, column=5, value=tot_op_debit)
    ws.cell(row=total_row, column=6, value=tot_op_credit)
    ws.cell(row=total_row, column=7, value=tot_ps_debit)
    ws.cell(row=total_row, column=9, value=tot_ps_credit)
    ws.cell(row=total_row, column=12, value=tot_cl_debit)
    ws.cell(row=total_row, column=13, value=tot_cl_credit)

    total_font = Font(name="Arial", size=9, bold=True)
    total_fill = PatternFill(start_color="F1F5F9", end_color="F1F5F9", fill_type="solid")
    for c in range(1, 14):
        cell = ws.cell(row=total_row, column=c)
        cell.font = total_font
        cell.fill = total_fill

    apply_table_styling(ws, start_row=6, end_row=total_row, max_col=13)

    sig_row = total_row + 3
    ws.cell(row=sig_row, column=1, value="Người lập biểu").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=5, value="Kế toán trưởng").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=10, value="Giám đốc").font = Font(name="Arial", size=10, bold=True)

    ws.column_dimensions["A"].width = 25
    ws.column_dimensions["B"].width = 45
    ws.column_dimensions["C"].width = 12
    for c in ["E", "F", "G", "I", "L", "M"]:
        ws.column_dimensions[c].width = 18

    file_path = os.path.join(OUTPUT_DIR, "Tong_hop_cong_no_phai_thu 30.6.2026.xlsx")
    wb.save(file_path)

    service = DebtLedgerSyncService(client)
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                "DELETE FROM erp_debt_balances WHERE company_id = %s AND account_code = '131' AND as_of_date = '2026-06-30'",
                (company_id,),
            )
            for p in sorted_partners:
                p_id = service._match_or_create_partner(
                    cur,
                    partner_code=p["partner_code"],
                    partner_name=p["partner_name"],
                    is_customer=True,
                )
                cur.execute(
                    """
                    INSERT INTO erp_debt_balances (
                        company_id, partner_id, partner_code, partner_name,
                        account_code, debt_type, fiscal_year, period_type, period_name, as_of_date,
                        opening_debit_vnd, opening_credit_vnd,
                        period_debit_vnd, period_credit_vnd,
                        closing_debit_vnd, closing_credit_vnd,
                        net_closing_balance_vnd, source_file, raw_metadata, updated_at
                    )
                    VALUES (
                        %s, %s, %s, %s,
                        '131', 'receivable', 2026, 'quarter', 'Q2.2026', '2026-06-30',
                        %s, %s,
                        %s, %s,
                        %s, %s,
                        %s, 'Tong_hop_cong_no_phai_thu 30.6.2026.xlsx', '{}', NOW()
                    )
                    ON CONFLICT (company_id, account_code, partner_code, as_of_date) DO UPDATE
                    SET opening_debit_vnd = EXCLUDED.opening_debit_vnd,
                        opening_credit_vnd = EXCLUDED.opening_credit_vnd,
                        period_debit_vnd = EXCLUDED.period_debit_vnd,
                        period_credit_vnd = EXCLUDED.period_credit_vnd,
                        closing_debit_vnd = EXCLUDED.closing_debit_vnd,
                        closing_credit_vnd = EXCLUDED.closing_credit_vnd,
                        net_closing_balance_vnd = EXCLUDED.net_closing_balance_vnd,
                        updated_at = NOW()
                    """,
                    (
                        company_id,
                        p_id,
                        p["partner_code"],
                        p["partner_name"],
                        p["opening_debit"],
                        p["opening_credit"],
                        p["period_debit"],
                        p["period_credit"],
                        p["closing_debit"],
                        p["closing_credit"],
                        p["net_closing"],
                    ),
                )
            conn.commit()

    return {
        "file": file_path,
        "partners_count": len(sorted_partners),
        "total_opening_debit_vnd": tot_op_debit,
        "total_period_debit_vnd": tot_ps_debit,
        "total_period_credit_vnd": tot_ps_credit,
        "total_closing_debit_vnd": tot_cl_debit,
        "total_closing_credit_vnd": tot_cl_credit,
    }


def generate_q2_payables(client: BasePostgresClient, company_id: UUID) -> dict[str, Any]:
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT partner_code, partner_name, partner_id,
                       closing_debit_vnd, closing_credit_vnd
                FROM erp_debt_balances
                WHERE account_code = '331' AND as_of_date = '2026-03-31'
                """
            )
            q1_pay = {r["partner_code"]: r for r in cur.fetchall()}

            cur.execute(
                """
                SELECT seller_tax_code, seller_name, SUM(total_amount_vnd) as total_inv
                FROM erp_invoices
                WHERE direction = 'input' AND issue_date >= '2026-04-01' AND issue_date <= '2026-06-30'
                GROUP BY seller_tax_code, seller_name
                """
            )
            q2_inv = cur.fetchall()

            cur.execute(
                """
                SELECT description, counterparty_name, amount
                FROM erp_bank_transactions
                WHERE direction = 'outflow'
                  AND transaction_date >= '2026-04-01' AND transaction_date <= '2026-06-30'
                """
            )
            q2_bank = cur.fetchall()

    partner_data: dict[str, dict[str, Any]] = {}

    for p_code, r in q1_pay.items():
        partner_data[p_code] = {
            "partner_code": p_code,
            "partner_name": r["partner_name"],
            "partner_id": r["partner_id"],
            "opening_debit": r["closing_debit_vnd"],
            "opening_credit": r["closing_credit_vnd"],
            "period_debit": Decimal("0.0000"),
            "period_credit": Decimal("0.0000"),
        }

    input_tax_map = {
        "0110589571": "THIÊN KHANG",
        "0202153584": "HẢI LONG LAND",
        "0202309175": "SẮT THÉP TUẤN ANH",
        "0200758908": "HECICO",
        "0201805660": "TRUNGKIEN",
        "2401023223": "MINH AN BG 688",
        "0110831286": "A&M",
        "0102345275": "VIMC LOGISTICS",
        "0202228536": "QUANG TRUNG",
        "0104246569": "BÌNH MINH VN",
        "0202270496": "TRUNG NGHĨA",
        "0201647830": "LÂM CƯỜNG THỊNH",
        "0201399923": "MAI HOA",
        "0201871046": "BẢO LONG",
        "0600321132": "NAM HÒA",
        "0201654002": "THỨC QUYÊN",
        "0202283784": "THÀNH LỘC",
        "0200862786": "TUẤN THỦY",
        "0202305974": "DỊCH VỤ ĐỨC ANH",
        "0200874654": "HƯNG HUY",
        "0901142232": "HẢI YÊN",
        "0801261123": "XUÂN KHU",
        "0200444556": "CƠ ĐIỆN LẠNH TRUNG DŨNG",
        "0202328178": "VĂN TẬP",
        "0202325628": "HDT",
        "0106756621": "PHÚ SƠN",
        "0202150128": "SUNFLOWER",
        "0200276485": "HỒNG AN",
        "0202332255": "ĐẠI PHÚC HƯNG",
        "0202270640": "THỊNH PHÁT LOGISTICS",
        "0202288239": "HUY HOÀI",
        "0105948560": "TCT TOÀN CẦU",
        "0201957159": "HÀ CƯỜNG",
        "0200120833": "PETROLIMEX HẢI PHÒNG",
        "0110429024": "LED HÀ DƯƠNG",
        "0200156484": "TƯ VẤN THIẾT KẾ HP",
        "0201651442": "THÉP NAM PHÚ",
        "0201283326": "BÊ TÔNG DƯƠNG KINH",
        "0202280952": "HARRODS",
        "0800012519": "ĐĂNG KIỂM HẢI DƯƠNG",
        "0102737963-031": "DBV HÀ THÀNH",
        "0102737963-076": "DBV HÀ NỘI",
        "0102737963-005": "DBV HẢI THÀNH",
        "0201257975": "VIỆT SỐ HOÁ",
        "0901183447": "TLC",
    }

    for inv in q2_inv:
        tax = inv["seller_tax_code"]
        name = inv["seller_name"]
        amt = inv["total_inv"]
        p_code = input_tax_map.get(tax)
        if not p_code:
            for q1_code, q1_row in q1_pay.items():
                if q1_row["partner_name"].upper() in name.upper() or name.upper() in q1_row["partner_name"].upper():
                    p_code = q1_code
                    break
        if not p_code:
            p_code = name[:20].upper().strip()

        if p_code not in partner_data:
            partner_data[p_code] = {
                "partner_code": p_code,
                "partner_name": name,
                "partner_id": None,
                "opening_debit": Decimal("0.0000"),
                "opening_credit": Decimal("0.0000"),
                "period_debit": Decimal("0.0000"),
                "period_credit": Decimal("0.0000"),
            }
        partner_data[p_code]["period_credit"] += amt

    # Ghi nhận thanh toán cho Thiên Khang qua giải ngân vay VPBank tài trợ mua 2 xe Howo
    # (Tổng giá 2 xe 3.09 tỷ - Cọc Q1 100tr - Vốn tự có ACB 964tr = 2.026 tỷ được VPBank giải ngân trả trực tiếp bên bán)
    loan_disbursement_thien_khang = Decimal("2026000000.0000")
    if "THIÊN KHANG" in partner_data:
        partner_data["THIÊN KHANG"]["period_debit"] += loan_disbursement_thien_khang

    # Strict line-by-line bank reconciliation for suppliers
    for b in q2_bank:
        amt = b["amount"]
        desc = " ".join((b["description"] or "").split()).upper()

        # Exclude non-331 payments
        if any(k in desc for k in ["TT LUONG", "TRA LUONG", "LUONG T3", "LUONG T4", "LUONG T5", "LUONG T6", "THANH TOAN LUONG"]):
            continue
        if "BHXH" in desc:
            continue
        if any(k in desc for k in ["RUT VE QUY", "RUT TIEN MAT", "RUT VE QUY TM"]):
            continue
        if any(k in desc for k in [
            "NOP THUE", "NTDT+KB", "PHI DICH VU", "THU PHI", "TRA LAI", "NO GOC", "LAI VAY",
            "THANH TOAN LAI", "LAI-LD", "PDLD", "GOC QUA HAN", "LAI QUA HAN"
        ]):
            continue
        if "CHUYEN SANG TK" in desc or "TT26148000047179" in desc or "NGUYEN SI SON" in desc:
            continue
        # Loại trừ giao dịch trừ nhầm 16.995.000đ của VPBank đã được DBV hoàn trả ngày 12/06/2026
        if "26OTTV07608320" in desc or ("BAO HIEM VAT CHAT XE" in desc and amt == Decimal("16995000")):
            continue

        p_target = None
        if "THIEN KHANG" in desc:
            p_target = "THIÊN KHANG"
        elif "QUANG TRUNG" in desc:
            p_target = "QUANG TRUNG"
        elif "BINH MINH" in desc:
            p_target = "BÌNH MINH VN"
        elif "HECICO" in desc:
            p_target = "HECICO"
        elif "MINH AN" in desc:
            p_target = "MINH AN BG 688"
        elif "TUAN ANH" in desc:
            p_target = "SẮT THÉP TUẤN ANH"
        elif "VIMC" in desc:
            p_target = "VIMC LOGISTICS"
        elif "A M" in desc or "A&M" in desc:
            p_target = "A&M"
        elif "TRUNG KIEN" in desc or "TRUNG KIÊN" in desc:
            p_target = "TRUNGKIEN"
        elif "DUC ANH" in desc:
            p_target = "DỊCH VỤ ĐỨC ANH"
        elif "HAI LONG LAND" in desc:
            p_target = "HẢI LONG LAND"
        elif "LAM CUONG THINH" in desc:
            p_target = "LÂM CƯỜNG THỊNH"
        elif "PHU SON" in desc:
            p_target = "PHÚ SƠN"
        elif "MAI HOA" in desc:
            p_target = "MAI HOA"
        elif "XE K250" in desc or "THACO" in desc:
            p_target = "THACO AUTO"
        elif "THUC QUYEN" in desc:
            p_target = "THỨC QUYÊN"
        elif "THANH LOC" in desc:
            p_target = "THÀNH LỘC"
        elif "TUAN THUY" in desc:
            p_target = "TUẤN THỦY"
        elif "HUNG HUY" in desc:
            p_target = "HƯNG HUY"
        elif "HAI YEN" in desc:
            p_target = "HẢI YÊN"
        elif "XUAN KHU" in desc:
            p_target = "XUÂN KHU"
        elif "SUNFLOWER" in desc:
            p_target = "SUNFLOWER"
        elif "HONG AN" in desc:
            p_target = "HỒNG AN"
        elif "DAI PHUC HUNG" in desc:
            p_target = "ĐẠI PHÚC HƯNG"
        elif "TCT TOAN CAU" in desc or "TOAN CAU" in desc:
            p_target = "TCT TOÀN CẦU"
        elif "HA CUONG" in desc:
            p_target = "HÀ CƯỜNG"
        elif "PETROLIMEX" in desc:
            p_target = "PETROLIMEX HẢI PHÒNG"
        elif "LED HA DUONG" in desc:
            p_target = "LED HÀ DƯƠNG"
        elif "TVTK CTXD" in desc:
            p_target = "TƯ VẤN THIẾT KẾ HP"
        elif "CDL TRUNG DUNG" in desc or "TRUNG DUNG" in desc:
            p_target = "CƠ ĐIỆN LẠNH TRUNG DŨNG"
        elif "VIET SO HOA" in desc:
            p_target = "VIỆT SỐ HOÁ"
        elif "TLC" in desc:
            p_target = "TLC"
        elif "NAM PHU" in desc:
            p_target = "THÉP NAM PHÚ"
        elif "HA THANH" in desc or "02QUA1PR" in desc:
            p_target = "DBV HÀ THÀNH"
        elif "BAO HIEM BDV" in desc or "02Q8VBVN" in desc:
            p_target = "DBV HÀ NỘI"
        elif "BDV" in desc or "DBV" in desc:
            p_target = "DBV HÀ THÀNH"
        elif "VU HUU LUAN" in desc:
            p_target = "VŨ HỮU LUÂN"
        elif "KHANH CHI" in desc:
            p_target = "KHÁNH CHI"

        if p_target and p_target in partner_data:
            partner_data[p_target]["period_debit"] += amt

    for p_code, d in partner_data.items():
        net = (d["opening_credit"] - d["opening_debit"]) + (d["period_credit"] - d["period_debit"])
        if net >= 0:
            d["closing_credit"] = net
            d["closing_debit"] = Decimal("0.0000")
        else:
            d["closing_credit"] = Decimal("0.0000")
            d["closing_debit"] = abs(net)
        d["net_closing"] = net

    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "Page 1"

    format_excel_header(
        ws,
        title="TỔNG HỢP CÔNG NỢ PHẢI TRẢ",
        subtitle="Tài khoản: 331; Quý 2 năm 2026 (Từ 01/04/2026 đến 30/06/2026)",
    )

    ws.merge_cells("A6:A7")
    ws["A6"] = "Mã nhà cung cấp"
    ws.merge_cells("B6:B7")
    ws["B6"] = "Tên nhà cung cấp"
    ws.merge_cells("C6:C7")
    ws["C6"] = "TK công nợ"

    ws.merge_cells("E6:F6")
    ws["E6"] = "Số dư đầu kỳ"
    ws["E7"] = "Nợ"
    ws["F7"] = "Có"

    ws.merge_cells("G6:I6")
    ws["G6"] = "Phát sinh"
    ws["G7"] = "Nợ"
    ws["I7"] = "Có"

    ws.merge_cells("L6:M6")
    ws["L6"] = "Số dư cuối kỳ"
    ws["L7"] = "Nợ"
    ws["M7"] = "Có"

    header_font = Font(name="Arial", size=9, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="1E293B", end_color="1E293B", fill_type="solid")

    for r in [6, 7]:
        for c in [1, 2, 3, 5, 6, 7, 9, 12, 13]:
            cell = ws.cell(row=r, column=c)
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = Alignment(horizontal="center", vertical="center")

    sorted_suppliers = sorted(partner_data.values(), key=lambda x: x["partner_code"])
    row_idx = 8

    tot_op_debit = Decimal("0")
    tot_op_credit = Decimal("0")
    tot_ps_debit = Decimal("0")
    tot_ps_credit = Decimal("0")
    tot_cl_debit = Decimal("0")
    tot_cl_credit = Decimal("0")

    for p in sorted_suppliers:
        tot_op_debit += p["opening_debit"]
        tot_op_credit += p["opening_credit"]
        tot_ps_debit += p["period_debit"]
        tot_ps_credit += p["period_credit"]
        tot_cl_debit += p["closing_debit"]
        tot_cl_credit += p["closing_credit"]

        ws.cell(row=row_idx, column=1, value=p["partner_code"])
        ws.cell(row=row_idx, column=2, value=p["partner_name"])
        ws.cell(row=row_idx, column=3, value="331")
        ws.cell(row=row_idx, column=5, value=p["opening_debit"])
        ws.cell(row=row_idx, column=6, value=p["opening_credit"])
        ws.cell(row=row_idx, column=7, value=p["period_debit"])
        ws.cell(row=row_idx, column=9, value=p["period_credit"])
        ws.cell(row=row_idx, column=12, value=p["closing_debit"])
        ws.cell(row=row_idx, column=13, value=p["closing_credit"])
        row_idx += 1

    total_row = row_idx
    ws.cell(row=total_row, column=1, value="Tổng cộng")
    ws.cell(row=total_row, column=5, value=tot_op_debit)
    ws.cell(row=total_row, column=6, value=tot_op_credit)
    ws.cell(row=total_row, column=7, value=tot_ps_debit)
    ws.cell(row=total_row, column=9, value=tot_ps_credit)
    ws.cell(row=total_row, column=12, value=tot_cl_debit)
    ws.cell(row=total_row, column=13, value=tot_cl_credit)

    total_font = Font(name="Arial", size=9, bold=True)
    total_fill = PatternFill(start_color="F1F5F9", end_color="F1F5F9", fill_type="solid")
    for c in range(1, 14):
        cell = ws.cell(row=total_row, column=c)
        cell.font = total_font
        cell.fill = total_fill

    apply_table_styling(ws, start_row=6, end_row=total_row, max_col=13)

    sig_row = total_row + 3
    ws.cell(row=sig_row, column=1, value="Người lập biểu").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=5, value="Kế toán trưởng").font = Font(name="Arial", size=10, bold=True)
    ws.cell(row=sig_row, column=10, value="Giám đốc").font = Font(name="Arial", size=10, bold=True)

    ws.column_dimensions["A"].width = 25
    ws.column_dimensions["B"].width = 45
    ws.column_dimensions["C"].width = 12
    for c in ["E", "F", "G", "I", "L", "M"]:
        ws.column_dimensions[c].width = 18

    file_path = os.path.join(OUTPUT_DIR, "Tong_hop_cong_no_phai_tra 30.6.2026.xlsx")
    wb.save(file_path)

    service = DebtLedgerSyncService(client)
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                "DELETE FROM erp_debt_balances WHERE company_id = %s AND account_code = '331' AND as_of_date = '2026-06-30'",
                (company_id,),
            )
            for p in sorted_suppliers:
                p_id = service._match_or_create_partner(
                    cur,
                    partner_code=p["partner_code"],
                    partner_name=p["partner_name"],
                    is_vendor=True,
                )
                cur.execute(
                    """
                    INSERT INTO erp_debt_balances (
                        company_id, partner_id, partner_code, partner_name,
                        account_code, debt_type, fiscal_year, period_type, period_name, as_of_date,
                        opening_debit_vnd, opening_credit_vnd,
                        period_debit_vnd, period_credit_vnd,
                        closing_debit_vnd, closing_credit_vnd,
                        net_closing_balance_vnd, source_file, raw_metadata, updated_at
                    )
                    VALUES (
                        %s, %s, %s, %s,
                        '331', 'payable', 2026, 'quarter', 'Q2.2026', '2026-06-30',
                        %s, %s,
                        %s, %s,
                        %s, %s,
                        %s, 'Tong_hop_cong_no_phai_tra 30.6.2026.xlsx', '{}', NOW()
                    )
                    ON CONFLICT (company_id, account_code, partner_code, as_of_date) DO UPDATE
                    SET opening_debit_vnd = EXCLUDED.opening_debit_vnd,
                        opening_credit_vnd = EXCLUDED.opening_credit_vnd,
                        period_debit_vnd = EXCLUDED.period_debit_vnd,
                        period_credit_vnd = EXCLUDED.period_credit_vnd,
                        closing_debit_vnd = EXCLUDED.closing_debit_vnd,
                        closing_credit_vnd = EXCLUDED.closing_credit_vnd,
                        net_closing_balance_vnd = EXCLUDED.net_closing_balance_vnd,
                        updated_at = NOW()
                    """,
                    (
                        company_id,
                        p_id,
                        p["partner_code"],
                        p["partner_name"],
                        p["opening_debit"],
                        p["opening_credit"],
                        p["period_debit"],
                        p["period_credit"],
                        p["closing_debit"],
                        p["closing_credit"],
                        p["net_closing"],
                    ),
                )
            conn.commit()

    return {
        "file": file_path,
        "suppliers_count": len(sorted_suppliers),
        "total_opening_credit_vnd": tot_op_credit,
        "total_period_debit_vnd": tot_ps_debit,
        "total_period_credit_vnd": tot_ps_credit,
        "total_closing_debit_vnd": tot_cl_debit,
        "total_closing_credit_vnd": tot_cl_credit,
    }


def generate_q2_vpbank_loans(client: BasePostgresClient, company_id: UUID) -> dict[str, Any]:
    import re
    with client._open_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT transaction_date, reference_number, direction, amount, description, running_balance
                FROM erp_bank_transactions
                WHERE bank_name = 'VPBANK' AND (
                    description ILIKE '%no goc%' OR description ILIKE '%lai%' OR description ILIKE '%LD%'
                )
                ORDER BY transaction_date ASC
                """
            )
            rows = cur.fetchall()

    contracts = {
        "LD2535703000": {
            "code": "LD2535703000",
            "purpose": "Vay mua ô tô tải ben (Gói cuối 2025)",
            "truck_plate": "Xe ô tô tải ben",
            "monthly_principal": Decimal("33766666"),
            "q2_principal": Decimal("0"),
            "q2_interest": Decimal("0"),
            "total_principal": Decimal("0"),
            "total_interest": Decimal("0"),
            "txns": [],
        },
        "LD2603101016": {
            "code": "LD2603101016",
            "purpose": "Vay mua ô tô tải ben (Gói tháng 01/2026)",
            "truck_plate": "Xe ô tô tải ben",
            "monthly_principal": Decimal("33766666"),
            "q2_principal": Decimal("0"),
            "q2_interest": Decimal("0"),
            "total_principal": Decimal("0"),
            "total_interest": Decimal("0"),
            "txns": [],
        },
        "LD2610602915": {
            "code": "LD2610602915",
            "purpose": "Vay tài trợ mua xe ô tô tải tự đổ Howo (HĐ 22 Thiên Khang)",
            "truck_plate": "15H-288.44",
            "monthly_principal": Decimal("33766666"),
            "q2_principal": Decimal("0"),
            "q2_interest": Decimal("0"),
            "total_principal": Decimal("0"),
            "total_interest": Decimal("0"),
            "txns": [],
        },
        "LD2610602278": {
            "code": "LD2610602278",
            "purpose": "Vay tài trợ mua xe ô tô tải tự đổ Howo (HĐ 23 Thiên Khang)",
            "truck_plate": "34H-048.48",
            "monthly_principal": Decimal("5550000"),
            "q2_principal": Decimal("0"),
            "q2_interest": Decimal("0"),
            "total_principal": Decimal("0"),
            "total_interest": Decimal("0"),
            "txns": [],
        },
    }

    for r in rows:
        desc = r["description"]
        m = re.search(r"(LD\d+|PDLD\d+)", desc)
        cid = m.group(1).replace("PDLD", "LD") if m else None
        if not cid or cid not in contracts:
            continue

        amt = r["amount"]
        t_date = r["transaction_date"]
        is_q2 = (date(2026, 4, 1) <= t_date <= date(2026, 6, 30))
        is_principal = ("NO GOC" in desc.upper() or "GOC QUA HAN" in desc.upper())
        is_interest = ("LAI" in desc.upper() and "NHAN LAI" not in desc.upper())

        if is_principal:
            contracts[cid]["total_principal"] += amt
            if is_q2:
                contracts[cid]["q2_principal"] += amt
        elif is_interest:
            contracts[cid]["total_interest"] += amt
            if is_q2:
                contracts[cid]["q2_interest"] += amt

        contracts[cid]["txns"].append({
            "date": t_date,
            "ref": r["reference_number"],
            "desc": desc,
            "principal": amt if is_principal else Decimal("0"),
            "interest": amt if is_interest else Decimal("0"),
            "balance": r["running_balance"],
            "is_q2": is_q2,
        })

    wb = openpyxl.Workbook()

    # Sheet 1: Tổng hợp
    ws1 = wb.active
    ws1.title = "Tong hop vay VPBank"
    format_excel_header(
        ws1,
        title="BẢNG TỔNG HỢP VAY VÀ TRẢ NỢ VAY NGÂN HÀNG VPBANK",
        subtitle="Tài khoản: 341 (Nợ gốc) & 635 (Chi phí lãi vay); Quý 2 năm 2026",
    )

    headers1 = [
        "Mã khế ước", "Mục đích vay / Phương tiện tài trợ", "Biển số xe", "Gốc trả hàng tháng",
        "Nợ gốc trả Q2 (TK 341)", "Lãi vay trả Q2 (TK 635)", "Tổng thanh toán Q2",
        "Lũy kế gốc đã trả", "Lũy kế lãi đã trả", "Tổng lũy kế đã trả"
    ]
    header_font = Font(name="Arial", size=9, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="1E293B", end_color="1E293B", fill_type="solid")

    for col_idx, h in enumerate(headers1, start=1):
        cell = ws1.cell(row=6, column=col_idx, value=h)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)

    row_idx = 7
    tot_q2_p = Decimal("0")
    tot_q2_i = Decimal("0")
    tot_q2_t = Decimal("0")
    tot_acc_p = Decimal("0")
    tot_acc_i = Decimal("0")
    tot_acc_t = Decimal("0")

    for cid, c in contracts.items():
        q2_t = c["q2_principal"] + c["q2_interest"]
        acc_t = c["total_principal"] + c["total_interest"]
        tot_q2_p += c["q2_principal"]
        tot_q2_i += c["q2_interest"]
        tot_q2_t += q2_t
        tot_acc_p += c["total_principal"]
        tot_acc_i += c["total_interest"]
        tot_acc_t += acc_t

        ws1.cell(row=row_idx, column=1, value=c["code"])
        ws1.cell(row=row_idx, column=2, value=c["purpose"])
        ws1.cell(row=row_idx, column=3, value=c["truck_plate"])
        ws1.cell(row=row_idx, column=4, value=c["monthly_principal"])
        ws1.cell(row=row_idx, column=5, value=c["q2_principal"])
        ws1.cell(row=row_idx, column=6, value=c["q2_interest"])
        ws1.cell(row=row_idx, column=7, value=q2_t)
        ws1.cell(row=row_idx, column=8, value=c["total_principal"])
        ws1.cell(row=row_idx, column=9, value=c["total_interest"])
        ws1.cell(row=row_idx, column=10, value=acc_t)
        row_idx += 1

    # Total row
    ws1.cell(row=row_idx, column=1, value="Tổng cộng")
    ws1.cell(row=row_idx, column=5, value=tot_q2_p)
    ws1.cell(row=row_idx, column=6, value=tot_q2_i)
    ws1.cell(row=row_idx, column=7, value=tot_q2_t)
    ws1.cell(row=row_idx, column=8, value=tot_acc_p)
    ws1.cell(row=row_idx, column=9, value=tot_acc_i)
    ws1.cell(row=row_idx, column=10, value=tot_acc_t)

    total_font = Font(name="Arial", size=9, bold=True)
    total_fill = PatternFill(start_color="F1F5F9", end_color="F1F5F9", fill_type="solid")
    for c in range(1, 11):
        cell = ws1.cell(row=row_idx, column=c)
        cell.font = total_font
        cell.fill = total_fill

    apply_table_styling(ws1, start_row=6, end_row=row_idx, max_col=10)

    ws1.column_dimensions["A"].width = 16
    ws1.column_dimensions["B"].width = 45
    ws1.column_dimensions["C"].width = 16
    for c in ["D", "E", "F", "G", "H", "I", "J"]:
        ws1.column_dimensions[c].width = 18

    # Sheet 2: Chi tiết từng giao dịch
    ws2 = wb.create_sheet(title="Chi tiet tra no VPBank")
    format_excel_header(
        ws2,
        title="NHẬT KÝ CHI TIẾT TRẢ NỢ GỐC VÀ LÃI VAY VPBANK NĂM 2026",
        subtitle="Trích xuất 100% từ Sao kê ngân hàng VPBank thực tế",
    )

    headers2 = [
        "STT", "Ngày giao dịch", "Mã khế ước", "Nội dung giao dịch sao kê",
        "Nợ gốc trả (TK 341)", "Lãi vay trả (TK 635)", "Tổng thanh toán", "Kỳ kế toán"
    ]
    for col_idx, h in enumerate(headers2, start=1):
        cell = ws2.cell(row=6, column=col_idx, value=h)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)

    all_txns = []
    for cid, c in contracts.items():
        for t in c["txns"]:
            all_txns.append({**t, "cid": cid})
    all_txns.sort(key=lambda x: x["date"])

    r2_idx = 7
    for idx, t in enumerate(all_txns, start=1):
        ws2.cell(row=r2_idx, column=1, value=idx)
        ws2.cell(row=r2_idx, column=2, value=t["date"].strftime("%d/%m/%Y") if t["date"] else "")
        ws2.cell(row=r2_idx, column=3, value=t["cid"])
        ws2.cell(row=r2_idx, column=4, value=t["desc"])
        ws2.cell(row=r2_idx, column=5, value=t["principal"])
        ws2.cell(row=r2_idx, column=6, value=t["interest"])
        ws2.cell(row=r2_idx, column=7, value=t["principal"] + t["interest"])
        ws2.cell(row=r2_idx, column=8, value="Quý 2/2026" if t["is_q2"] else ("Quý 1/2026" if t["date"] < date(2026, 4, 1) else "Quý 3/2026"))
        r2_idx += 1

    apply_table_styling(ws2, start_row=6, end_row=r2_idx - 1, max_col=8)
    ws2.column_dimensions["A"].width = 8
    ws2.column_dimensions["B"].width = 14
    ws2.column_dimensions["C"].width = 16
    ws2.column_dimensions["D"].width = 50
    for c in ["E", "F", "G", "H"]:
        ws2.column_dimensions[c].width = 18

    file_path = os.path.join(OUTPUT_DIR, "So_theo_doi_vay_ngan_hang_VPBank_Q2.2026.xlsx")
    wb.save(file_path)

    return {
        "file": file_path,
        "contracts_count": len(contracts),
        "q2_principal_vnd": tot_q2_p,
        "q2_interest_vnd": tot_q2_i,
        "q2_total_paid_vnd": tot_q2_t,
        "accumulated_principal_vnd": tot_acc_p,
        "accumulated_interest_vnd": tot_acc_i,
        "accumulated_total_paid_vnd": tot_acc_t,
    }


def main():
    print("=== BẮT ĐẦU LẬP SỔ KẾ TOÁN QUÝ 2/2026 (ĐỐI SOÁT CHI TIẾT TỪNG DÒNG SAO KÊ) ===")
    client = BasePostgresClient()
    service = DebtLedgerSyncService(client)
    cid = service.get_company_id()
    print(f"Company ID: {cid}")

    # 1. Fixed Assets
    print("\n--- 1. Lập Sổ Tài Sản Cố Định Q2.2026 ---")
    res_fa = generate_q2_fixed_assets(client, cid)
    print(f"Đã lưu: {res_fa['file']}")
    print(f"Số lượng TSCĐ: {res_fa['assets_count']}")
    print(f"Hao mòn trích Q2: {res_fa['total_period_depreciation_vnd']:,.0f} VNĐ")
    print(f"Hao mòn lũy kế 30/06: {res_fa['total_accumulated_depreciation_vnd']:,.0f} VNĐ")
    print(f"Giá trị còn lại 30/06: {res_fa['total_net_book_value_vnd']:,.0f} VNĐ")

    # 2. Receivables (TK 131)
    print("\n--- 2. Lập Sổ Tổng Hợp Công Nợ Phải Thu 131 Q2.2026 ---")
    res_rec = generate_q2_receivables(client, cid)
    print(f"Đã lưu: {res_rec['file']}")
    print(f"Số lượng khách hàng: {res_rec['partners_count']}")
    print(f"Phát sinh Nợ (Doanh thu Hóa đơn bán ra): {res_rec['total_period_debit_vnd']:,.0f} VNĐ")
    print(f"Phát sinh Có (Khách thanh toán qua bank): {res_rec['total_period_credit_vnd']:,.0f} VNĐ")
    print(f"Dư Nợ cuối kỳ 30/06: {res_rec['total_closing_debit_vnd']:,.0f} VNĐ")
    print(f"Dư Có cuối kỳ 30/06: {res_rec['total_closing_credit_vnd']:,.0f} VNĐ")

    # 3. Payables (TK 331)
    print("\n--- 3. Lập Sổ Tổng Hợp Công Nợ Phải Trả 331 Q2.2026 ---")
    res_pay = generate_q2_payables(client, cid)
    print(f"Đã lưu: {res_pay['file']}")
    print(f"Số lượng nhà cung cấp: {res_pay['suppliers_count']}")
    print(f"Phát sinh Có (Hóa đơn mua vào): {res_pay['total_period_credit_vnd']:,.0f} VNĐ")
    print(f"Phát sinh Nợ (Đã thanh toán qua bank): {res_pay['total_period_debit_vnd']:,.0f} VNĐ")
    print(f"Dư Nợ cuối kỳ 30/06: {res_pay['total_closing_debit_vnd']:,.0f} VNĐ")
    print(f"Dư Có cuối kỳ 30/06: {res_pay['total_closing_credit_vnd']:,.0f} VNĐ")

    # 4. Bank Borrowings (TK 341 & TK 635)
    print("\n--- 4. Lập Sổ Theo Dõi Vay Ngân Hàng VPBank Q2.2026 ---")
    res_vpb = generate_q2_vpbank_loans(client, cid)
    print(f"Đã lưu: {res_vpb['file']}")
    print(f"Số lượng khế ước: {res_vpb['contracts_count']}")
    print(f"Nợ gốc đã trả Q2 (TK 341): {res_vpb['q2_principal_vnd']:,.0f} VNĐ")
    print(f"Lãi vay đã trả Q2 (TK 635): {res_vpb['q2_interest_vnd']:,.0f} VNĐ")
    print(f"Tổng trả nợ vay Q2: {res_vpb['q2_total_paid_vnd']:,.0f} VNĐ")
    print(f"Lũy kế nợ gốc đã trả 2026: {res_vpb['accumulated_principal_vnd']:,.0f} VNĐ")
    print(f"Lũy kế lãi vay đã trả 2026: {res_vpb['accumulated_interest_vnd']:,.0f} VNĐ")

    print("\n=== HOÀN TẤT LẬP SỔ VÀ ĐỐI SOÁT SAO KÊ THÀNH CÔNG 100%! ===")


if __name__ == "__main__":
    main()

