from __future__ import annotations

"""Templates resource — list, get, and register templates."""

from pathlib import Path

from nexure.exceptions import ValidationError
from nexure.models import TemplateDetail, TemplateInfo, TemplateList
from nexure.resources._base import BaseResource


class TemplatesResource(BaseResource):
    """nx.templates — template management."""

    def list(self, *, industry: str | None = None) -> TemplateList:
        """List available templates.

        Args:
            industry: Filter by industry (e.g. "financial_services").

        Returns:
            TemplateList with available templates.
        """
        params = {}
        if industry is not None:
            params["industry"] = industry
        data = self._get("/templates", params=params or None)
        return TemplateList(**data)

    def get(self, template_id: str) -> TemplateDetail:
        """Get full template detail by ID.

        Args:
            template_id: Template identifier (e.g. "credit_underwriting").

        Returns:
            TemplateDetail with config.
        """
        data = self._get(f"/templates/{template_id}")
        return TemplateDetail(**data)

    def register(
        self,
        *,
        template_yaml: str | None = None,
        filepath: str | Path | None = None,
    ) -> TemplateInfo:
        """Register a custom template from YAML.

        Provide either ``template_yaml`` (raw string) or ``filepath``
        (path to a YAML file on disk). Exactly one must be given.

        Args:
            template_yaml: Full YAML content of the template.
            filepath: Path to a YAML template file.

        Returns:
            TemplateInfo for the registered template.
        """
        yaml_content = _resolve_yaml(template_yaml, filepath)
        data = self._post("/templates", json={"template_yaml": yaml_content})
        return TemplateInfo(**data)

    def update(self, template_id: str, *, template_yaml: str) -> TemplateInfo:
        """Update a template (creates new version).

        Args:
            template_id: Template identifier to update.
            template_yaml: Full YAML content with the new version.

        Returns:
            TemplateInfo for the new version.
        """
        data = self._put(f"/templates/{template_id}", json={"template_yaml": template_yaml})
        return TemplateInfo(**data)


def _resolve_yaml(
    template_yaml: str | None,
    filepath: str | Path | None,
) -> str:
    """Resolve YAML content from either a string or a file path."""
    if template_yaml and filepath:
        raise ValidationError("Provide either template_yaml or filepath, not both.")
    if filepath:
        return Path(filepath).read_text(encoding="utf-8")
    if template_yaml:
        return template_yaml
    raise ValidationError("Must provide template_yaml or filepath.")
