"""SP3 linkage forms — directory entries, connections, MoUs, advisory."""
from __future__ import annotations

from django import forms

from apps.core.countries import CountryMultipleChoiceField
from apps.smehub._shared.choices import (
    COUNTRIES,
    SECTORS,
    SERVICE_OFFERINGS,
)
from apps.smehub._shared.validators import (
    DEAL_ROOM_DOCUMENT_VALIDATOR,
    SIGNED_AGREEMENT_VALIDATOR,
)
from apps.smehub.linkage.models import (
    AdvisorySession,
    AdvisorySlot,
    ConnectionRequest,
    MoU,
    MoUComment,
    OrganisationRecommendation,
    PartnerDirectoryEntry,
    RegulatoryGuide,
    ServiceProviderEntry,
)

INPUT_BASE = (
    "block w-full rounded-lg border border-ruforum-border bg-white px-3 py-2 "
    "text-sm text-ruforum-text shadow-sm placeholder-ruforum-text-muted/70 "
    "focus:border-ruforum-primary focus:outline-none focus:ring-1 focus:ring-ruforum-primary"
)
TEXTAREA_BASE = INPUT_BASE + " min-h-[7rem]"
SELECT_BASE = INPUT_BASE


def _s2_single(*, placeholder: str = "") -> dict:
    attrs = {"class": SELECT_BASE, "data-s2": ""}
    if placeholder:
        attrs["data-s2-placeholder"] = placeholder
    return attrs


def _s2_multi(*, placeholder: str) -> dict:
    return {
        "class": SELECT_BASE + " min-h-[2.5rem]",
        "data-s2": "",
        "data-s2-placeholder": placeholder,
    }


# ---------------------------------------------------------------------------
# Directory entries
# ---------------------------------------------------------------------------

class _BaseDirectoryEntryForm(forms.ModelForm):
    sector_focus = forms.MultipleChoiceField(
        required=False,
        choices=SECTORS,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Sectors of focus")),
    )
    geographic_coverage = CountryMultipleChoiceField(
        required=False,
        choices=COUNTRIES,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Countries covered")),
    )

    class Meta:
        fields = [
            "organisation_name",
            "org_type",
            "sector_focus",
            "geographic_coverage",
            "contact_email",
            "contact_phone",
            "website",
            "description",
            "areas_of_interest",
            "logo",
        ]
        widgets = {
            "organisation_name": forms.TextInput(attrs={"class": INPUT_BASE}),
            "org_type": forms.Select(attrs=_s2_single(placeholder="Pick an organisation type")),
            "contact_email": forms.EmailInput(attrs={"class": INPUT_BASE}),
            "contact_phone": forms.TextInput(attrs={"class": INPUT_BASE}),
            "website": forms.URLInput(attrs={"class": INPUT_BASE, "placeholder": "https://"}),
            "description": forms.Textarea(attrs={"class": TEXTAREA_BASE}),
            "areas_of_interest": forms.Textarea(attrs={"class": TEXTAREA_BASE}),
        }


class PartnerDirectoryEntryForm(_BaseDirectoryEntryForm):
    class Meta(_BaseDirectoryEntryForm.Meta):
        model = PartnerDirectoryEntry


class ServiceProviderEntryForm(_BaseDirectoryEntryForm):
    service_offerings = forms.MultipleChoiceField(
        required=False,
        choices=SERVICE_OFFERINGS,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Pick services offered")),
    )

    class Meta(_BaseDirectoryEntryForm.Meta):
        model = ServiceProviderEntry
        fields = _BaseDirectoryEntryForm.Meta.fields + ["service_offerings"]


class DirectoryRejectForm(forms.Form):
    reason = forms.CharField(
        widget=forms.Textarea(attrs={"class": TEXTAREA_BASE, "placeholder": "Why is this entry being rejected?"}),
    )


# ---------------------------------------------------------------------------
# Connections
# ---------------------------------------------------------------------------

