"""
LARAsuite lara_django_sequences admin forms.

:PROJECT: LARAsuite

*lara_django_sequences admin*

:details: lara_django_sequences admin module backend form configuration.
         -
:authors: mark doerr <mark.doerr@uni-greifswald.de>

.. note:: -
.. todo:: - run "lara-django-dev forms_generator -c lara_django_sequences > forms.py" to update this file
________________________________________________________________________
"""

# django crispy forms s. https://github.com/django-crispy-forms/django-crispy-forms for []
# generated with django-extensions forms_generator -c  [] > forms.py (LARA-version)

from typing import ClassVar

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

from .models import ExtraData, Sequence, SequenceClass


class CustomFormRenderer(TemplatesSetting):
    """Custom renderer using app-specific field-group template."""

    field_template_name = "lara_django_sequences/forms/field_group.html"


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

    template_name = "lara_django_sequences/widgets/searchable_select_multiple.html"

    def __init__(self, attrs: dict[str, str] | None = None) -> None:
        """Initialize searchable multi-select widget with default class."""
        default_attrs = {"class": "searchable-select-multiple"}
        if attrs:
            default_attrs.update(attrs)
        super().__init__(attrs=default_attrs)


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

    This form includes fields for all attributes of the ExtraData model,
    allowing users to input data for each field.
    It uses crispy forms for better layout and styling.
    """

    default_renderer: ClassVar = CustomFormRenderer()

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

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

        text_fields_required: ClassVar = ("name",)

        text_fields: ClassVar = (
            "name_full",
            "name_display",
            "version",
            "hash_sha256",
        )

        textarea_fields: ClassVar = (
            "data_json",
            "description",
        )

        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
            },
            "data_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "media_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "url": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "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"}),
        }


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

    This form includes the same fields as the create form but with
    an update submit button.
    """

    default_renderer: ClassVar = CustomFormRenderer()

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

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

        text_fields_required: ClassVar = ("name",)

        text_fields: ClassVar = (
            "name_full",
            "name_display",
            "version",
            "hash_sha256",
        )

        textarea_fields: ClassVar = (
            "data_json",
            "description",
        )

        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
            },
            "data_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "media_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "url": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "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"}),
        }


class SequenceClassCreateForm(forms.ModelForm):
    """Form for creating SequenceClass instances."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for SequenceClassCreateForm."""

        model = SequenceClass
        fields = ("name", "encoding", "iri", "description")

        text_fields_required: ClassVar = ("name",)

        textarea_fields: ClassVar = (
            "encoding",
            "description",
        )

        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
            },
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
        }


class SequenceClassUpdateForm(forms.ModelForm):
    """Form for updating SequenceClass instances."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for SequenceClassUpdateForm."""

        model = SequenceClass
        fields = ("name", "encoding", "iri", "description")

        text_fields_required: ClassVar = ("name",)

        textarea_fields: ClassVar = (
            "encoding",
            "description",
        )

        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
            },
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
        }


class SequenceCreateForm(forms.ModelForm):
    """Form for creating Sequence instances."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for SequenceCreateForm."""

        model = Sequence
        fields = (
            "namespace",
            "name_display",
            "name",
            "hash_sha256",
            "hash_blockchain",
            "sequence_class",
            "sequence",
            "properties",
            "uniprot_accession",
            "ncbi_gi",
            "ncbi_accession_version",
            "source_organism",
            "media_type",
            "sequence_file",
            "status",
            "version",
            "tags",
            "description",
            "iri",
            "datetime_last_modified",
        )

        text_fields_required: ClassVar = ("name",)

        text_fields: ClassVar = (
            "name_display",
            "hash_sha256",
            "hash_blockchain",
            "uniprot_accession",
            "ncbi_gi",
            "ncbi_accession_version",
            "version",
        )

        textarea_fields: ClassVar = (
            "sequence",
            "properties",
            "source_organism",
            "description",
        )

        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
            },
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "sequence_class": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "media_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "status": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "tags": SearchableSelectMultiple(),
            "sequence_file": forms.ClearableFileInput(
                attrs={"class": "file-input file-input-sm file-input-bordered w-full"}
            ),
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "datetime_last_modified": forms.DateTimeInput(
                attrs={"class": "input input-sm input-bordered w-full", "type": "datetime-local"}
            ),
        }


class SequenceUpdateForm(forms.ModelForm):
    """Form for updating Sequence instances."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for SequenceUpdateForm."""

        model = Sequence
        fields = (
            "namespace",
            "name_display",
            "name",
            "hash_sha256",
            "hash_blockchain",
            "sequence_class",
            "sequence",
            "properties",
            "uniprot_accession",
            "ncbi_gi",
            "ncbi_accession_version",
            "source_organism",
            "media_type",
            "sequence_file",
            "status",
            "version",
            "tags",
            "description",
            "iri",
            "datetime_last_modified",
        )

        text_fields_required: ClassVar = ("name",)

        text_fields: ClassVar = (
            "name_display",
            "hash_sha256",
            "hash_blockchain",
            "uniprot_accession",
            "ncbi_gi",
            "ncbi_accession_version",
            "version",
        )

        textarea_fields: ClassVar = (
            "sequence",
            "properties",
            "source_organism",
            "description",
        )

        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
            },
            "namespace": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "sequence_class": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "media_type": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "status": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "tags": SearchableSelectMultiple(),
            "sequence_file": forms.ClearableFileInput(
                attrs={"class": "file-input file-input-sm file-input-bordered w-full"}
            ),
            "iri": forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}),
            "datetime_last_modified": forms.DateTimeInput(
                attrs={"class": "input input-sm input-bordered w-full", "type": "datetime-local"}
            ),
        }
