"""Generator für die Fabric Eventstream-Dokumentation.

Definition-basiert (analog zu :mod:`core.copyjob_doc_generator`): die
``eventstream.json`` beschreibt Quellen, Ziele und Operatoren/Transformationen.
Rendering aus einem :class:`~core.models.EventstreamInfo`.
"""
from __future__ import annotations

from core.models import EventstreamInfo, EventstreamNodeInfo
from core.template_renderer import TemplateRenderer
from core.workspace_doc_generator import _escape_cell, ensure_template, load_template

EVENTSTREAM_TEMPLATE_FILENAME = "WorkspaceEventstreamvorlage.md"

__all__ = [
    "EVENTSTREAM_TEMPLATE_FILENAME",
    "DEFAULT_EVENTSTREAM_TEMPLATE",
    "ensure_template",
    "load_template",
    "build_nodes_table",
    "build_service_hint",
    "build_eventstream_values",
    "render_eventstream",
]


DEFAULT_EVENTSTREAM_TEMPLATE = """# Microsoft Fabric Eventstream-Dokumentation

> **Hinweis:** Diese Dokumentation ist verpflichtend für alle Produktiv-Eventstreams.
> Nicht relevante Kapitel können leer bleiben, dürfen jedoch nicht entfernt werden.
> Automatisch befüllte Felder stammen aus dem Microsoft Fabric Service; mit
> _„Manuell zu ergänzen"_ markierte Felder sind fachlich zu vervollständigen.

---

## 1. Metadaten

| Feld | Wert |
|-----|------|
| Eventstream-Name | {{ES_Name}} |
| Beschreibung | {{ES_Beschreibung}} |
| Eventstream-ID | {{ES_ID}} |
| Web-URL | {{ES_WebUrl}} |
| Anzahl Quellen | {{ES_AnzahlQuellen}} |
| Anzahl Ziele | {{ES_AnzahlZiele}} |
| Anzahl Operatoren | {{ES_AnzahlOperatoren}} |
| Erstellt / konfiguriert von | {{ES_ConfiguredBy}} |
| Zuletzt geändert | {{ES_ModifiedTime}} |
| Fachbereich | {{ES_Fachbereich}} |
| Konzerndomäne | {{ES_Konzerndomaene}} |
| Aktuelle Version | 1.0 |
| Status | Produktiv |
| Letzte Aktualisierung | {{ES_ExportDatum}} |

---

## 2. Ansprechpartner & Verantwortlichkeiten

| Rolle | Name / Team | Kontakt |
|-----|-------------|--------|
| Fachlicher Owner | {{KONTAKT_BusinessOwner}} | {{KONTAKT_BusinessOwnerMail}} |
| Technischer Owner | {{KONTAKT_TechOwner}} | {{KONTAKT_TechOwnerMail}} |
| Data Steward | {{KONTAKT_DataSteward}} | {{KONTAKT_DataStewardMail}} |
| Betrieb / Support | {{KONTAKT_Betrieb}} | {{KONTAKT_BetriebMail}} |

---

## 3. Business-Ziel & fachlicher Kontext

### 3.1 Zielsetzung
{{ES_Zielsetzung}}

### 3.2 Fachlicher Anwendungsfall
{{ES_Anwendungsfall}}

### 3.3 Nachgelagerte Verbraucher (KQL-Datenbanken / Lakehouses / Aktivatoren)
{{ES_Konsumenten}}

---

## 4. Aufbau & Struktur

### 4.1 Quellen

{{ES_QuellenTabelle}}

### 4.2 Ziele

{{ES_ZieleTabelle}}

### 4.3 Operatoren / Transformationen

{{ES_OperatorenTabelle}}

---

## 5. Datenquellen & Beladung

### 5.1 Eingehende Datenströme

{{ES_DatenquellenTabelle}}

### 5.2 Detailbeschreibung je Datenquelle
{{ES_DatenquellenDetail}}

---

## 6. Inhalt & Nutzung

{{ES_ServiceHinweis}}

### 6.1 Verarbeitungslogik
{{ES_VerarbeitungHinweis}}

### 6.2 Parameter & Konfiguration
{{ES_ParameterHinweis}}

### 6.3 Datenqualität

- Umgang mit fehlerhaften Events: {{ES_NullHandling}}
- Datenvalidierungsregeln: {{ES_Validierungsregeln}}
- Aufbewahrung / Historisierung: {{ES_Aufbewahrung}}

### 6.4 Performance-Hinweise

- Durchsatz / Skalierung: {{ES_Optimierung}}
- Bekannte Performance-Engpässe: {{ES_PerformanceHinweise}}
- Weitere Maßnahmen: {{ES_Optimierungen}}

---

## 7. Betrieb & Wartung

### 7.1 Streaming & Orchestrierung

{{ES_Beladung}}

### 7.2 Monitoring & Fehlerbehandlung
{{ES_Monitoring}}

### 7.3 Bekannte Probleme / Technische Schulden
{{ES_BekannteProbleme}}

---

## 8. Sicherheit & Berechtigungen

### 8.1 Zugriff & Freigaben
{{ES_Zugriffe}}

### 8.2 Sensitivity Labels
{{ES_Labels}}

### 8.3 Risiken & Einschränkungen
{{ES_Risiken}}

---

## 9. Versionierung & Änderungsverlauf

### 9.1 Repository / Ablage
{{ES_Repository}}

### 9.2 Änderungsprotokoll

| Version | Datum | Änderung | Typ (fachlich/technisch) | Autor |
|-------|-------|---------|--------------------------|-------|
| 1.0 | {{ES_ExportDatum}} | Automatische Erst-Dokumentation | technisch | Auto-Dokumentation |

---

## 10. Freigabe & Review

| Rolle | Name | Datum | Kommentar |
|-----|------|-------|----------|
| Fachlich | {{REVIEW_FachName}} | {{REVIEW_FachDatum}} | {{REVIEW_FachKommentar}} |
| Technisch | {{REVIEW_TechName}} | {{REVIEW_TechDatum}} | {{REVIEW_TechKommentar}} |

---

## 11. Anhänge & Referenzen
- Übergeordnete Workspace-Dokumentation
- Architekturdiagramme
- Regulatorische Nachweise (separat)
"""