class ConnectionRequestForm(forms.ModelForm):
    business = forms.ModelChoiceField(
        queryset=None,
        widget=forms.Select(attrs=_s2_single(placeholder="Pick the business behind this request")),
        help_text="Recipients see this business profile attached to your message.",
    )

    class Meta:
        model = ConnectionRequest
        fields = ["business", "message"]
        widgets = {
            "message": forms.Textarea(
                attrs={
                    "class": TEXTAREA_BASE,
                    "placeholder": "Tell them about your business and why you want to connect.",
                },
            ),
        }

    def __init__(self, *args, entrepreneur=None, **kwargs):
        super().__init__(*args, **kwargs)
        from apps.smehub.onboarding.models import Business
        if entrepreneur is not None:
            self.fields["business"].queryset = Business.objects.filter(
                entrepreneur=entrepreneur,
                verification_status=Business.Status.VERIFIED,
            )
        else:
            self.fields["business"].queryset = Business.objects.none()


class ConnectionDeclineForm(forms.Form):
    reason = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={
                "class": TEXTAREA_BASE,
                "placeholder": "Optional context for the entrepreneur.",
            },
        ),
    )


# ---------------------------------------------------------------------------
# MoU
# ---------------------------------------------------------------------------

class MoUDraftForm(forms.ModelForm):
    class Meta:
        model = MoU
        fields = ["title", "summary", "draft_file"]
        widgets = {
            "title": forms.TextInput(attrs={"class": INPUT_BASE}),
            "summary": forms.Textarea(attrs={"class": TEXTAREA_BASE}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if "draft_file" in self.fields:
            self.fields["draft_file"].validators = [
                *self.fields["draft_file"].validators,
                DEAL_ROOM_DOCUMENT_VALIDATOR,
            ]


class MoUFormaliseForm(forms.Form):
    signed_file = forms.FileField(validators=[SIGNED_AGREEMENT_VALIDATOR])


class MoUAmendForm(forms.ModelForm):
    class Meta:
        model = MoU
        fields = ["title", "summary", "draft_file"]
        widgets = {
            "title": forms.TextInput(attrs={"class": INPUT_BASE}),
            "summary": forms.Textarea(attrs={"class": TEXTAREA_BASE}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if "draft_file" in self.fields:
            self.fields["draft_file"].validators = [
                *self.fields["draft_file"].validators,
                DEAL_ROOM_DOCUMENT_VALIDATOR,
            ]


class MoUCommentForm(forms.ModelForm):
    parent_id = forms.IntegerField(required=False, widget=forms.HiddenInput())

    class Meta:
        model = MoUComment
        fields = ["body"]
        widgets = {
            "body": forms.Textarea(
                attrs={
                    "class": TEXTAREA_BASE,
                    "placeholder": "Add a comment to the draft thread.",
                    "rows": 3,
                },
            ),
        }


# ---------------------------------------------------------------------------
# Advisory bookings
# ---------------------------------------------------------------------------

class _SlotChoiceField(forms.ModelChoiceField):
    """Render each open slot as a human date/time + duration."""

    def label_from_instance(self, obj):
        from django.utils import timezone as _tz

        local = _tz.localtime(obj.starts_at)
        return f"{local:%a %d %b %Y · %H:%M} ({obj.duration_minutes} min)"


class AdvisorySessionForm(forms.Form):
    """FRSME-MPL017 — book an advisory session by choosing one of the service
    provider's published, still-open time slots (no free-text datetime)."""

    slot = _SlotChoiceField(
        queryset=AdvisorySlot.objects.none(),
        widget=forms.Select(attrs=_s2_single(placeholder="Pick an available slot")),
        label="Available time slots",
        empty_label="Select a slot…",
    )
    type = forms.ChoiceField(
        choices=AdvisorySession.Type.choices,
        widget=forms.Select(attrs=_s2_single(placeholder="Pick session type")),
        initial=AdvisorySession.Type.VIRTUAL,
        label="Session type",
    )
    location = forms.CharField(
        required=False,
        widget=forms.TextInput(
            attrs={"class": INPUT_BASE, "placeholder": "Zoom link or physical address"},
        ),
    )
    agenda = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={"class": TEXTAREA_BASE}),
    )

    def __init__(self, *args, service_provider=None, **kwargs):
        super().__init__(*args, **kwargs)
        from django.utils import timezone as _tz

        if service_provider is not None:
            self.fields["slot"].queryset = AdvisorySlot.objects.filter(
                service_provider=service_provider,
                session__isnull=True,
                starts_at__gte=_tz.now(),
            ).order_by("starts_at")


class AdvisorySlotForm(forms.ModelForm):
    """FRSME-MPL017 — a service provider publishes a bookable advisory slot."""

    class Meta:
        model = AdvisorySlot
        fields = ["starts_at", "duration_minutes"]
        widgets = {
            "starts_at": forms.DateTimeInput(
                attrs={"class": INPUT_BASE, "type": "datetime-local"},
                format="%Y-%m-%dT%H:%M",
            ),
            "duration_minutes": forms.NumberInput(attrs={"class": INPUT_BASE, "min": 15, "step": 15}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["starts_at"].input_formats = [
            "%Y-%m-%dT%H:%M",
            "%Y-%m-%d %H:%M:%S",
            "%Y-%m-%d %H:%M",
        ]

    def clean_starts_at(self):
        from django.utils import timezone as _tz

        value = self.cleaned_data["starts_at"]
        if value and value < _tz.now():
            raise forms.ValidationError("Publish slots in the future.")
        return value


class AdvisorySessionCancelForm(forms.Form):
    reason = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={"class": TEXTAREA_BASE, "rows": 3, "placeholder": "Why are you cancelling?"},
        ),
    )


class AdvisorySessionCompleteForm(forms.Form):
    notes = forms.CharField(
        required=False,
        widget=forms.Textarea(
            attrs={"class": TEXTAREA_BASE, "rows": 3, "placeholder": "Session notes (visible to both sides)."},
        ),
    )


# ---------------------------------------------------------------------------
# Organisation recommendation
# ---------------------------------------------------------------------------

class OrganisationRecommendationForm(forms.ModelForm):
    sector_focus = forms.MultipleChoiceField(
        required=False,
        choices=SECTORS,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Sectors")),
    )
    geographic_coverage = CountryMultipleChoiceField(
        required=False,
        choices=COUNTRIES,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Countries")),
    )

    class Meta:
        model = OrganisationRecommendation
        fields = [
            "kind",
            "organisation_name",
            "contact_email",
            "contact_phone",
            "sector_focus",
            "geographic_coverage",
            "rationale",
        ]
        widgets = {
            "kind": forms.Select(attrs=_s2_single(placeholder="What kind of organisation?")),
            "organisation_name": forms.TextInput(attrs={"class": INPUT_BASE}),
            "contact_email": forms.EmailInput(attrs={"class": INPUT_BASE}),
            "contact_phone": forms.TextInput(attrs={"class": INPUT_BASE}),
            "rationale": forms.Textarea(attrs={"class": TEXTAREA_BASE}),
        }


# ---------------------------------------------------------------------------
# Regulatory & Policy Navigation
# ---------------------------------------------------------------------------

class RegulatoryGuideForm(forms.ModelForm):
    sectors = forms.MultipleChoiceField(
        required=False,
        choices=SECTORS,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Sectors this guide applies to")),
        help_text="Leave empty if the guide applies regionally to all sectors.",
    )
    countries = CountryMultipleChoiceField(
        required=False,
        choices=COUNTRIES,
        widget=forms.SelectMultiple(attrs=_s2_multi(placeholder="Countries this guide applies to")),
        help_text="Leave empty if the guide applies regionally.",
    )

    class Meta:
        model = RegulatoryGuide
        fields = [
            "title",
            "slug",
            "body_type",
            "sectors",
            "countries",
            "summary",
            "issuing_authority",
            "official_link",
            "is_active",
        ]
        widgets = {
            "title": forms.TextInput(attrs={"class": INPUT_BASE}),
            "slug": forms.TextInput(attrs={"class": INPUT_BASE, "placeholder": "kebab-case-id"}),
            "body_type": forms.Select(attrs=_s2_single(placeholder="What kind of guide?")),
            "summary": forms.Textarea(attrs={"class": TEXTAREA_BASE, "rows": 6}),
            "issuing_authority": forms.TextInput(attrs={"class": INPUT_BASE}),
            "official_link": forms.URLInput(attrs={"class": INPUT_BASE, "placeholder": "https://"}),
            "is_active": forms.CheckboxInput(attrs={"class": "h-4 w-4 rounded border-ruforum-border"}),
        }
