from __future__ import annotations

import hashlib

"""Entrypoint XML parser dispatcher."""


import logging
import re
import xml.etree.ElementTree as ET
from typing import Any

from .xml_gdt import InvoiceGdtXmlMixin
from .xml_misa import InvoiceMisaXmlMixin

logger = logging.getLogger(__name__)


class InvoiceXmlParserMixin(InvoiceGdtXmlMixin, InvoiceMisaXmlMixin):
    """Unified XML parser dispatcher mixin."""

    def parse_xml_content(
        self, xml_text: str | bytes, source_channel: str = "manual_xml"
    ) -> dict[str, Any]:
        """Bóc tách toàn diện file XML Hóa đơn điện tử (Chuẩn NĐ123 Tổng Cục Thuế & MISA meInvoice)."""
        if isinstance(xml_text, bytes):
            try:
                raw_str = xml_text.decode("utf-8")
            except UnicodeDecodeError:
                raw_str = xml_text.decode("utf-8-sig", errors="replace")
        else:
            raw_str = xml_text

        # 1. Cryptographic Hash Calculation (SHA-256) for deduplication
        sha256_hash = hashlib.sha256(raw_str.encode("utf-8")).hexdigest()

        # Clean namespace if present for easier tag lookup
        cleaned_xml = re.sub(r'xmlns(:\w+)?="[^"]+"', "", raw_str)
        try:
            root = ET.fromstring(cleaned_xml)
        except Exception as e:
            raise ValueError(f"Không thể đọc cấu trúc XML Hóa đơn điện tử: {e!s}")

        # Detect schema structure
        is_misa_format = (
            root.tag in ("InvoiceData", "MISAInvoice")
            or root.find(".//InvoiceHeader") is not None
        )

        if is_misa_format:
            parsed = self._parse_misa_meinvoice_xml(
                root, raw_str, sha256_hash, source_channel
            )
        else:
            parsed = self._parse_gdt_nd123_xml(
                root, raw_str, sha256_hash, source_channel
            )

        return parsed