def _t(language: str, de: str, en: str) -> str:
    return en if (language or "de").lower().startswith("en") else de


def _manual_hint(language: str) -> str:
    return _t(language, "_Manuell zu ergänzen_", "_To be completed_")


def _none(language: str) -> str:
    return _t(language, "–", "–")


def build_nodes_table(
    nodes: list[EventstreamNodeInfo], language: str, empty_de: str, empty_en: str
) -> str:
    """Baut eine ``Name | Typ``-Tabelle für Quellen/Ziele/Operatoren."""
    if not nodes:
        return _t(language, empty_de, empty_en)
    header = _t(language, "| Name | Typ |", "| Name | Type |")
    dash = _none(language)
    lines = [header, "|---|---|"]
    for node in nodes:
        lines.append(
            f"| {_escape_cell(node.name) or dash} | "
            f"{_escape_cell(node.node_type) or dash} |"
        )
    return "\n".join(lines)


def build_service_hint(language: str = "de") -> str:
    return _t(
        language,
        "> **Hinweis:** Die Struktur (Quellen, Ziele, Operatoren) wird aus der "
        "Definition (`eventstream.json`) des Microsoft Fabric Service gelesen. "
        "Fachliche Beschreibungen sind manuell zu ergänzen.",
        "> **Note:** The structure (sources, destinations, operators) is read "
        "from the definition (`eventstream.json`) of the Microsoft Fabric "
        "service. Business descriptions must be completed manually.",
    )


