# ============================================================
# core/tndn_report.py
# Tờ khai thuế Thu nhập doanh nghiệp (Mẫu 03/TNDN rút gọn)
# CLI: python core/cli.py company CTY001 tax-tndn --year 2026
# ============================================================

import sqlite3
import os
from datetime import datetime
from typing import Optional

try:
    import openpyxl
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    from openpyxl.utils import get_column_letter
    HAS_OPENPYXL = True
except ImportError:
    HAS_OPENPYXL = False

# Thuế suất TNDN phổ thông
TNDN_RATE = 0.20   # 20% — DN thông thường
TNDN_RATE_SME = 0.17  # 17% — DN vừa và nhỏ (doanh thu ≤ 20 tỷ, <200 LĐ)


def calc_tndn(conn: sqlite3.Connection, year: int,
              tax_rate: float = TNDN_RATE) -> dict:
    """
    Tính thuế TNDN phải nộp từ sổ kế toán.
    Lấy từ TK 511, 515, 711 (thu nhập) và 632, 635, 641, 642, 811 (chi phí).
    """
    c = conn.cursor()

    def ytd(prefixes, sign=1):
        t = 0.0
        for p in prefixes:
            r = c.execute("""
                SELECT COALESCE(SUM(je.credit - je.debit), 0)
                FROM journal_entries je
                JOIN vouchers v ON v.id = je.voucher_id
                WHERE je.account_code LIKE ?
                  AND v.status = 'posted'
                  AND v.period_year = ?
            """, (p + "%", year)).fetchone()
            t += (r[0] if r else 0) * sign
        return t

    # Thu nhập chịu thuế
    doanh_thu     = ytd(["511", "515"])
    thu_khac      = ytd(["711"])
    tong_thu_nhap = doanh_thu + thu_khac

    # Chi phí được trừ (theo quy định thuế TNDN)
    gia_von       = ytd(["632"], sign=-1)
    cp_ban_hang   = ytd(["641"], sign=-1)
    cp_qldn       = ytd(["642"], sign=-1)
    cp_tc         = ytd(["635"], sign=-1)
    cp_khac       = ytd(["811"], sign=-1)
    tong_chi_phi  = gia_von + cp_ban_hang + cp_qldn + cp_tc + cp_khac

    # Thu nhập tính thuế
    tnct = max(0, tong_thu_nhap - tong_chi_phi)

    # Thuế TNDN phải nộp
    thue_tndn = tnct * tax_rate

    # Thuế đã tạm nộp (theo TK 821)
    tam_nop = ytd(["821"], sign=-1)
    con_phai_nop = max(0, thue_tndn - tam_nop)
    duoc_hoan = max(0, tam_nop - thue_tndn)

    return {
        "year": year,
        "tax_rate": tax_rate,
        "doanh_thu": doanh_thu,
        "thu_khac": thu_khac,
        "tong_thu_nhap": tong_thu_nhap,
        "gia_von": gia_von,
        "cp_ban_hang": cp_ban_hang,
        "cp_qldn": cp_qldn,
        "cp_tc": cp_tc,
        "cp_khac": cp_khac,
        "tong_chi_phi": tong_chi_phi,
        "tnct": tnct,               # Thu nhập chịu thuế
        "thue_tndn": thue_tndn,     # Thuế phải nộp theo tính toán
        "tam_nop": tam_nop,         # Đã tạm nộp
        "con_phai_nop": con_phai_nop,
        "duoc_hoan": duoc_hoan,
    }


def print_tndn_report(data: dict) -> None:
    fmt = lambda x: f"{x:>18,.0f}"
    rate_pct = int(data["tax_rate"] * 100)
    print(f"\n{'='*58}")
    print(f"  TỜ KHAI THUẾ TNDN (Mẫu 03/TNDN rút gọn) — NĂM {data['year']}")
    print(f"  Thuế suất: {rate_pct}%")
    print(f"{'='*58}")
    print(f"  Thu nhập:")
    print(f"    Doanh thu bán hàng + DV    {fmt(data['doanh_thu'])}")
    print(f"    Thu nhập khác              {fmt(data['thu_khac'])}")
    print(f"    TỔNG THU NHẬP              {fmt(data['tong_thu_nhap'])}")
    print(f"  Chi phí được trừ:")
    print(f"    Giá vốn hàng bán           {fmt(data['gia_von'])}")
    print(f"    Chi phí bán hàng + QLDN    {fmt(data['cp_ban_hang'] + data['cp_qldn'])}")
    print(f"    Chi phí tài chính + khác   {fmt(data['cp_tc'] + data['cp_khac'])}")
    print(f"    TỔNG CHI PHÍ               {fmt(data['tong_chi_phi'])}")
    print(f"  {'─'*55}")
    print(f"  THU NHẬP CHỊU THUẾ          {fmt(data['tnct'])}")
    print(f"  THUẾ TNDN ({rate_pct}%)            {fmt(data['thue_tndn'])}")
    print(f"  Đã tạm nộp trong năm         {fmt(data['tam_nop'])}")
    print(f"  {'─'*55}")
    if data["con_phai_nop"] > 0:
        print(f"  ✅ CÒN PHẢI NỘP              {fmt(data['con_phai_nop'])} VND")
        print(f"     Hạn nộp: 31/03/{data['year'] + 1}")
    else:
        print(f"  ♻️  ĐƯỢC HOÀN/KHẤU TRỪ       {fmt(data['duoc_hoan'])} VND")
    print(f"{'='*58}\n")


