from __future__ import annotations

"""XML Parser for MISA meInvoice format."""


import logging
import xml.etree.ElementTree as ET
from datetime import date, datetime
from decimal import ROUND_HALF_UP, Decimal
from typing import Any

from .common import DSCONS_DEFAULT_TAX_CODE, to_decimal

logger = logging.getLogger(__name__)


class InvoiceMisaXmlMixin:
    """Mixin for parsing MISA meInvoice XML format."""

    def _parse_misa_meinvoice_xml(
        self, root: ET.Element, raw_str: str, sha256_hash: str, source_channel: str
    ) -> dict[str, Any]:
        """Bóc tách cấu trúc XML xuất từ phần mềm MISA meInvoice."""

        def get_text(parent: ET.Element | None, tag: str, default: str = "") -> str:
            if parent is None:
                return default
            el = parent.find(f".//{tag}")
            return el.text.strip() if el is not None and el.text else default

        header = root.find(".//InvoiceHeader") or root

        invoice_number = get_text(header, "InvoiceNo") or get_text(
            root, "InvNo", "00000000"
        )
        if invoice_number.isdigit() and len(invoice_number) < 8:
            invoice_number = invoice_number.zfill(8)

        invoice_series = get_text(header, "InvoiceSeries") or get_text(
            root, "InvSeries", "1C26TDS"
        )
        template_code = get_text(header, "TemplateCode") or get_text(
            root, "TemplateCode", "1"
        )
        issue_date_str = get_text(header, "InvoiceDate") or get_text(
            root, "InvDate", str(date.today())
        )

        try:
            issue_date = datetime.strptime(issue_date_str[:10], "%Y-%m-%d").date()
        except Exception:
            issue_date = date.today()

        seller_tax_code = get_text(header, "SellerTaxCode") or get_text(
            root, "SellerTaxCode", ""
        )
        seller_name = get_text(header, "SellerLegalName") or get_text(
            root, "SellerName", "Người Bán Chưa Xác Định"
        )
        seller_address = get_text(header, "SellerAddress", "")

        buyer_tax_code = get_text(header, "BuyerTaxCode") or get_text(
            root, "BuyerTaxCode", ""
        )
        buyer_name = get_text(header, "BuyerLegalName") or get_text(
            root, "BuyerName", "Người Mua Chưa Xác Định"
        )
        buyer_address = get_text(header, "BuyerAddress", "")

        subtotal_amount = to_decimal(get_text(header, "TotalAmountWithoutVAT", "0"))
        vat_amount = to_decimal(get_text(header, "VATAmount", "0"))
        total_amount = to_decimal(get_text(header, "TotalAmountWithVAT", "0"))
        amount_in_words = get_text(header, "TotalAmountInWords", "")

        if (
            seller_tax_code == DSCONS_DEFAULT_TAX_CODE
            or "ĐỊNH SƠN" in seller_name.upper()
        ):
            direction = "output"
        else:
            direction = "input"

        items: list[dict[str, Any]] = []
        item_nodes = root.findall(".//Item") or root.findall(".//InvoiceDetail")
        item_idx = 1

        for node in item_nodes:
            item_name = get_text(node, "ItemName", f"Hàng hóa / Dịch vụ #{item_idx}")
            item_code = get_text(node, "ItemCode", "")
            unit = get_text(node, "UnitName", "Lô")
            quantity = to_decimal(get_text(node, "Quantity", "1.0000"))
            unit_price = to_decimal(get_text(node, "UnitPrice", "0.0000"))
            line_amount = to_decimal(get_text(node, "AmountWithoutVAT", "0.0000"))
            line_vat = to_decimal(get_text(node, "ItemVATAmount", "0.0000"))
            line_total = to_decimal(get_text(node, "ItemTotalAmount", "0.0000"))

            if line_amount == Decimal("0.0000"):
                line_amount = (quantity * unit_price).quantize(
                    Decimal("0.0001"), rounding=ROUND_HALF_UP
                )
            if line_total == Decimal("0.0000"):
                line_total = line_amount + line_vat

            cost_cat = self.categorize_item_cost(item_name, item_code)
            items.append(
                {
                    "item_order": item_idx,
                    "item_name": item_name,
                    "item_code": item_code,
                    "unit": unit,
                    "quantity": quantity,
                    "unit_price_vnd": unit_price,
                    "amount_before_vat_vnd": line_amount,
                    "vat_rate_percent": Decimal("8.00"),
                    "vat_amount_vnd": line_vat,
                    "total_item_amount_vnd": line_total,
                    "cost_category": cost_cat,
                }
            )
            item_idx += 1

        return {
            "direction": direction,
            "invoice_type": "vat",
            "invoice_number": invoice_number,
            "invoice_series": invoice_series,
            "template_code": template_code,
            "issue_date": str(issue_date),
            "seller_tax_code": seller_tax_code,
            "seller_name": seller_name,
            "seller_address": seller_address,
            "buyer_tax_code": buyer_tax_code,
            "buyer_name": buyer_name,
            "buyer_address": buyer_address,
            "currency_code": "VND",
            "exchange_rate": Decimal("1.0000"),
            "subtotal_amount_vnd": subtotal_amount,
            "vat_rate_percent": Decimal("8.00"),
            "vat_amount_vnd": vat_amount,
            "total_amount_vnd": total_amount,
            "amount_in_words": amount_in_words,
            "status": "valid",
            "tax_authority_code": "",
            "xml_raw_content": raw_str,
            "xml_hash_sha256": sha256_hash,
            "signature_valid": True,
            "signed_by": seller_name,
            "signed_at": datetime.now().isoformat(),
            "source_channel": "meinvoice_web",
            "reconciliation_status": "unreconciled",
            "items": items,
        }
