"""High-level workflows.

This module provides convenience helpers that compose lower-level modules:
- xmlgen: generation
- xmlsign: signing
- qrgen: QR insertion

The library remains "pure" (no CLI). These helpers are optional sugar.
"""

from __future__ import annotations

from typing import Optional

from lxml import etree

from .xmlgen import generate_de_xml
from .qrgen import add_qr_to_signed_de_xml


def sign_de_xml(xml: str, pfx_bytes: bytes, password: Optional[str] = None) -> str:
    # Lazy import so that importing this module does not require optional deps.
    from .xmlsign.api import sign_de_xml as _sign

    return _sign(xml=xml, pfx_bytes=pfx_bytes, password=password)


def sign_event_xml(xml: str, pfx_bytes: bytes, password: Optional[str] = None) -> str:
    # Lazy import so that importing this module does not require optional deps.
    from .xmlsign.api import sign_event_xml as _sign

    return _sign(xml=xml, pfx_bytes=pfx_bytes, password=password)


def _serialize_with_decl(root: etree._Element) -> str:
    """Serialize XML with a double-quote XML declaration.

    Note: the XML declaration is not part of the signed node-set.
    """

    body = etree.tostring(root, xml_declaration=False, encoding="UTF-8")
    return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' + body.decode("utf-8")


def generate_de_signed_qr_xml(
    *,
    params: dict,
    data: dict,
    pfx_bytes: bytes,
    password: Optional[str],
    id_csc: int,
    csc: str,
    qr_test: bool = True,
    pretty: bool = True,
) -> str:
    """Generate a DE XML, sign it, and insert the QR.

    Args:
        params: Emisor/config parameters (same shape as xmlgen).
        data: DE document data (same shape as xmlgen).
        pfx_bytes: PKCS#12 bytes (.p12/.pfx).
        password: PKCS#12 password.
        id_csc: QR IdCSC.
        csc: QR CSC secret.
        qr_test: If True, uses test QR base URL.

    Returns:
        Final XML string: signed + QR inserted.
    """

    xml = generate_de_xml(params=params, data=data)

    # Pretty-print BEFORE signing so canonicalization/digest includes the same whitespace.
    if pretty:
        root = etree.fromstring(xml.encode("utf-8"))
        etree.indent(root, space="  ")
        xml = _serialize_with_decl(root)

    signed = sign_de_xml(xml=xml, pfx_bytes=pfx_bytes, password=password)
    return add_qr_to_signed_de_xml(signed, id_csc=id_csc, csc=csc, test=qr_test)
