"""Forms."""

from django import forms

from allianceauth.eveonline.models import EveCorporationInfo
from eveuniverse.models import EveType

from .models import (
    FIXED_PRICE, FIXED_STOCK, PCT_MODES, PRICE_MODE_CHOICES, SECTION_CHOICES,
    STOCK_MODE_CHOICES, Shop,
)
from .sources import owner_characters

SHIP_CATEGORY_ID = 6


def ship_type_queryset():
    return EveType.objects.filter(
        eve_group__eve_category_id=SHIP_CATEGORY_ID, published=True
    ).order_by("name")


def _resolve_corp(corporation_id):
    try:
        return EveCorporationInfo.objects.get(corporation_id=corporation_id)
    except EveCorporationInfo.DoesNotExist:
        return EveCorporationInfo.objects.create_corporation(corporation_id)


class ShopForm(forms.ModelForm):
    enabled_sections = forms.MultipleChoiceField(
        choices=SECTION_CHOICES,
        required=False,
        widget=forms.CheckboxSelectMultiple,
        label="Sections",
    )

    class Meta:
        model = Shop
        fields = ["name", "slug", "shop_type", "is_published", "enabled_sections", "description"]
        widgets = {
            "description": forms.Textarea(attrs={"rows": 6}),
        }
        help_texts = {
            "description": "Markdown supported — bold, italic, headings, lists, links.",
        }

    def __init__(self, *args, user=None, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)
        # shop_type is fixed after creation
        if self.instance and self.instance.pk:
            self.fields["shop_type"].disabled = True

    def clean_shop_type(self):
        shop_type = self.cleaned_data["shop_type"]
        if shop_type == Shop.ShopType.CORPORATION:
            if not (self.user and self.user.has_perm("shop.manage_corporation_shops")):
                raise forms.ValidationError(
                    "You do not have permission to create corporation shops."
                )
            main = getattr(getattr(self.user, "profile", None), "main_character", None)
            if main is None or not main.corporation_id:
                raise forms.ValidationError(
                    "Your main character has no corporation set."
                )
        return shop_type

    def save(self, commit=True):
        creating = self.instance.pk is None
        shop = super().save(commit=False)
        if creating:
            shop.created_by = self.user
            if shop.shop_type == Shop.ShopType.CORPORATION:
                corp_id = self.user.profile.main_character.corporation_id
                shop.corporation = _resolve_corp(corp_id)
        if commit:
            shop.save()
        return shop


class AddStockroomForm(forms.Form):
    character_id = forms.IntegerField()
    location_id = forms.IntegerField()
    container_item_id = forms.IntegerField(required=False)
    price_mode = forms.ChoiceField(choices=PRICE_MODE_CHOICES)
    price_pct = forms.DecimalField(
        min_value=0, max_digits=5, decimal_places=2, required=False
    )

    def __init__(self, *args, owner=None, **kwargs):
        self.owner = owner
        super().__init__(*args, **kwargs)

    def clean_character_id(self):
        cid = self.cleaned_data["character_id"]
        if not owner_characters(self.owner).filter(id=cid).exists():
            raise forms.ValidationError("Not one of your characters.")
        return cid

    def clean(self):
        cleaned = super().clean()
        if cleaned.get("price_mode") in PCT_MODES and not cleaned.get("price_pct"):
            self.add_error("price_pct", "Enter a percentage for %-based pricing.")
        return cleaned


class EditStockroomForm(forms.Form):
    price_mode = forms.ChoiceField(choices=PRICE_MODE_CHOICES)
    price_pct = forms.DecimalField(
        min_value=0, max_digits=5, decimal_places=2, required=False
    )

    def clean(self):
        cleaned = super().clean()
        if cleaned.get("price_mode") in PCT_MODES and not cleaned.get("price_pct"):
            self.add_error("price_pct", "Enter a percentage for %-based pricing.")
        return cleaned


class HullModeFieldsMixin(forms.Form):
    stock_mode = forms.ChoiceField(choices=STOCK_MODE_CHOICES)
    stock = forms.IntegerField(min_value=0, required=False)
    price_mode = forms.ChoiceField(choices=PRICE_MODE_CHOICES)
    price = forms.IntegerField(min_value=0, required=False)  # ISK, fixed mode
    price_pct = forms.DecimalField(
        min_value=0, max_digits=5, decimal_places=2, required=False
    )
    persist = forms.BooleanField(required=False)  # keep listing at 0 stock
    description = forms.CharField(
        required=False, widget=forms.Textarea(attrs={"rows": 4}),
        help_text="Markdown supported.",
    )

    def clean(self):
        cleaned = super().clean()
        if cleaned.get("stock_mode") == FIXED_STOCK and cleaned.get("stock") is None:
            self.add_error("stock", "Enter a stock quantity for fixed stock.")
        if cleaned.get("price_mode") == FIXED_PRICE and cleaned.get("price") is None:
            self.add_error("price", "Enter a price (0 = Ask) for fixed price.")
        if cleaned.get("price_mode") in PCT_MODES and not cleaned.get("price_pct"):
            self.add_error("price_pct", "Enter a percentage for %-based pricing.")
        return cleaned


class EditHullForm(HullModeFieldsMixin):
    pass


class AddHullForm(HullModeFieldsMixin):
    eve_type = forms.ModelChoiceField(queryset=EveType.objects.none(), label="Ship")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["eve_type"].queryset = ship_type_queryset()
        self.fields["eve_type"].widget.attrs["class"] = "form-select"
