from django import forms
from django.forms import ModelChoiceField
from django.urls import reverse_lazy

from apps.parks.models import Park, ParkArea

from ..models.company import Company
from ..models.rides import Ride, RideModel

Manufacturer = Company
Designer = Company


class RideForm(forms.ModelForm):
    park_search = forms.CharField(
        label="Park *",
        required=True,
        widget=forms.TextInput(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-input "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "placeholder": "Search for a park...",
                "hx-get": "/parks/search/",
                "hx-trigger": "click, input delay:200ms",
                "hx-target": "#park-search-results",
                "name": "q",
                "autocomplete": "off",
            }
        ),
    )

    manufacturer_search = forms.CharField(
        label="Manufacturer",
        required=False,
        widget=forms.TextInput(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-input "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "placeholder": "Search for a manufacturer...",
                "hx-get": reverse_lazy("rides:search_companies"),
                "hx-trigger": "click, input delay:200ms",
                "hx-target": "#manufacturer-search-results",
                "name": "q",
                "autocomplete": "off",
            }
        ),
    )

    designer_search = forms.CharField(
        label="Designer",
        required=False,
        widget=forms.TextInput(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-input "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "placeholder": "Search for a designer...",
                "hx-get": reverse_lazy("rides:search_companies"),
                "hx-trigger": "click, input delay:200ms",
                "hx-target": "#designer-search-results",
                "name": "q",
                "autocomplete": "off",
            }
        ),
    )

    ride_model_search = forms.CharField(
        label="Ride Model",
        required=False,
        widget=forms.TextInput(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-input "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "placeholder": "Search for a ride model...",
                "hx-get": reverse_lazy("rides:search_ride_models"),
                "hx-trigger": "click, input delay:200ms",
                "hx-target": "#ride-model-search-results",
                "hx-include": "[name='manufacturer']",
                "name": "q",
                "autocomplete": "off",
            }
        ),
    )

    park = forms.ModelChoiceField(
        queryset=Park.objects.all(),
        required=True,
        label="",
        widget=forms.HiddenInput(),
    )

    manufacturer = forms.ModelChoiceField(
        queryset=Manufacturer.objects.all(),
        required=False,
        label="",
        widget=forms.HiddenInput(),
    )

    designer = forms.ModelChoiceField(
        queryset=Designer.objects.all(),
        required=False,
        label="",
        widget=forms.HiddenInput(),
    )

    ride_model = forms.ModelChoiceField(
        queryset=RideModel.objects.all(),
        required=False,
        label="",
        widget=forms.HiddenInput(),
    )

    park_area = ModelChoiceField(
        queryset=ParkArea.objects.none(),
        required=False,
        widget=forms.Select(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-select "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "placeholder": "Select an area within the park...",
            }
        ),
    )

    class Meta:
        model = Ride
        fields = [
            "name",
            "category",
            "manufacturer",
            "designer",
            "ride_model",
            "status",
            "post_closing_status",
            "opening_date",
            "closing_date",
            "status_since",
            "min_height_in",
            "max_height_in",
            "capacity_per_hour",
            "ride_duration_seconds",
            "description",
        ]
        widgets = {
            "name": forms.TextInput(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Official name of the ride",
                }
            ),
            "category": forms.Select(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-select "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "hx-get": reverse_lazy("rides:coaster_fields"),
                    "hx-target": "#coaster-fields",
                    "hx-trigger": "change",
                    "hx-include": "this",
                    "hx-swap": "innerHTML",
                }
            ),
            "status": forms.Select(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-select "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Current operational status",
                    "x-model": "status",
                    "@change": "handleStatusChange",
                }
            ),
            "post_closing_status": forms.Select(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-select "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Status after closing",
                    "x-show": "status === 'CLOSING'",
                }
            ),
            "opening_date": forms.DateInput(
                attrs={
                    "type": "date",
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Date when ride first opened",
                }
            ),
            "closing_date": forms.DateInput(
                attrs={
                    "type": "date",
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Date when ride will close",
                    "x-show": "['CLOSING', 'SBNO', 'CLOSED_PERM', 'DEMOLISHED', 'RELOCATED'].includes(status)",
                    ":required": "status === 'CLOSING'",
                }
            ),
            "status_since": forms.DateInput(
                attrs={
                    "type": "date",
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "Date when current status took effect",
                }
            ),
            "min_height_in": forms.NumberInput(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "min": "0",
                    "placeholder": "Minimum height requirement in inches",
                }
            ),
            "max_height_in": forms.NumberInput(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "min": "0",
                    "placeholder": "Maximum height limit in inches (if applicable)",
                }
            ),
            "capacity_per_hour": forms.NumberInput(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "min": "0",
                    "placeholder": "Theoretical hourly ride capacity",
                }
            ),
            "ride_duration_seconds": forms.NumberInput(
                attrs={
                    "class": (
                        "w-full border-gray-300 rounded-lg form-input "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "min": "0",
                    "placeholder": "Total duration of one ride cycle in seconds",
                }
            ),
            "description": forms.Textarea(
                attrs={
                    "rows": 4,
                    "class": (
                        "w-full border-gray-300 rounded-lg form-textarea "
                        "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                    ),
                    "placeholder": "General description and notable features of the ride",
                }
            ),
        }

    def __init__(self, *args, **kwargs):
        park = kwargs.pop("park", None)
        super().__init__(*args, **kwargs)

        # Make category required
        self.fields["category"].required = True

        # Clear any default values for date fields
        self.fields["opening_date"].initial = None
        self.fields["closing_date"].initial = None
        self.fields["status_since"].initial = None

        # Move fields to the beginning in desired order
        field_order = [
            "park_search",
            "park",
            "park_area",
            "name",
            "manufacturer_search",
            "manufacturer",
            "designer_search",
            "designer",
            "ride_model_search",
            "ride_model",
            "category",
            "status",
            "post_closing_status",
            "opening_date",
            "closing_date",
            "status_since",
            "min_height_in",
            "max_height_in",
            "capacity_per_hour",
            "ride_duration_seconds",
            "description",
        ]
        self.order_fields(field_order)

        if park:
            # If park is provided, set it as the initial value
            self.fields["park"].initial = park
            # Hide the park search field since we know the park
            del self.fields["park_search"]
            # Create new park_area field with park's areas
            self.fields["park_area"] = forms.ModelChoiceField(
                queryset=park.areas.all(),
                required=False,
                widget=forms.Select(
                    attrs={
                        "class": (
                            "w-full border-gray-300 rounded-lg form-select "
                            "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                        ),
                        "placeholder": "Select an area within the park...",
                    }
                ),
            )
        else:
            # If no park provided, show park search and disable park_area until
            # park is selected
            self.fields["park_area"].widget.attrs["disabled"] = True
            # Initialize park search with current park name if editing
            if self.instance and self.instance.pk and self.instance.park:
                self.fields["park_search"].initial = self.instance.park.name
                self.fields["park"].initial = self.instance.park

        # Initialize manufacturer, designer, and ride model search fields if
        # editing
        if self.instance and self.instance.pk:
            if self.instance.manufacturer:
                self.fields["manufacturer_search"].initial = self.instance.manufacturer.name
                self.fields["manufacturer"].initial = self.instance.manufacturer
            if self.instance.designer:
                self.fields["designer_search"].initial = self.instance.designer.name
                self.fields["designer"].initial = self.instance.designer
            if self.instance.ride_model:
                self.fields["ride_model_search"].initial = self.instance.ride_model.name
                self.fields["ride_model"].initial = self.instance.ride_model


class RideSearchForm(forms.Form):
    """Form for searching rides with HTMX autocomplete."""

    ride = forms.ModelChoiceField(
        queryset=Ride.objects.all(),
        label="Find a ride",
        required=False,
        widget=forms.Select(
            attrs={
                "class": (
                    "w-full border-gray-300 rounded-lg form-input "
                    "dark:border-gray-600 dark:bg-gray-700 dark:text-white"
                ),
                "hx-get": reverse_lazy("rides:search"),
                "hx-trigger": "change",
                "hx-target": "#ride-search-results",
            }
        ),
    )
