"""Generator für die Fabric Mirrored-Database-Dokumentation.

Definition-basiert (analog zu :mod:`core.copyjob_doc_generator`): die
``mirroring.json`` beschreibt Quelle (Source-Connection), Ziel und die
gespiegelten Tabellen. Rendering aus einem
:class:`~core.models.MirroredDatabaseInfo`.
"""
from __future__ import annotations

from core.models import MirroredDatabaseInfo, MirroredTableInfo
from core.template_renderer import TemplateRenderer
from core.workspace_doc_generator import _escape_cell, ensure_template, load_template

MIRROREDDB_TEMPLATE_FILENAME = "WorkspaceMirroredDatabasevorlage.md"

__all__ = [
    "MIRROREDDB_TEMPLATE_FILENAME",
    "DEFAULT_MIRROREDDB_TEMPLATE",
    "ensure_template",
    "load_template",
    "build_source_section",
    "build_tables_table",
    "build_service_hint",
    "build_mirroreddb_values",
    "render_mirroreddb",
]


DEFAULT_MIRROREDDB_TEMPLATE = """# Microsoft Fabric Mirrored-Database-Dokumentation

> **Hinweis:** Diese Dokumentation ist verpflichtend für alle Produktiv-Mirrored-Databases.
> 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 |
|-----|------|
| Mirrored-Database-Name | {{MD_Name}} |
| Beschreibung | {{MD_Beschreibung}} |
| Mirrored-Database-ID | {{MD_ID}} |
| Web-URL | {{MD_WebUrl}} |
| Quelltyp | {{MD_SourceType}} |
| Quelldatenbank | {{MD_SourceDatabase}} |
| Ziel-Standardschema | {{MD_DefaultSchema}} |
| Zielformat | {{MD_TargetFormat}} |
| Anzahl gespiegelter Tabellen | {{MD_AnzahlTabellen}} |
| Erstellt / konfiguriert von | {{MD_ConfiguredBy}} |
| Zuletzt geändert | {{MD_ModifiedTime}} |
| Fachbereich | {{MD_Fachbereich}} |
| Konzerndomäne | {{MD_Konzerndomaene}} |
| Aktuelle Version | 1.0 |
| Status | Produktiv |
| Letzte Aktualisierung | {{MD_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
{{MD_Zielsetzung}}

### 3.2 Fachlicher Anwendungsfall
{{MD_Anwendungsfall}}

### 3.3 Nachgelagerte Verbraucher (Semantic Models / Berichte / Notebooks)
{{MD_Konsumenten}}

---

## 4. Aufbau & Struktur

### 4.1 Quell- & Zielkonfiguration

{{MD_QuelleTabelle}}

### 4.2 Gespiegelte Tabellen

{{MD_TabellenTabelle}}

---

## 5. Datenquellen & Beladung

### 5.1 Quelldatenbank / vorgelagerte Systeme

{{MD_DatenquellenTabelle}}

### 5.2 Detailbeschreibung je Datenquelle
{{MD_DatenquellenDetail}}

---

## 6. Inhalt & Nutzung

{{MD_ServiceHinweis}}

### 6.1 Replikationsverhalten
{{MD_ReplikationHinweis}}

### 6.2 Parameter & Konfiguration
{{MD_ParameterHinweis}}

### 6.3 Datenqualität

- Umgang mit NULL-/Fehlwerten: {{MD_NullHandling}}
- Datenvalidierungsregeln: {{MD_Validierungsregeln}}
- Aufbewahrung / Historisierung: {{MD_Aufbewahrung}}

### 6.4 Performance-Hinweise

- Replikations-Latenz / Optimierung: {{MD_Optimierung}}
- Bekannte Performance-Engpässe: {{MD_PerformanceHinweise}}
- Weitere Maßnahmen: {{MD_Optimierungen}}

---

## 7. Betrieb & Wartung

### 7.1 Replikation & Orchestrierung

{{MD_Beladung}}

### 7.2 Monitoring & Fehlerbehandlung
{{MD_Monitoring}}

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

---

## 8. Sicherheit & Berechtigungen

### 8.1 Zugriff & Freigaben
{{MD_Zugriffe}}

### 8.2 Sensitivity Labels
{{MD_Labels}}

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

---

## 9. Versionierung & Änderungsverlauf

### 9.1 Repository / Ablage
{{MD_Repository}}

### 9.2 Änderungsprotokoll

| Version | Datum | Änderung | Typ (fachlich/technisch) | Autor |
|-------|-------|---------|--------------------------|-------|
| 1.0 | {{MD_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_source_section(md: MirroredDatabaseInfo, language: str = "de") -> str:
    """Baut die Tabelle mit Quell-/Zielkonfiguration."""
    dash = _none(language)
    header = _t(language, "| Eigenschaft | Wert |", "| Property | Value |")
    src_lbl = _t(language, "Quelltyp", "Source type")
    db_lbl = _t(language, "Quelldatenbank", "Source database")
    tgt_lbl = _t(language, "Zieltyp", "Target type")
    schema_lbl = _t(language, "Standardschema (Ziel)", "Default schema (target)")
    fmt_lbl = _t(language, "Zielformat", "Target format")
    ret_lbl = _t(language, "Aufbewahrung (Tage)", "Retention (days)")
    lines = [
        header,
        "|---|---|",
        f"| {src_lbl} | {_escape_cell(md.source_type) or dash} |",
        f"| {db_lbl} | {_escape_cell(md.source_database) or dash} |",
        f"| {tgt_lbl} | {_escape_cell(md.target_type) or dash} |",
        f"| {schema_lbl} | {_escape_cell(md.default_schema) or dash} |",
        f"| {fmt_lbl} | {_escape_cell(md.target_format) or dash} |",
        f"| {ret_lbl} | {_escape_cell(md.retention_days) or dash} |",
    ]
    return "\n".join(lines)


def build_tables_table(
    tables: list[MirroredTableInfo], language: str = "de"
) -> str:
    """Baut die Tabelle der gespiegelten Tabellen."""
    if not tables:
        return _t(
            language,
            "_Keine gespiegelten Tabellen angegeben (ggf. werden alle Tabellen "
            "gespiegelt)._",
            "_No mirrored tables specified (all tables may be mirrored)._",
        )
    header = _t(language, "| Schema | Tabelle |", "| Schema | Table |")
    dash = _none(language)
    lines = [header, "|---|---|"]
    for tbl in tables:
        lines.append(
            f"| {_escape_cell(tbl.schema_name) or dash} | "
            f"{_escape_cell(tbl.table_name) or dash} |"
        )
    return "\n".join(lines)


def build_service_hint(language: str = "de") -> str:
    return _t(
        language,
        "> **Hinweis:** Die Struktur wird aus der Definition (`mirroring.json`) "
        "des Microsoft Fabric Service gelesen. Die Spiegelung erfolgt automatisch "
        "aus der Quelldatenbank; fachliche Beschreibungen sind manuell zu ergänzen.",
        "> **Note:** The structure is read from the definition (`mirroring.json`) "
        "of the Microsoft Fabric service. Mirroring happens automatically from "
        "the source database; business descriptions must be completed manually.",
    )


_MANUAL_PLACEHOLDERS = (
    "KONTAKT_BusinessOwner",
    "KONTAKT_BusinessOwnerMail",
    "KONTAKT_TechOwner",
    "KONTAKT_TechOwnerMail",
    "KONTAKT_DataSteward",
    "KONTAKT_DataStewardMail",
    "KONTAKT_Betrieb",
    "KONTAKT_BetriebMail",
    "MD_Fachbereich",
    "MD_Konzerndomaene",
    "MD_Zielsetzung",
    "MD_Anwendungsfall",
    "MD_Konsumenten",
    "MD_DatenquellenDetail",
    "MD_ParameterHinweis",
    "MD_NullHandling",
    "MD_Validierungsregeln",
    "MD_Aufbewahrung",
    "MD_Optimierung",
    "MD_PerformanceHinweise",
    "MD_Optimierungen",
    "MD_Monitoring",
    "MD_BekannteProbleme",
    "MD_Zugriffe",
    "MD_Labels",
    "MD_Risiken",
    "MD_Repository",
    "REVIEW_FachName",
    "REVIEW_FachDatum",
    "REVIEW_FachKommentar",
    "REVIEW_TechName",
    "REVIEW_TechDatum",
    "REVIEW_TechKommentar",
)


def build_mirroreddb_values(
    md: MirroredDatabaseInfo, export_date: str, language: str = "de"
) -> dict[str, str]:
    """Baut das Platzhalter-Wörterbuch für die Mirrored-Database-Vorlage."""
    hint = _manual_hint(language)
    dash = _none(language)

    values: dict[str, str] = {name: hint for name in _MANUAL_PLACEHOLDERS}
    values.update(
        {
            "MD_Name": md.name or dash,
            "MD_Beschreibung": md.description or dash,
            "MD_ID": md.id or dash,
            "MD_WebUrl": md.web_url or dash,
            "MD_SourceType": md.source_type or dash,
            "MD_SourceDatabase": md.source_database or dash,
            "MD_DefaultSchema": md.default_schema or dash,
            "MD_TargetFormat": md.target_format or dash,
            "MD_AnzahlTabellen": str(len(md.mirrored_tables)),
            "MD_ConfiguredBy": md.configured_by or dash,
            "MD_ModifiedTime": md.modified_time or dash,
            "MD_ExportDatum": export_date,
            "MD_QuelleTabelle": build_source_section(md, language),
            "MD_TabellenTabelle": build_tables_table(md.mirrored_tables, language),
            "MD_ServiceHinweis": build_service_hint(language),
            "MD_DatenquellenTabelle": _t(
                language,
                f"_Quelltyp: {md.source_type or dash}, Quelldatenbank: "
                f"{md.source_database or dash}. Weitere Details bitte fachlich "
                f"ergänzen._",
                f"_Source type: {md.source_type or dash}, source database: "
                f"{md.source_database or dash}. Please complete further details "
                f"manually._",
            ),
            "MD_ReplikationHinweis": _t(
                language,
                "_Die Mirrored Database repliziert Änderungen der Quelldatenbank "
                "nahezu in Echtzeit nach OneLake (Delta). Bitte konkrete "
                "Replikationsmodalitäten fachlich ergänzen._",
                "_The mirrored database replicates changes from the source "
                "database to OneLake (Delta) in near real time. Please complete "
                "the concrete replication details manually._",
            ),
            "MD_Beladung": _t(
                language,
                "_Die Beladung erfolgt automatisch über die Fabric-Mirroring-"
                "Engine. Bitte Überwachung/Orchestrierung fachlich ergänzen._",
                "_Loading happens automatically via the Fabric mirroring engine. "
                "Please complete monitoring/orchestration details manually._",
            ),
        }
    )
    return values


def render_mirroreddb(
    template_content: str,
    md: MirroredDatabaseInfo,
    export_date: str,
    language: str = "de",
) -> str:
    """Rendert ein eigenständiges Mirrored-Database-Dokument anhand der Vorlage."""
    values = build_mirroreddb_values(md, export_date, language)
    rendered, _warnings = TemplateRenderer().render(template_content, values)
    return rendered
