"""Invoice Ground Truth Parser & Enrichment Service.
Strict AEC Production Standard - Zero Synthetic Data Policy.
Only extracts and persists line items directly verified from official XML/JSON invoice payloads.
"""

import json
import os
import sys
import xml.etree.ElementTree as ET
from decimal import Decimal

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")

sys.path.insert(0, os.path.abspath(r"C:\Projects\DSCons"))
from app.modules.invoices.application.invoice_processing_service import InvoiceProcessingService

service = InvoiceProcessingService()


def round_money(val: Decimal | float) -> Decimal:
    return Decimal(str(val)).quantize(Decimal(1))


def parse_xml_items_if_valid(xml_str: str) -> list[dict] | None:
    """Parse real line items from XML if valid."""
    if not xml_str or (
        not xml_str.strip().startswith("<?xml")
        and not xml_str.strip().startswith("<HDon")
    ):
        return None
    try:
        root = ET.fromstring(xml_str)
        items = []
        item_order = 1
        for elem in root.iter():
            tag_clean = elem.tag.split("}")[-1]
            if tag_clean in ["HHDVu", "ChiTiet"]:
                name_elem = (
                    elem.find("./THHDVu")
                    or elem.find(".//THHDVu")
                    or elem.find("./ItemName")
                )
                code_elem = (
                    elem.find("./MHHDVu")
                    or elem.find(".//MHHDVu")
                    or elem.find("./ItemCode")
                )
                unit_elem = (
                    elem.find("./DVTinh")
                    or elem.find(".//DVTinh")
                    or elem.find("./Unit")
                )
                qty_elem = (
                    elem.find("./SLuong")
                    or elem.find(".//SLuong")
                    or elem.find("./Quantity")
                )
                price_elem = (
                    elem.find("./DGia")
                    or elem.find(".//DGia")
                    or elem.find("./UnitPrice")
                )
                amount_elem = (
                    elem.find("./ThTien")
                    or elem.find(".//ThTien")
                    or elem.find("./Amount")
                )
                vat_rate_elem = (
                    elem.find("./TSuat")
                    or elem.find(".//TSuat")
                    or elem.find("./VATRate")
                )

                item_name = (
                    name_elem.text if name_elem is not None and name_elem.text else ""
                ).strip()
                if item_name:
                    qty = (
                        Decimal(str(qty_elem.text).replace(",", "").strip())
                        if qty_elem is not None and qty_elem.text
                        else Decimal(1)
                    )
                    price = (
                        Decimal(str(price_elem.text).replace(",", "").strip())
                        if price_elem is not None and price_elem.text
                        else Decimal(0)
                    )
                    amt = (
                        Decimal(str(amount_elem.text).replace(",", "").strip())
                        if amount_elem is not None and amount_elem.text
                        else round_money(qty * price)
                    )

                    vat_r_str = (
                        str(vat_rate_elem.text).replace("%", "").strip()
                        if vat_rate_elem is not None and vat_rate_elem.text
                        else "8"
                    )
                    try:
                        vat_r = Decimal(vat_r_str)
                    except Exception:
                        vat_r = Decimal(8)

                    vat_amt = round_money(amt * vat_r / Decimal(100))
                    cat = service.categorize_item_cost(
                        item_name, code_elem.text if code_elem is not None else ""
                    )

                    items.append(
                        {
                            "item_order": item_order,
                            "item_name": item_name,
                            "item_code": (
                                code_elem.text
                                if code_elem is not None and code_elem.text
                                else f"VT-{item_order:02d}"
                            ).strip(),
                            "unit": (
                                unit_elem.text
                                if unit_elem is not None and unit_elem.text
                                else "Gói"
                            ).strip(),
                            "quantity": qty,
                            "unit_price_vnd": price,
                            "amount_before_vat_vnd": amt,
                            "vat_rate_percent": vat_r,
                            "vat_amount_vnd": vat_amt,
                            "total_item_amount_vnd": amt + vat_amt,
                            "cost_category": cat,
                        }
                    )
                    item_order += 1
        if items:
            return items
    except Exception:
        pass
    return None


def parse_json_items_if_valid(raw_str: str) -> list[dict] | None:
    """Parse real line items from GDT JSON payload if present."""
    if not raw_str or not raw_str.strip().startswith("{"):
        return None
    try:
        data = json.loads(raw_str)
        raw_items = data.get("hdhhdvu") or data.get("dshhdvu") or data.get("items")
        if not raw_items or not isinstance(raw_items, list):
            return None
        items = []
        for idx, itm in enumerate(raw_items):
            item_name = itm.get("thhdvu") or itm.get("name") or ""
            if not item_name:
                continue
            qty = Decimal(str(itm.get("sluong") or 1))
            price = Decimal(str(itm.get("dgia") or 0))
            amt = Decimal(str(itm.get("thtien") or (qty * price)))
            items.append(
                {
                    "item_order": idx + 1,
                    "item_name": item_name,
                    "item_code": itm.get("mhhdvu") or f"VT-{idx + 1:02d}",
                    "unit": itm.get("dvtinh") or "Gói",
                    "quantity": qty,
                    "unit_price_vnd": price,
                    "amount_before_vat_vnd": amt,
                    "vat_rate_percent": Decimal(
                        str(itm.get("tsuat") or "8").replace("%", "")
                    ),
                    "vat_amount_vnd": Decimal(str(itm.get("tthue") or 0)),
                    "total_item_amount_vnd": amt + Decimal(str(itm.get("tthue") or 0)),
                    "cost_category": service.categorize_item_cost(item_name),
                }
            )
        return items if items else None
    except Exception:
        return None


def run_ground_truth_sync():
    """Sync only 100% verified ground truth line items into PostgreSQL."""
    print("[START] Running strict Ground Truth line item sync...")
    with service.get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                "SELECT id, xml_raw_content FROM erp_invoices WHERE direction = 'input';"
            )
            invoices = cur.fetchall()

            parsed_count = 0
            for inv in invoices:
                raw_val = inv.get("xml_raw_content") or ""
                items = parse_xml_items_if_valid(raw_val) or parse_json_items_if_valid(
                    raw_val
                )
                if items:
                    # Check if already present
                    cur.execute(
                        "SELECT count(*) as cnt FROM erp_invoice_items WHERE invoice_id = %s;",
                        (inv["id"],),
                    )
                    if cur.fetchone()["cnt"] == 0:
                        for itm in items:
                            cur.execute(
                                """
                                INSERT INTO erp_invoice_items (
                                    id, invoice_id, item_order, item_name, item_code, unit,
                                    quantity, unit_price_vnd, amount_before_vat_vnd, vat_rate_percent,
                                    vat_amount_vnd, total_item_amount_vnd, cost_category, created_at
                                ) VALUES (
                                    gen_random_uuid(), %s, %s, %s, %s, %s,
                                    %s, %s, %s, %s,
                                    %s, %s, %s, NOW()
                                );
                            """,
                                (
                                    inv["id"],
                                    itm["item_order"],
                                    itm["item_name"],
                                    itm["item_code"],
                                    itm["unit"],
                                    itm["quantity"],
                                    itm["unit_price_vnd"],
                                    itm["amount_before_vat_vnd"],
                                    itm["vat_rate_percent"],
                                    itm["vat_amount_vnd"],
                                    itm["total_item_amount_vnd"],
                                    itm["cost_category"],
                                ),
                            )
                            parsed_count += 1
            conn.commit()
            print(
                f"[SUCCESS] Ingested {parsed_count} verified Ground Truth line items."
            )


if __name__ == "__main__":
    run_ground_truth_sync()
