"""Template Renderer für die PBI Documentation by Oliver Gropp.

Ersetzt {{...}}-Platzhalter durch zugeordnete Werte und erzeugt
das Ausgabedokument. Unbefüllte Platzhalter werden als leerer String
belassen und eine Warnung wird erzeugt.
"""
from __future__ import annotations

import re

from core.models import FileWriteError

# Gleiche Regex wie im Parser für {{...}}-Platzhalter
_PLACEHOLDER_RE = re.compile(r"\{\{(.+?)\}\}")


class TemplateRenderer:
    """Renderer für Markdown-Dokumentationsvorlagen mit {{...}}-Platzhaltern."""

    def render(
        self, template_content: str, values: dict[str, str]
    ) -> tuple[str, list[str]]:
        """Ersetzt alle Platzhalter durch zugeordnete Werte.

        Args:
            template_content: Der Markdown-Text der Vorlage.
            values: Zuordnung Platzhalter-Name → Wert.

        Returns:
            Tuple aus (gerenderter Inhalt, Liste von Warnungen).
            Für Platzhalter ohne Wert wird ein leerer String eingesetzt
            und eine Warnung erzeugt.
        """
        warnings: list[str] = []

        def _replace(match: re.Match) -> str:
            name = match.group(1).strip()
            if name in values:
                return values[name]
            warnings.append(
                f"Platzhalter '{{{{{name}}}}}' hat keinen zugeordneten Wert."
            )
            return ""

        rendered = _PLACEHOLDER_RE.sub(_replace, template_content)
        return rendered, warnings

    def render_to_file(
        self,
        template_content: str,
        values: dict[str, str],
        output_path: str,
    ) -> list[str]:
        """Rendert das Template und speichert das Ergebnis als Datei.

        Args:
            template_content: Der Markdown-Text der Vorlage.
            values: Zuordnung Platzhalter-Name → Wert.
            output_path: Pfad für die Ausgabedatei.

        Returns:
            Liste von Warnungen (leere Liste wenn alle Platzhalter befüllt).

        Raises:
            FileWriteError: Wenn die Datei nicht geschrieben werden kann.
        """
        rendered, warnings = self.render(template_content, values)

        try:
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(rendered)
        except OSError as exc:
            raise FileWriteError(
                f"Ausgabedokument kann nicht gespeichert werden: {output_path} – {exc}"
            ) from exc

        return warnings