_MANUAL_PLACEHOLDERS = (
    "KONTAKT_BusinessOwner",
    "KONTAKT_BusinessOwnerMail",
    "KONTAKT_TechOwner",
    "KONTAKT_TechOwnerMail",
    "KONTAKT_DataSteward",
    "KONTAKT_DataStewardMail",
    "KONTAKT_Betrieb",
    "KONTAKT_BetriebMail",
    "ES_Fachbereich",
    "ES_Konzerndomaene",
    "ES_Zielsetzung",
    "ES_Anwendungsfall",
    "ES_Konsumenten",
    "ES_DatenquellenDetail",
    "ES_ParameterHinweis",
    "ES_NullHandling",
    "ES_Validierungsregeln",
    "ES_Aufbewahrung",
    "ES_Optimierung",
    "ES_PerformanceHinweise",
    "ES_Optimierungen",
    "ES_Monitoring",
    "ES_BekannteProbleme",
    "ES_Zugriffe",
    "ES_Labels",
    "ES_Risiken",
    "ES_Repository",
    "REVIEW_FachName",
    "REVIEW_FachDatum",
    "REVIEW_FachKommentar",
    "REVIEW_TechName",
    "REVIEW_TechDatum",
    "REVIEW_TechKommentar",
)


def build_eventstream_values(
    es: EventstreamInfo, export_date: str, language: str = "de"
) -> dict[str, str]:
    """Baut das Platzhalter-Wörterbuch für die Eventstream-Vorlage."""
    hint = _manual_hint(language)
    dash = _none(language)

    values: dict[str, str] = {name: hint for name in _MANUAL_PLACEHOLDERS}
    values.update(
        {
            "ES_Name": es.name or dash,
            "ES_Beschreibung": es.description or dash,
            "ES_ID": es.id or dash,
            "ES_WebUrl": es.web_url or dash,
            "ES_AnzahlQuellen": str(len(es.sources)),
            "ES_AnzahlZiele": str(len(es.destinations)),
            "ES_AnzahlOperatoren": str(len(es.operators)),
            "ES_ConfiguredBy": es.configured_by or dash,
            "ES_ModifiedTime": es.modified_time or dash,
            "ES_ExportDatum": export_date,
            "ES_QuellenTabelle": build_nodes_table(
                es.sources, language, "_Keine Quellen verfügbar._",
                "_No sources available._",
            ),
            "ES_ZieleTabelle": build_nodes_table(
                es.destinations, language, "_Keine Ziele verfügbar._",
                "_No destinations available._",
            ),
            "ES_OperatorenTabelle": build_nodes_table(
                es.operators, language, "_Keine Operatoren verfügbar._",
                "_No operators available._",
            ),
            "ES_ServiceHinweis": build_service_hint(language),
            "ES_DatenquellenTabelle": build_nodes_table(
                es.sources, language, "_Keine Quellen verfügbar._",
                "_No sources available._",
            ),
            "ES_VerarbeitungHinweis": _t(
                language,
                "_Der Eventstream verarbeitet eingehende Events über die "
                "definierten Operatoren und leitet sie an die Ziele weiter. Bitte "
                "konkrete Verarbeitungslogik fachlich ergänzen._",
                "_The eventstream processes incoming events via the defined "
                "operators and routes them to the destinations. Please complete "
                "the concrete processing logic manually._",
            ),
            "ES_Beladung": _t(
                language,
                "_Der Eventstream läuft kontinuierlich (Streaming). Bitte "
                "Betrieb/Überwachung fachlich ergänzen._",
                "_The eventstream runs continuously (streaming). Please complete "
                "operations/monitoring details manually._",
            ),
        }
    )
    return values


def render_eventstream(
    template_content: str,
    es: EventstreamInfo,
    export_date: str,
    language: str = "de",
) -> str:
    """Rendert ein eigenständiges Eventstream-Dokument anhand der Vorlage."""
    values = build_eventstream_values(es, export_date, language)
    rendered, _warnings = TemplateRenderer().render(template_content, values)
    return rendered
