"""Template discovery and manifest loading for Tableau templates."""

from __future__ import annotations

from pathlib import Path
from typing import Dict, List, Tuple

import yaml

from g_gremlin.tableau.template_models import TemplateManifest


class TemplateManager:
    """Discover and load template manifests."""

    def __init__(self, templates_dir: Path | None = None) -> None:
        self.templates_dir = templates_dir or (Path(__file__).parent / "templates")

    def list_templates(self) -> List[Dict[str, object]]:
        """Return available templates with summary metadata."""
        templates: List[Dict[str, object]] = []
        for manifest_path in sorted(self.templates_dir.glob("*.manifest.yaml")):
            manifest = self._load_manifest_path(manifest_path)
            roles = [role.id for role in manifest.canonical_roles]
            templates.append(
                {
                    "name": manifest.template.name,
                    "display_name": manifest.template.display_name,
                    "description": manifest.template.description,
                    "viz_type": manifest.template.viz_type,
                    "roles": roles,
                    "data_mode": manifest.template.data_mode,
                    "version": manifest.template.version,
                }
            )
        return templates

    def get_manifest_path(self, name: str) -> Path:
        """Return manifest path for a template name."""
        manifest_path = self.templates_dir / f"{name}.manifest.yaml"
        if not manifest_path.exists():
            raise FileNotFoundError(f"Template manifest not found for {name}")
        return manifest_path

    def load_manifest(self, name: str) -> TemplateManifest:
        """Load manifest by template name."""
        return self._load_manifest_path(self.get_manifest_path(name))

    def get_template_paths(self, name: str) -> Tuple[Path, Path]:
        """Return (manifest_path, twb_path) for template name."""
        manifest_path = self.get_manifest_path(name)
        manifest = self._load_manifest_path(manifest_path)
        twb_path = self.templates_dir / manifest.template.twb_file
        if not twb_path.exists():
            raise FileNotFoundError(f"Template TWB not found: {twb_path}")
        return manifest_path, twb_path

    def _load_manifest_path(self, manifest_path: Path) -> TemplateManifest:
        data = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
        return TemplateManifest.model_validate(data)


__all__ = ["TemplateManager"]
