"""
Base forms module for lara_django_material.

:PROJECT: LARAsuite

:details: Common form utilities, widgets, and renderer
         optimized for Python 3.13+ with ClassVar pattern.

:authors: mark doerr <mark.doerr@uni-greifswald.de>

.. note:: Contains shared components used across all form modules
.. todo:: -
"""

from typing import ClassVar

from django import forms
from django.forms.renderers import TemplatesSetting

from ..models import ExtraData, PartDeviceClass


class CustomFormRenderer(TemplatesSetting):
    """Custom form renderer for lara_django_material forms."""

    field_template_name = "lara_django_material/forms/field_group.html"


class SearchableSelectMultiple(forms.SelectMultiple):
    """Custom widget for searchable multi-select using Alpine.js."""

    template_name = "lara_django_material/widgets/searchable_select_multiple.html"

    def __init__(self, attrs=None):
        """Initialize widget with custom CSS class."""
        default_attrs = {"class": "searchable-select-multiple"}
        if attrs:
            default_attrs.update(attrs)
        super().__init__(attrs=default_attrs)


## -------------- ExtraData -------------- ##


class ExtraDataCreateForm(forms.ModelForm):
    """Form for creating new ExtraData entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for ExtraDataCreateForm."""

        model = ExtraData
        fields = (
            "data_type",
            "namespace",
            "name",
            "name_display",
            "version",
            "url",
            "description",
            "file",
            "media_type",
        )

        text_fields_required: ClassVar = ("data_type", "name")
        text_fields: ClassVar = ("name_display", "version", "media_type")
        textarea_fields: ClassVar = ("description",)
        url_fields: ClassVar = ("url",)

        widgets: ClassVar = {
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full", "required": True})
                for field in text_fields_required
            },
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in text_fields
            },
            **{
                field: forms.Textarea(attrs={"class": "textarea textarea-sm textarea-bordered w-full", "rows": 3})
                for field in textarea_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "file": forms.ClearableFileInput(attrs={"class": "file-input file-input-sm file-input-bordered w-full"}),
        }


class ExtraDataUpdateForm(forms.ModelForm):
    """Form for updating existing ExtraData entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for ExtraDataUpdateForm."""

        model = ExtraData
        fields = (
            "data_type",
            "name",
            "name_display",
            "namespace",
            "version",
            "hash_sha256",
            "data_json",
            "media_type",
            "iri",
            "url",
            "description",
            "image",
            "file",
        )

        text_fields_required: ClassVar = ("data_type", "name")
        text_fields: ClassVar = ("name_display", "version", "media_type", "hash_sha256")
        textarea_fields: ClassVar = ("description",)
        url_fields: ClassVar = ("iri", "url")

        widgets: ClassVar = {
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full", "required": True})
                for field in text_fields_required
            },
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in text_fields
            },
            **{
                field: forms.Textarea(attrs={"class": "textarea textarea-sm textarea-bordered w-full", "rows": 3})
                for field in textarea_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "data_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "image": forms.ClearableFileInput(attrs={"class": "file-input file-input-sm file-input-bordered w-full"}),
            "file": forms.ClearableFileInput(attrs={"class": "file-input file-input-sm file-input-bordered w-full"}),
        }


## -------------- PartDeviceClass -------------- ##


class PartDeviceClassCreateForm(forms.ModelForm):
    """Form for creating new PartDeviceClass entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for PartDeviceClassCreateForm."""

        model = PartDeviceClass
        fields = ("name", "iri", "description")

        text_fields_required: ClassVar = ("name",)
        textarea_fields: ClassVar = ("description",)
        url_fields: ClassVar = ("iri",)

        widgets: ClassVar = {
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full", "required": True})
                for field in text_fields_required
            },
            **{
                field: forms.Textarea(attrs={"class": "textarea textarea-sm textarea-bordered w-full", "rows": 3})
                for field in textarea_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
        }


class PartDeviceClassUpdateForm(forms.ModelForm):
    """Form for updating existing PartDeviceClass entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for PartDeviceClassUpdateForm."""

        model = PartDeviceClass
        fields = ("name", "iri", "description")

        text_fields_required: ClassVar = ("name",)
        textarea_fields: ClassVar = ("description",)
        url_fields: ClassVar = ("iri",)

        widgets: ClassVar = {
            **{
                field: forms.TextInput(attrs={"class": "input input-sm input-bordered w-full", "required": True})
                for field in text_fields_required
            },
            **{
                field: forms.Textarea(attrs={"class": "textarea textarea-sm textarea-bordered w-full", "rows": 3})
                for field in textarea_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
        }
