"""Shared forms: the Shop model form + the section-neutral stockroom base.

Section-specific forms (hull stock/price modes, etc.) live with their section,
e.g. ``shop/sections/hulls/forms.py``.
"""

from allianceauth.eveonline.models import EveCorporationInfo
from django import forms

from .models import SECTION_CHOICES, Shop
from .sources import owner_characters, owner_corporations


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",
            "discord_webhook",
        ]
        widgets = {
            "description": forms.Textarea(attrs={"rows": 6}),
        }
        help_texts = {
            "description": "Markdown supported — bold, italic, headings, lists, links.",
            "discord_webhook": (
                "Optional. Paste a Discord channel webhook URL to be pinged "
                "there on new orders."
            ),
        }

    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):
    """Base stockroom form — owner + location. Section-neutral (bpc/modules reuse it).
    `owner_id` is a CharacterAudit pk for personal shops, a CorporationAudit pk for
    corporation shops (dispatched on ``shop.shop_type``)."""

    owner_id = forms.IntegerField()
    location_id = forms.IntegerField()
    container_item_id = forms.IntegerField(required=False)

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

    def clean_owner_id(self):
        oid = self.cleaned_data["owner_id"]
        if self._is_corp():
            if not owner_corporations(self.owner).filter(pk=oid).exists():
                raise forms.ValidationError("Not one of your corporations.")
        else:
            if not owner_characters(self.owner).filter(id=oid).exists():
                raise forms.ValidationError("Not one of your characters.")
        return oid

    def clean(self):
        cleaned = super().clean()
        if self._is_corp() and cleaned.get("owner_id") and cleaned.get("location_id"):
            from corptools.models import EveLocation

            ok = EveLocation.objects.filter(
                location_id=cleaned["location_id"],
                managed=True,
                managed_corp_id=cleaned["owner_id"],
            ).exists()
            if not ok:
                self.add_error("location_id", "Not a division of that corporation.")
        return cleaned

    def _is_corp(self) -> bool:
        return (
            self.shop is not None and self.shop.shop_type == Shop.ShopType.CORPORATION
        )
