"""Htmx-aware view mixins for LARAsuite apps."""

from django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.utils.safestring import mark_safe
from django.views.generic.base import TemplateResponseMixin


class HtmxResponseMixin(TemplateResponseMixin):
    """
    Return a partial for htmx requests, auto-wrapped full page otherwise.

    Every view only needs ``partial_template_name``.  For htmx requests the
    partial is rendered directly.  For normal browser requests the partial is
    rendered first, then injected into ``wrapper_template`` via the
    ``inner_content`` context variable — no per-app full-page template needed.

    Attributes:
        partial_template_name: Path to the partial template rendered for every
            request type.
        wrapper_template: Full-page layout that wraps the partial for normal
            (non-htmx) browser requests.
        page_title: Value passed to the wrapper's ``<title>`` block.

    Example::

        class ProjectListView(HtmxResponseMixin, ListView):
            partial_template_name = "myapp/partials/list.html"
            page_title = "Projects"

    """

    partial_template_name: str | None = None
    wrapper_template: str = "lara_django_base/htmx_wrapper.html"
    page_title: str = ""

    def get_template_names(self) -> list[str]:
        """Always render the partial — wrapping happens in *render_to_response*."""
        if self.partial_template_name:
            return [self.partial_template_name]
        return super().get_template_names()

    def render_to_response(self, context: dict, **response_kwargs) -> TemplateResponse:
        """Wrap partial in full layout for non-htmx requests."""
        if getattr(self.request, "htmx", False):
            # htmx request → return bare partial
            return super().render_to_response(context, **response_kwargs)

        # Normal request → render partial, inject into wrapper
        partial_html = render_to_string(
            self.get_template_names()[0],
            context=context,
            request=self.request,
        )
        wrapper_context = {
            **context,
            "inner_content": mark_safe(partial_html),  # noqa: S308
            "page_title": self.page_title,
        }
        return TemplateResponse(
            self.request,
            self.wrapper_template,
            wrapper_context,
            **response_kwargs,
        )
