"""Generator für die Power BI / Fabric Dashboard-Dokumentation.

Analog zu :mod:`core.lakehouse_doc_generator`: eingebaute Standard-Vorlage +
Rendering aus einem :class:`~core.models.DashboardInfo`. Dashboards sind
Power-BI-Artefakte (kein ``getDefinition``); die Doku stützt sich auf die
Item-Properties und die Kachelliste (``/tiles``).
"""
from __future__ import annotations

from core.models import DashboardInfo, DashboardTileInfo
from core.template_renderer import TemplateRenderer
from core.workspace_doc_generator import _escape_cell, ensure_template, load_template

DASHBOARD_TEMPLATE_FILENAME = "WorkspaceDashboardvorlage.md"

__all__ = [
    "DASHBOARD_TEMPLATE_FILENAME",
    "DEFAULT_DASHBOARD_TEMPLATE",
    "ensure_template",
    "load_template",
    "build_tiles_table",
    "build_linked_items_section",
    "build_service_hint",
    "build_dashboard_values",
    "render_dashboard",
]


DEFAULT_DASHBOARD_TEMPLATE = """# Power BI / Fabric Dashboard-Dokumentation

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

---

## 1. Metadaten

| Feld | Wert |
|-----|------|
| Dashboard-Name | {{DB_Name}} |
| Beschreibung | {{DB_Beschreibung}} |
| Dashboard-ID | {{DB_ID}} |
| Web-URL | {{DB_WebUrl}} |
| Schreibgeschützt | {{DB_ReadOnly}} |
| Datenklassifizierung | {{DB_DataClassification}} |
| Anzahl Kacheln | {{DB_AnzahlKacheln}} |
| Erstellt / konfiguriert von | {{DB_ConfiguredBy}} |
| Zuletzt geändert | {{DB_ModifiedTime}} |
| Fachbereich | {{DB_Fachbereich}} |
| Konzerndomäne | {{DB_Konzerndomaene}} |
| Aktuelle Version | 1.0 |
| Status | Produktiv |
| Letzte Aktualisierung | {{DB_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
{{DB_Zielsetzung}}

### 3.2 Fachlicher Anwendungsfall
{{DB_Anwendungsfall}}

### 3.3 Zielgruppe / Konsumenten
{{DB_Konsumenten}}

---

## 4. Aufbau & Inhalt

### 4.1 Übersicht der Kacheln

{{DB_KachelnTabelle}}

### 4.2 Verknüpfte Berichte & Semantic Models

{{DB_VerknuepfungenTabelle}}

---

## 5. Datenquellen & Abhängigkeiten

### 5.1 Zugrundeliegende Datenquellen

{{DB_DatenquellenTabelle}}

### 5.2 Detailbeschreibung je Datenquelle
{{DB_DatenquellenDetail}}

---

## 6. Nutzung & Aussagekraft

{{DB_ServiceHinweis}}

### 6.1 Kacheln im Detail

{{DB_KachelnDetail}}

### 6.2 Fachliche Interpretation der Kennzahlen
{{DB_Interpretation}}

### 6.3 Aktualität & Datenqualität

- Datenaktualität (abhängig von Quell-Modellen): {{DB_Aktualitaet}}
- Bekannte Einschränkungen: {{DB_Einschraenkungen}}

---

## 7. Betrieb & Wartung

### 7.1 Aktualisierung & Abonnements
{{DB_Aktualisierung}}

### 7.2 Monitoring & Support
{{DB_Monitoring}}

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

---

## 8. Sicherheit & Berechtigungen

### 8.1 Zugriff & Freigaben
{{DB_Zugriffe}}

### 8.2 Sensitivity Labels
{{DB_Labels}}

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

---

## 9. Versionierung & Änderungsverlauf

### 9.1 Repository / Ablage
{{DB_Repository}}

### 9.2 Änderungsprotokoll

| Version | Datum | Änderung | Typ (fachlich/technisch) | Autor |
|-------|-------|---------|--------------------------|-------|
| 1.0 | {{DB_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_tiles_table(tiles: list[DashboardTileInfo], language: str = "de") -> str:
    """Baut die Übersichtstabelle der Dashboard-Kacheln."""
    if not tiles:
        return _t(
            language, "_Keine Kacheln verfügbar._", "_No tiles available._"
        )
    header = _t(
        language,
        "| # | Titel | Untertitel | Verknüpfter Bericht | Semantic Model |",
        "| # | Title | Subtitle | Linked report | Semantic model |",
    )
    dash = _none(language)
    lines = [header, "|---|---|---|---|---|"]
    for idx, tile in enumerate(tiles, start=1):
        lines.append(
            f"| {idx} | {_escape_cell(tile.title) or dash} | "
            f"{_escape_cell(tile.subtitle) or dash} | "
            f"{_escape_cell(tile.report_id) or dash} | "
            f"{_escape_cell(tile.dataset_id) or dash} |"
        )
    return "\n".join(lines)


def build_linked_items_section(
    tiles: list[DashboardTileInfo], language: str = "de"
) -> str:
    """Baut die Tabelle der verknüpften Berichte/Semantic Models (dedupliziert)."""
    report_ids = sorted({t.report_id for t in tiles if t.report_id})
    dataset_ids = sorted({t.dataset_id for t in tiles if t.dataset_id})
    if not report_ids and not dataset_ids:
        return _t(
            language,
            "_Keine verknüpften Berichte oder Semantic Models ermittelt._",
            "_No linked reports or semantic models identified._",
        )
    header = _t(language, "| Typ | ID |", "| Type | ID |")
    report_lbl = _t(language, "Bericht", "Report")
    model_lbl = _t(language, "Semantic Model", "Semantic model")
    lines = [header, "|---|---|"]
    for rid in report_ids:
        lines.append(f"| {report_lbl} | {_escape_cell(rid)} |")
    for did in dataset_ids:
        lines.append(f"| {model_lbl} | {_escape_cell(did)} |")
    return "\n".join(lines)


def build_service_hint(language: str = "de") -> str:
    return _t(
        language,
        "> **Hinweis:** Die Metadaten und Kacheln stammen aus dem Power BI / "
        "Fabric Service (Dashboard-Properties und `/tiles`). Ein Dashboard "
        "besitzt keine Code-Definition; die fachliche Aussage der Kacheln ist "
        "manuell zu ergänzen.",
        "> **Note:** The metadata and tiles come from the Power BI / Fabric "
        "service (dashboard properties and `/tiles`). A dashboard has no code "
        "definition; the business meaning of the tiles must be completed "
        "manually.",
    )


_MANUAL_PLACEHOLDERS = (
    "KONTAKT_BusinessOwner",
    "KONTAKT_BusinessOwnerMail",
    "KONTAKT_TechOwner",
    "KONTAKT_TechOwnerMail",
    "KONTAKT_DataSteward",
    "KONTAKT_DataStewardMail",
    "KONTAKT_Betrieb",
    "KONTAKT_BetriebMail",
    "DB_Fachbereich",
    "DB_Konzerndomaene",
    "DB_Zielsetzung",
    "DB_Anwendungsfall",
    "DB_Konsumenten",
    "DB_DatenquellenDetail",
    "DB_Interpretation",
    "DB_Aktualitaet",
    "DB_Einschraenkungen",
    "DB_Aktualisierung",
    "DB_Monitoring",
    "DB_BekannteProbleme",
    "DB_Zugriffe",
    "DB_Labels",
    "DB_Risiken",
    "DB_Repository",
    "REVIEW_FachName",
    "REVIEW_FachDatum",
    "REVIEW_FachKommentar",
    "REVIEW_TechName",
    "REVIEW_TechDatum",
    "REVIEW_TechKommentar",
)


def build_dashboard_values(
    db: DashboardInfo, export_date: str, language: str = "de"
) -> dict[str, str]:
    """Baut das Platzhalter-Wörterbuch für die Dashboard-Vorlage."""
    hint = _manual_hint(language)
    dash = _none(language)
    yes = _t(language, "Ja", "Yes")
    no = _t(language, "Nein", "No")

    values: dict[str, str] = {name: hint for name in _MANUAL_PLACEHOLDERS}
    values.update(
        {
            "DB_Name": db.name or dash,
            "DB_Beschreibung": db.description or dash,
            "DB_ID": db.id or dash,
            "DB_WebUrl": db.web_url or dash,
            "DB_ReadOnly": yes if db.is_read_only else no,
            "DB_DataClassification": db.data_classification or dash,
            "DB_AnzahlKacheln": str(len(db.tiles)),
            "DB_ConfiguredBy": db.configured_by or dash,
            "DB_ModifiedTime": db.modified_time or dash,
            "DB_ExportDatum": export_date,
            "DB_KachelnTabelle": build_tiles_table(db.tiles, language),
            "DB_KachelnDetail": build_tiles_table(db.tiles, language),
            "DB_VerknuepfungenTabelle": build_linked_items_section(db.tiles, language),
            "DB_ServiceHinweis": build_service_hint(language),
            "DB_DatenquellenTabelle": _t(
                language,
                "_Die zugrundeliegenden Datenquellen ergeben sich aus den "
                "verknüpften Berichten/Semantic Models (siehe Abschnitt 4.2). "
                "Bitte fachlich ergänzen._",
                "_The underlying data sources are derived from the linked "
                "reports/semantic models (see section 4.2). Please complete "
                "manually._",
            ),
        }
    )
    return values


def render_dashboard(
    template_content: str,
    db: DashboardInfo,
    export_date: str,
    language: str = "de",
) -> str:
    """Rendert ein eigenständiges Dashboard-Dokument anhand der Vorlage."""
    values = build_dashboard_values(db, export_date, language)
    rendered, _warnings = TemplateRenderer().render(template_content, values)
    return rendered