def export_tndn_excel(data: dict, out_dir: str, company_name: str = "") -> str:
    if not HAS_OPENPYXL:
        raise ImportError("Cần cài openpyxl")

    os.makedirs(out_dir, exist_ok=True)
    fname = f"TKhai_TNDN_{data['year']}.xlsx"
    fpath = os.path.join(out_dir, fname)

    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = f"TNDN {data['year']}"

    navy = "1F3864"; bold = Font(name="Arial", bold=True, size=10)
    norm = Font(name="Arial", size=10)
    thin = Side(style="thin", color="BFBFBF")
    bd   = Border(left=thin, right=thin, top=thin, bottom=thin)
    ca   = Alignment(horizontal="center"); ra = Alignment(horizontal="right")
    la   = Alignment(horizontal="left", indent=1)
    def fill(c): return PatternFill("solid", fgColor=c)

    ws.column_dimensions["A"].width = 45
    ws.column_dimensions["B"].width = 10
    ws.column_dimensions["C"].width = 22

    ws.merge_cells("A1:C1")
    ws["A1"] = f"TỜ KHAI THUẾ TNDN — NĂM {data['year']} | {company_name}"
    ws["A1"].font = Font(name="Arial", bold=True, size=13, color="FFFFFF")
    ws["A1"].fill = fill(navy); ws["A1"].alignment = ca
    ws.row_dimensions[1].height = 28

    rows_data = [
        ("Chỉ tiêu", "Mã", "Số tiền (VND)", True, "2E75B6", True),
        ("I. DOANH THU BÁN HÀNG VÀ CCDV", "[01]", data["doanh_thu"], True, "E2EFDA", False),
        ("II. THU NHẬP KHÁC", "[02]", data["thu_khac"], False, None, False),
        ("III. TỔNG THU NHẬP", "[03]", data["tong_thu_nhap"], True, "E2EFDA", False),
        ("IV. CHI PHÍ ĐƯỢC TRỪ", "[04]", data["tong_chi_phi"], True, "FCE4D6", False),
        ("  - Giá vốn", "[04a]", data["gia_von"], False, None, False),
        ("  - Chi phí bán hàng + QLDN", "[04b]", data["cp_ban_hang"]+data["cp_qldn"], False, None, False),
        ("  - Chi phí TC + khác", "[04c]", data["cp_tc"]+data["cp_khac"], False, None, False),
        ("V. THU NHẬP CHỊU THUẾ (III-IV)", "[05]", data["tnct"], True, "C6EFCE", False),
        (f"VI. THUẾ TNDN ({int(data['tax_rate']*100)}%)", "[06]", data["thue_tndn"], True, "C6EFCE", False),
        ("VII. ĐÃ TẠM NỘP", "[07]", data["tam_nop"], False, None, False),
        ("VIII. CÒN PHẢI NỘP / ĐƯỢC HOÀN", "[08]",
         data["con_phai_nop"] if data["con_phai_nop"] > 0 else -data["duoc_hoan"],
         True, "FFFF99", False),
    ]

    for r_idx, (label, code, val, is_bold, fc, is_header) in enumerate(rows_data, 3):
        ft = Font(name="Arial", bold=is_bold, size=10,
                  color="FFFFFF" if is_header else "000000")
        cells = [(1, label, la), (2, code, ca), (3, val if not is_header else "Số tiền (VND)", ra if not is_header else ca)]
        for col, v, al in cells:
            cell = ws.cell(row=r_idx, column=col, value=v)
            cell.font = ft; cell.alignment = al; cell.border = bd
            if fc: cell.fill = fill(fc)
            if col == 3 and isinstance(v, (int, float)):
                cell.number_format = '#,##0'
        ws.row_dimensions[r_idx].height = 18

    ws.merge_cells(f"A{len(rows_data)+4}:C{len(rows_data)+4}")
    ws[f"A{len(rows_data)+4}"] = (f"Hạn nộp quyết toán TNDN: 31/03/{data['year']+1}  |  "
                                   f"Xuất ngày {datetime.now().strftime('%d/%m/%Y')}")
    ws[f"A{len(rows_data)+4}"].font = Font(name="Arial", italic=True, size=9, color="808080")
    ws[f"A{len(rows_data)+4}"].alignment = ca

    wb.save(fpath)
    return fpath


def run_tndn(db_path: str, year: int, out_dir: Optional[str] = None,
             company_name: str = "", sme: bool = False) -> dict:
    conn = sqlite3.connect(db_path)
    rate = TNDN_RATE_SME if sme else TNDN_RATE
    data = calc_tndn(conn, year, rate)
    print_tndn_report(data)
    if out_dir:
        fpath = export_tndn_excel(data, out_dir, company_name)
        print(f"📄 Đã xuất: {fpath}")
    conn.close()
    return data
