"""Generatoren für Sicherheits-/Zugriffs-Tabellen der Standarddokumentation.

Erzeugt Markdown für
- die RLS-Rollen-Mitglieder (welche Benutzer/Gruppen sind je Rolle zugewiesen)
- die Berichtszugriffe (welche Benutzer/Gruppen haben Zugriff auf den Bericht)

Beide Informationen können ausschließlich aus dem Power BI / Fabric Service
extrahiert werden. Für lokale Berichte (PBIX) und PBIP-Projekte wird stattdessen
ein entsprechender Hinweis ausgegeben.
"""
from __future__ import annotations

from core.models import ReportMetadata

_HINT = {
    "de": (
        "> **Hinweis:** RLS-Rollen-Mitglieder und Berichtszugriffe können nur "
        "aus dem Power BI / Fabric Service exportiert werden. Für lokale Berichte "
        "(PBIX) und PBIP-Projekte stehen diese Informationen nicht zur Verfügung."
    ),
    "en": (
        "> **Note:** RLS role members and report access can only be exported from "
        "the Power BI / Fabric Service. This information is not available for local "
        "reports (PBIX) and PBIP projects."
    ),
}

_LABELS = {
    "de": {
        "no_roles": "_Keine RLS-Rollen definiert._",
        "no_members": "_Keine Mitglieder zugewiesen._",
        "role": "Rolle",
        "members": "Mitglieder",
        "no_access": (
            "_Keine Berichtszugriffe verfügbar (erfordert Fabric-Administratorrechte)._"
        ),
        "name": "Name",
        "type": "Typ",
        "right": "Zugriffsrecht",
        "id": "Kennung",
    },
    "en": {
        "no_roles": "_No RLS roles defined._",
        "no_members": "_No members assigned._",
        "role": "Role",
        "members": "Members",
        "no_access": (
            "_No report access available (requires Fabric administrator rights)._"
        ),
        "name": "Name",
        "type": "Type",
        "right": "Access right",
        "id": "Identifier",
    },
}


def _lang(language: str) -> str:
    return language if language in _LABELS else "de"


def _escape(value: str) -> str:
    if value is None:
        return ""
    return str(value).replace("|", "\\|").replace("\n", " ").strip()


def access_hint(language: str = "de") -> str:
    """Gibt den Hinweistext für Nicht-Fabric-Quellen zurück."""
    return _HINT.get(_lang(language), _HINT["de"])


def generate_rls_members_table(
    metadata: ReportMetadata,
    connection_type: str = "fabric",
    language: str = "de",
) -> str:
    """Erzeugt die RLS-Rollen-Mitglieder-Tabelle (oder den Hinweis)."""
    lang = _lang(language)
    if connection_type != "fabric":
        return access_hint(lang)

    labels = _LABELS[lang]
    roles = metadata.rls_roles or []
    if not roles:
        return labels["no_roles"]

    lines = [
        f"| {labels['role']} | {labels['members']} |",
        "|---|---|",
    ]
    for role in roles:
        members = getattr(role, "members", None) or []
        member_str = ", ".join(_escape(m) for m in members) if members else labels["no_members"]
        lines.append(f"| {_escape(role.name)} | {member_str} |")
    return "\n".join(lines)


def generate_report_access_table(
    metadata: ReportMetadata,
    connection_type: str = "fabric",
    language: str = "de",
) -> str:
    """Erzeugt die Berichtszugriffs-Tabelle (oder den Hinweis)."""
    lang = _lang(language)
    if connection_type != "fabric":
        return access_hint(lang)

    labels = _LABELS[lang]
    users = getattr(metadata, "report_users", None) or []
    if not users:
        return labels["no_access"]

    lines = [
        f"| {labels['name']} | {labels['type']} | {labels['right']} | {labels['id']} |",
        "|---|---|---|---|",
    ]
    for u in users:
        lines.append(
            f"| {_escape(u.display_name)} | {_escape(u.principal_type) or '–'} | "
            f"{_escape(u.access_right) or '–'} | {_escape(u.identifier) or '–'} |"
        )
    return "\n".join(lines)


def build_report_access_table_from_users(
    users: list,
    connection_type: str = "fabric",
    language: str = "de",
) -> str:
    """Wie :func:`generate_report_access_table`, aber direkt aus einer Benutzerliste.

    Wird für eigenständige Berichtsdateien im Workspace-Export verwendet.
    """
    md = ReportMetadata(report_name="")
    md.report_users = users or []
    return generate_report_access_table(md, connection_type, language)
