"""
budget/forms.py
===============
Forms for Budget Management (Module 1 of EFMS).
"""

from django import forms
from django.utils.translation import gettext_lazy as _

from base.forms import ModelForm
from base.methods import reload_queryset

from .models import (
    PERIOD_ANNUAL,
    PERIOD_MONTHLY,
    PERIOD_QUARTERLY,
    PERIOD_WEEKLY,
    BudgetAllocation,
    BudgetHead,
    BudgetItem,
    BudgetSettings,
    BudgetSubHead,
)


class BudgetSettingsForm(ModelForm):
    class Meta:
        model = BudgetSettings
        fields = ["overrun_limit_percent"]
        widgets = {
            "overrun_limit_percent": forms.NumberInput(
                attrs={"class": "oh-input w-100", "step": "0.01", "min": "0"}
            ),
        }


class BudgetHeadForm(ModelForm):
    class Meta:
        model = BudgetHead
        fields = ["name", "description", "is_active"]
        widgets = {
            "name": forms.TextInput(attrs={"class": "oh-input w-100"}),
            "description": forms.Textarea(attrs={"class": "oh-input w-100", "rows": 3}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        reload_queryset(self.fields)


class BudgetSubHeadForm(ModelForm):
    class Meta:
        model = BudgetSubHead
        fields = ["head", "name", "description", "is_active"]
        widgets = {
            "head": forms.Select(attrs={"class": "oh-select oh-select-2"}),
            "name": forms.TextInput(attrs={"class": "oh-input w-100"}),
            "description": forms.Textarea(attrs={"class": "oh-input w-100", "rows": 3}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        reload_queryset(self.fields)
        self.fields["head"].queryset = BudgetHead.objects.filter(is_active=True)


class BudgetItemForm(ModelForm):
    class Meta:
        model = BudgetItem
        fields = ["sub_head", "name", "description", "is_active"]
        widgets = {
            "sub_head": forms.Select(attrs={"class": "oh-select oh-select-2"}),
            "name": forms.TextInput(attrs={"class": "oh-input w-100"}),
            "description": forms.Textarea(attrs={"class": "oh-input w-100", "rows": 3}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        reload_queryset(self.fields)
        self.fields["sub_head"].queryset = BudgetSubHead.objects.filter(is_active=True)


class BudgetAllocationForm(ModelForm):
    class Meta:
        model = BudgetAllocation
        fields = [
            "item",
            "fiscal_year",
            "period_type",
            "period_value",
            "allocated_amount",
        ]
        widgets = {
            "item": forms.Select(attrs={"class": "oh-select oh-select-2"}),
            "fiscal_year": forms.NumberInput(
                attrs={"class": "oh-input w-100", "min": "2000", "max": "2100"}
            ),
            "period_type": forms.Select(
                attrs={"class": "oh-select oh-select-2", "onchange": "togglePeriodValue(this)"}
            ),
            "period_value": forms.NumberInput(
                attrs={"class": "oh-input w-100", "min": "1", "max": "53"}
            ),
            "allocated_amount": forms.NumberInput(
                attrs={"class": "oh-input w-100", "step": "0.01", "min": "0"}
            ),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        reload_queryset(self.fields)
        self.fields["item"].queryset = BudgetItem.objects.filter(is_active=True).select_related(
            "sub_head__head"
        )
        self.fields["period_value"].required = False
        self.fields["period_value"].label = _("Period Value (Q1-4 / Month 1-12 / Week 1-53)")

    def clean(self):
        cleaned_data = super().clean()
        period_type = cleaned_data.get("period_type")
        period_value = cleaned_data.get("period_value")

        if period_type == PERIOD_ANNUAL:
            cleaned_data["period_value"] = None
        elif period_type == PERIOD_QUARTERLY:
            if not period_value or not (1 <= period_value <= 4):
                self.add_error("period_value", _("Quarter must be between 1 and 4."))
        elif period_type == PERIOD_MONTHLY:
            if not period_value or not (1 <= period_value <= 12):
                self.add_error("period_value", _("Month must be between 1 and 12."))
        elif period_type == PERIOD_WEEKLY:
            if not period_value or not (1 <= period_value <= 53):
                self.add_error("period_value", _("Week must be between 1 and 53."))

        return cleaned_data


# ---------------------------------------------------------------------------
# Bulk upload form
# ---------------------------------------------------------------------------

class BudgetBulkUploadForm(forms.Form):
    """
    Upload an Excel/CSV file to bulk create or update budget items.
    Expected columns: Head Name, Sub-Head Name, Item Name, Description
    Optional: Fiscal Year, Period Type, Period Value, Allocated Amount
    """

    file = forms.FileField(
        label=_("Upload File (.xlsx or .csv)"),
        widget=forms.FileInput(attrs={"class": "oh-input w-100", "accept": ".xlsx,.csv"}),
    )

    def clean_file(self):
        f = self.cleaned_data["file"]
        name = f.name.lower()
        if not (name.endswith(".xlsx") or name.endswith(".csv")):
            raise forms.ValidationError(_("Only .xlsx and .csv files are accepted."))
        if f.size > 5 * 1024 * 1024:  # 5 MB guard
            raise forms.ValidationError(_("File must be smaller than 5 MB."))
        return f
