"""
Labware forms module for lara_django_material.

:PROJECT: LARAsuite

:details: Django forms for Labware, LabwareClass, LabwareShape, and WellShape models
         optimized for Python 3.13+ with ClassVar pattern.

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

.. note:: Forms for labware management
.. todo:: -
"""

from typing import ClassVar

from django import forms

from ..models import Labware, LabwareClass, LabwareShape, WellShape
from .base import CustomFormRenderer, SearchableSelectMultiple

## -------------- LabwareClass -------------- ##


class LabwareClassCreateForm(forms.ModelForm):
    """Form for creating new LabwareClass entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareClassCreateForm."""

        model = LabwareClass
        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 LabwareClassUpdateForm(forms.ModelForm):
    """Form for updating existing LabwareClass entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareClassUpdateForm."""

        model = LabwareClass
        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},
        }


## -------------- WellShape -------------- ##


class WellShapeCreateForm(forms.ModelForm):
    """Form for creating new WellShape entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for WellShapeCreateForm."""

        model = WellShape
        fields = (
            "name",
            "iri",
            "depth_well",
            "shape_well",
            "shape_bottom",
            "top_radius_xy",
            "bottom_radius_xy",
            "bottom_radius_z",
            "cone_angle",
            "cone_depth",
            "shape_polygon_xy",
            "shape_polygon_z",
            "model_2d",
            "model_3d",
            "model_json",
            "data_extra",
            "description",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = ("shape_well", "shape_bottom")
        textarea_fields: ClassVar = ("model_2d", "model_3d")
        number_fields: ClassVar = (
            "depth_well",
            "top_radius_xy",
            "bottom_radius_xy",
            "bottom_radius_z",
            "cone_angle",
            "cone_depth",
        )
        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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "shape_polygon_xy": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "shape_polygon_z": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "model_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
        }


class WellShapeUpdateForm(forms.ModelForm):
    """Form for updating existing WellShape entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for WellShapeUpdateForm."""

        model = WellShape
        fields = (
            "name",
            "iri",
            "depth_well",
            "shape_well",
            "shape_bottom",
            "top_radius_xy",
            "bottom_radius_xy",
            "bottom_radius_z",
            "cone_angle",
            "cone_depth",
            "shape_polygon_xy",
            "shape_polygon_z",
            "model_2d",
            "model_3d",
            "model_json",
            "data_extra",
            "description",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = ("shape_well", "shape_bottom")
        textarea_fields: ClassVar = ("model_2d", "model_3d", "description")
        number_fields: ClassVar = (
            "depth_well",
            "top_radius_xy",
            "bottom_radius_xy",
            "bottom_radius_z",
            "cone_angle",
            "cone_depth",
        )
        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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "shape_polygon_xy": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "shape_polygon_z": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "model_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "data_extra": SearchableSelectMultiple(),
        }


## -------------- LabwareShape -------------- ##


class LabwareShapeCreateForm(forms.ModelForm):
    """Form for creating new LabwareShape entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareShapeCreateForm."""

        model = LabwareShape
        fields = (
            "name",
            "name_standard",
            "iri",
            "width",
            "length",
            "height_unlidded",
            "hight_lidded",
            "hight_stacked",
            "hight_stacked_lidded",
            "model_2d",
            "model_3d",
            "model_json",
            "well_dist_row",
            "well_dist_col",
            "well_shape",
            "data_extra",
            "description",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = ("name_standard",)
        textarea_fields: ClassVar = ("model_2d", "model_3d", "description")
        number_fields: ClassVar = (
            "width",
            "length",
            "height_unlidded",
            "hight_lidded",
            "hight_stacked",
            "hight_stacked_lidded",
            "well_dist_row",
            "well_dist_col",
        )
        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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "well_shape": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "model_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "data_extra": SearchableSelectMultiple(),
        }


class LabwareShapeUpdateForm(forms.ModelForm):
    """Form for updating existing LabwareShape entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareShapeUpdateForm."""

        model = LabwareShape
        fields = (
            "name",
            "name_standard",
            "iri",
            "width",
            "length",
            "height_unlidded",
            "hight_lidded",
            "hight_stacked",
            "hight_stacked_lidded",
            "model_2d",
            "model_3d",
            "model_json",
            "well_dist_row",
            "well_dist_col",
            "well_shape",
            "data_extra",
            "description",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = ("name_standard",)
        textarea_fields: ClassVar = ("model_2d", "model_3d", "description")
        number_fields: ClassVar = (
            "width",
            "length",
            "height_unlidded",
            "hight_lidded",
            "hight_stacked",
            "hight_stacked_lidded",
            "well_dist_row",
            "well_dist_col",
        )
        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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "well_shape": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "model_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "data_extra": SearchableSelectMultiple(),
        }


