"""Templates resource client for V1."""

from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from concentriq.client import ConcentriqClient


class Templates:
    """Client for Template resources (/api/templates)."""

    def __init__(self, client: "ConcentriqClient"):
        """Initialize with client instance.

        Args:
            client: ConcentriqClient instance
        """
        self._client = client
        self._base_path = "/api/templates"

    def list(self, filters: dict[str, Any] | None = None) -> dict[str, dict[str, Any]]:
        """List all templates.

        Args:
            filters: Filter criteria
                - name: List of template names
                - imageSetId: List of image set IDs
                - organizationId: List of organization IDs
                - templateId: List of template IDs
                - moduleId: List of module IDs

        Returns:
            Dictionary of template dictionaries keyed by template ID (as string)

        Raises:
            AuthenticationError: If not authenticated

        Example:
            templates = client.v1.templates.list()
            for template_id, template in templates.items():
                print(f"{template['name']}: {template['description']}")

            # With filters
            clinical_templates = client.v1.templates.list(
                filters={"name": ["Clinical"], "moduleId": [5]}
            )
        """
        params = {}
        if filters:
            params["filters"] = json.dumps(filters)

        response = self._client._request("GET", self._base_path, params=params)
        data = response.json()

        # V1 API returns data as keyed object: {templates: {"1": {...}, "2": {...}}}
        return data.get("data", {}).get("templates", {})

    def create(self, data: dict[str, Any]) -> dict[str, Any]:
        """Create a new template or duplicate an existing one.

        Args:
            data: Template data
                For new template:
                - name: Template name (required)
                - description: Template description (required)
                - moduleId: Module ID (optional)

                For duplicating template:
                - cloneSourceId: Template ID to clone (required)
                - name: New template name (optional)
                - moduleId: Module ID (optional)

        Returns:
            Created template dictionary

        Raises:
            AuthenticationError: If not authenticated
            AuthorizationError: If not authorized to manage templates
            ValidationError: If data is invalid

        Example:
            # Create new template
            template = client.v1.templates.create({
                "name": "Clinical Template",
                "description": "Template for clinical data",
                "moduleId": 5
            })

            # Duplicate existing template
            cloned = client.v1.templates.create({
                "cloneSourceId": 123,
                "name": "Cloned Template"
            })
        """
        response = self._client._request("POST", self._base_path, json=data)
        result = response.json()

        # V1 API returns data in envelope format
        return result.get("data", {})

    def update(self, id: int, data: dict[str, Any]) -> dict[str, Any]:
        """Update an existing template.

        Args:
            id: Template ID
            data: Updated template data
                - name: Template name (optional)
                - description: Template description (optional)
                - isDefault: Whether template is organization default (optional)
                - sharedWithOrganization: Whether shared with organization (optional)
                - ownerId: Owner user ID (optional)
                - moduleId: Module ID (optional)

        Returns:
            Updated template dictionary

        Raises:
            AuthenticationError: If not authenticated
            AuthorizationError: If not authorized to manage this template
            NotFoundError: If template not found
            ValidationError: If data is invalid

        Example:
            updated = client.v1.templates.update(123, {
                "name": "Updated Template",
                "sharedWithOrganization": True
            })
        """
        response = self._client._request("PATCH", f"{self._base_path}/{id}", json=data)
        result = response.json()

        # V1 API returns updated template data
        return result.get("data", {})

    def delete(self, id: int) -> None:
        """Delete a template.

        Args:
            id: Template ID

        Returns:
            None (backend returns success message)

        Raises:
            AuthenticationError: If not authenticated
            AuthorizationError: If not authorized to manage this template
            NotFoundError: If template not found

        Example:
            client.v1.templates.delete(123)
        """
        self._client._request("DELETE", f"{self._base_path}/{id}")
        # DELETE returns success message, no need to return anything
