from django import forms
from django.db.models import Q
from django.utils.translation import gettext_lazy as _

from servala.core.models import (
    CloudProvider,
    ComputePlanAssignment,
    ControlPlane,
    Service,
    ServiceCategory,
    ServiceInstance,
    ServiceOffering,
)


class ServiceFilterForm(forms.Form):
    category = forms.ModelChoiceField(
        queryset=ServiceCategory.objects.all(), required=False
    )
    cloud_provider = forms.ModelChoiceField(
        queryset=CloudProvider.objects.all(), required=False
    )
    q = forms.CharField(label=_("Search"), required=False)

    def __init__(self, *args, organization=None, **kwargs):
        super().__init__(*args, **kwargs)
        if organization and organization.limit_cloudproviders.exists():
            allowed_providers = organization.limit_cloudproviders
            if allowed_providers.count() <= 1:
                self.fields.pop("cloud_provider", None)
            else:
                self.fields["cloud_provider"].queryset = allowed_providers

    def filter_queryset(self, queryset):
        if category := self.cleaned_data.get("category"):
            queryset = queryset.filter(category=category)
        if cloud_provider := self.cleaned_data.get("cloud_provider"):
            queryset = queryset.filter(offerings__provider=cloud_provider)
        if search := self.cleaned_data.get("q"):
            queryset = queryset.filter(
                Q(name__icontains=search) | Q(category__name__icontains=search)
            )
        return queryset


class ControlPlaneSelectForm(forms.Form):
    control_plane = forms.ModelChoiceField(
        queryset=ControlPlane.objects.none(),
        label=_("Service Provider Zone"),
        empty_label=None,
    )

    def __init__(self, *args, planes=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["control_plane"].queryset = planes
        if planes and planes.count() == 1:
            self.fields["control_plane"].initial = planes.first()


class ComputePlanSelectionForm(forms.Form):
    compute_plan_assignment = forms.ModelChoiceField(
        queryset=ComputePlanAssignment.objects.none(),
        widget=forms.RadioSelect,
        required=True,
        label=_("Compute Plan"),
        empty_label=None,
    )

    def __init__(self, *args, control_plane_crd=None, **kwargs):
        super().__init__(*args, **kwargs)
        if control_plane_crd:
            self.fields["compute_plan_assignment"].queryset = (
                ComputePlanAssignment.objects.filter(
                    control_plane_crd=control_plane_crd, is_active=True
                )
                .select_related("compute_plan")
                .order_by("sort_order", "compute_plan__name", "sla")
            )
            if (
                not self.is_bound
                and self.fields["compute_plan_assignment"].queryset.exists()
            ):
                self.fields["compute_plan_assignment"].initial = self.fields[
                    "compute_plan_assignment"
                ].queryset.first()


class ServiceInstanceFilterForm(forms.Form):
    name = forms.CharField(required=False, label=_("Name"))
    service = forms.ModelChoiceField(
        queryset=Service.objects.all(), required=False, label=_("Service")
    )
    provider = forms.ModelChoiceField(
        queryset=CloudProvider.objects.filter(
            id__in=ServiceOffering.objects.values_list("provider", flat=True).distinct()
        ),
        required=False,
        label=_("Provider"),
    )
    control_plane = forms.ModelChoiceField(
        queryset=ControlPlane.objects.all(),
        required=False,
        label=_("Service Provider Zone"),
    )

    def filter_queryset(self, queryset):
        if self.is_valid():
            data = self.cleaned_data
            if data.get("name"):
                queryset = queryset.filter(name__icontains=data["name"])
            if data.get("service"):
                queryset = queryset.filter(
                    context__service_definition__service=data["service"]
                )
            if data.get("provider"):
                queryset = queryset.filter(
                    context__service_offering__provider=data["provider"]
                )
            if data.get("control_plane"):
                queryset = queryset.filter(context__control_plane=data["control_plane"])
        return queryset


class ServiceInstanceDeleteForm(forms.ModelForm):
    name = forms.CharField(
        label=_("Instance ID"),
        max_length=63,
        widget=forms.TextInput(attrs={"class": "form-control"}),
    )

    def __init__(self, *args, **kwargs):
        kwargs["initial"] = {"name": ""}
        super().__init__(*args, **kwargs)
        self.fields["name"].help_text = _(
            "To confirm deletion, please type the instance ID: <strong>{instance_name}</strong>"
        ).format(instance_name=self.instance.name)

    def clean_name(self):
        entered_name = self.cleaned_data.get("name")
        if entered_name != self.instance.name:
            raise forms.ValidationError(
                _(
                    "The entered name does not match the instance ID. Deletion not confirmed."
                )
            )
        return entered_name

    class Meta:
        model = ServiceInstance
        fields = ("name",)