## -------------- Labware -------------- ##


class LabwareCreateForm(forms.ModelForm):
    """Form for creating new Labware entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareCreateForm."""

        model = Labware
        fields = (
            "name",
            "name_display",
            "url",
            "pid",
            "pac_id",
            "iri",
            "manufacturer",
            "model_no",
            "product_type",
            "type_barcode",
            "type_barcode_json",
            "product_no",
            "weight",
            "energy_consumption",
            "spec_json",
            "hardware_config",
            "icon",
            "image",
            "resources_external",
            "tags",
            "description",
            "labware_class",
            "num_rows",
            "num_cols",
            "num_wells",
            "shape",
            "liddable",
            "sealable",
            "data_extra",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = (
            "name_display",
            "model_no",
            "product_type",
            "type_barcode",
            "product_no",
        )
        textarea_fields: ClassVar = ("icon", "description")
        number_fields: ClassVar = (
            "weight",
            "energy_consumption",
            "num_rows",
            "num_cols",
            "num_wells",
        )
        url_fields: ClassVar = ("url", "pid", "pac_id", "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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "manufacturer": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "labware_class": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "shape": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "liddable": forms.CheckboxInput(attrs={"class": "checkbox checkbox-sm"}),
            "sealable": forms.CheckboxInput(attrs={"class": "checkbox checkbox-sm"}),
            "spec_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "hardware_config": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "type_barcode_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "resources_external": SearchableSelectMultiple(),
            "tags": SearchableSelectMultiple(),
            "components": SearchableSelectMultiple(),
            "lids": SearchableSelectMultiple(),
            "data_extra": SearchableSelectMultiple(),
            "image": forms.ClearableFileInput(attrs={"class": "file-input file-input-sm file-input-bordered w-full"}),
        }


class LabwareUpdateForm(forms.ModelForm):
    """Form for updating existing Labware entries."""

    default_renderer: ClassVar = CustomFormRenderer()

    class Meta:
        """Meta configuration for LabwareUpdateForm."""

        model = Labware
        fields = (
            "name",
            "name_display",
            "url",
            "pid",
            "pac_id",
            "iri",
            "manufacturer",
            "model_no",
            "product_type",
            "type_barcode",
            "type_barcode_json",
            "product_no",
            "weight",
            "energy_consumption",
            "spec_json",
            "hardware_config",
            "icon",
            "image",
            "resources_external",
            "tags",
            "description",
            "labware_class",
            "num_rows",
            "num_cols",
            "num_wells",
            "shape",
            "liddable",
            "sealable",
            "data_extra",
        )

        text_fields_required: ClassVar = ("name",)
        text_fields: ClassVar = (
            "name_display",
            "model_no",
            "product_type",
            "type_barcode",
            "product_no",
        )
        textarea_fields: ClassVar = ("icon", "description")
        number_fields: ClassVar = (
            "weight",
            "energy_consumption",
            "num_rows",
            "num_cols",
            "num_wells",
        )
        url_fields: ClassVar = ("url", "pid", "pac_id", "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.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.NumberInput(attrs={"class": "input input-sm input-bordered w-full"})
                for field in number_fields
            },
            **{field: forms.URLInput(attrs={"class": "input input-sm input-bordered w-full"}) for field in url_fields},
            "manufacturer": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "labware_class": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "shape": forms.Select(attrs={"class": "select select-sm select-bordered w-full"}),
            "liddable": forms.CheckboxInput(attrs={"class": "checkbox checkbox-sm"}),
            "sealable": forms.CheckboxInput(attrs={"class": "checkbox checkbox-sm"}),
            "spec_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "hardware_config": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 6}
            ),
            "type_barcode_json": forms.Textarea(
                attrs={"class": "textarea textarea-sm textarea-bordered w-full font-mono", "rows": 3}
            ),
            "resources_external": SearchableSelectMultiple(),
            "tags": SearchableSelectMultiple(),
            "data_extra": SearchableSelectMultiple(),
            "image": forms.ClearableFileInput(attrs={"class": "file-input file-input-sm file-input-bordered w-full"}),
        }
