"""
Única fuente de verdad para permisos de facturas por (operation_type, invoice_type).

Debe mantenerse alineado con el seed en api/v1/modules/core/permissions/seed.py
y con frontend/src/lib/permissions/invoice-permissions.ts.
"""

from __future__ import annotations

from typing import Any, Iterable, Optional

# Tipos de exportación que cubre únicamente invoice.exp.view (histórico list_invoices).
EXP_TYPES_FROM_GENERAL_EXPORT_VIEW: tuple[str, ...] = (
    "EXDEF",
    "MATDE",
    "NODES",
    "PTERM",
    "SCRAP",
    "VEMEX",
    "VIRTU",
    "AFIJO",
    "REEXP",
)


def get_invoice_permission_base(operation_type: Any, invoice_type: Any) -> str:
    """Devuelve la clave base del permiso (sin .view/.create/...) según tipo de factura."""
    op = str(operation_type).lower().split(".")[-1] if operation_type else ""
    inv = str(invoice_type).upper() if invoice_type else ""

    if op == "imp":
        if inv == "TEM":
            return "invoice.imp.tem"
        if inv == "DEF":
            return "invoice.imp.def"
        if inv == "MEX":
            return "invoice.imp.cm"
        if inv == "CR":
            return "invoice.imp.cr"
        if inv == "REP":
            return "invoice.imp.rep"
        return "invoice.imp.tem"
    if op == "exp":
        if inv == "REPAR":
            return "invoice.exp.rep"
        if inv == "DONAC":
            return "invoice.exp.donac"
        return "invoice.exp"

    return "invoice.imp.tem"


def build_allowed_types_from_view_permissions(
    perm_codes: Iterable[str],
) -> list[tuple[str, str]]:
    """
    Construye la lista de tuplas (operation_type en minúsculas, invoice_type en MAYÚSCULAS)
    permitidas por los permisos *.view del usuario. Misma lógica que el antiguo list_invoices
    (sin permiso global invoice.view_all — eliminado de producto).
    """
    codes = set(perm_codes)
    allowed: list[tuple[str, str]] = []
    seen: set[tuple[str, str]] = set()

    def add_pair(op: str, inv: str) -> None:
        pair = (op.lower(), inv.upper())
        if pair not in seen:
            seen.add(pair)
            allowed.append(pair)

    if "invoice.imp.tem.view" in codes:
        add_pair("imp", "TEM")
    if "invoice.imp.def.view" in codes:
        add_pair("imp", "DEF")
    if "invoice.imp.cm.view" in codes:
        add_pair("imp", "MEX")
    if "invoice.imp.cr.view" in codes:
        add_pair("imp", "CR")
    if "invoice.imp.rep.view" in codes:
        add_pair("imp", "REP")

    if "invoice.exp.rep.view" in codes:
        add_pair("exp", "REPAR")
    if "invoice.exp.donac.view" in codes:
        add_pair("exp", "DONAC")

    if "invoice.exp.view" in codes:
        for t in EXP_TYPES_FROM_GENERAL_EXPORT_VIEW:
            add_pair("exp", t)

    return allowed
