from __future__ import annotations

from django import forms

from apps.mel.feedback.models import (
    FeedbackChannel,
    FeedbackSeverity,
    FeedbackSubmission,
)
from apps.mel.tracking.models import CorrectiveAction


class FeedbackSubmissionForm(forms.Form):
    """Public feedback form. Anonymous submitters may leave email blank."""

    submitter_name = forms.CharField(max_length=255, required=False)
    submitter_email = forms.EmailField(required=False)
    rating = forms.TypedChoiceField(
        # Blank default so an untouched select is stored as null, not 1/5
        # (which silently skewed channel satisfaction data — D-D9).
        choices=[("", "— No rating —")] + [(i, str(i)) for i in range(1, 6)],
        coerce=int,
        required=False,
        empty_value=None,
    )
    severity = forms.ChoiceField(
        choices=FeedbackSeverity.choices,
        initial=FeedbackSeverity.LOW,
        required=True,
    )
    narrative = forms.CharField(widget=forms.Textarea(attrs={"rows": 5}), required=True)


class FeedbackTriageForm(forms.ModelForm):
    """Officer-side form to record triage status."""

    class Meta:
        model = FeedbackSubmission
        fields = ["status", "severity"]


class CorrectiveActionTransitionForm(forms.ModelForm):
    """Officer-side form to advance a corrective action without leaving feedback detail."""

    class Meta:
        model = CorrectiveAction
        fields = ["status", "action_plan", "due_date", "outcome_note"]
        widgets = {
            "action_plan": forms.Textarea(attrs={"rows": 3}),
            "outcome_note": forms.Textarea(
                attrs={"rows": 2, "placeholder": "What was done? Visible to submitter on resolution."},
            ),
            "due_date": forms.DateInput(attrs={"type": "date"}),
        }


class FeedbackChannelForm(forms.ModelForm):
    """Officer-facing channel creation / edit form.

    Limits visible fields to operational ones — token is auto-generated on
    create, and the Generic FK subject is not exposed (use Django admin for
    that edge case since it requires content-type selection).
    """

    class Meta:
        model = FeedbackChannel
        fields = [
            "type", "name", "slug", "description",
            "is_public", "is_active", "opens_at", "closes_at",
        ]
        widgets = {
            "description": forms.Textarea(attrs={"rows": 3}),
            "opens_at": forms.DateTimeInput(attrs={"type": "datetime-local"}),
            "closes_at": forms.DateTimeInput(attrs={"type": "datetime-local"}),
        }

    def clean(self):
        cleaned = super().clean()
        opens = cleaned.get("opens_at")
        closes = cleaned.get("closes_at")
        if opens and closes and closes <= opens:
            raise forms.ValidationError("'Closes at' must be after 'opens at'.")
        return cleaned

    def save(self, commit: bool = True):
        instance = super().save(commit=False)
        if not instance.token:
            instance.token = FeedbackChannel.generate_token()
        if commit:
            instance.save()
        return instance
