"""
budget/cbv/allocation.py
========================
CBV views for BudgetAllocation CRUD.
"""

from typing import Any

from django.contrib import messages
from django.http import HttpResponse
from django.urls import reverse, reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _

from budget.filters import BudgetAllocationFilter
from budget.forms import BudgetAllocationForm
from budget.models import BudgetAllocation
from horilla_views.cbv_methods import login_required, permission_required
from horilla_views.generic.cbv.views import (
    HorillaFormView,
    HorillaListView,
    HorillaNavView,
    TemplateView,
)


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.view_budgetallocation"), name="dispatch")
class BudgetAllocationViewPage(TemplateView):
    template_name = "cbv/allocation/allocation_home.html"


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.view_budgetallocation"), name="dispatch")
class BudgetAllocationNavView(HorillaNavView):
    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self.search_url = reverse("budget-allocation-list")
        self.search_swap_target = "#listContainer"
        self.create_attrs = (
            f'hx-get="{reverse_lazy("budget-allocation-create")}" '
            'hx-target="#genericModalBody" '
            'data-target="#genericModal" '
            'data-toggle="oh-modal-toggle"'
        )

    nav_title = _("Budget Allocations")
    filter_instance = BudgetAllocationFilter()
    filter_body_template = "cbv/allocation/filter.html"
    filter_form_context_name = "form"


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.view_budgetallocation"), name="dispatch")
class BudgetAllocationListView(HorillaListView):
    model = BudgetAllocation
    filter_class = BudgetAllocationFilter

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self.view_id = "budget-allocation-container"
        self.search_url = reverse("budget-allocation-list")

        self.actions = []
        if self.request.user.has_perm("budget.change_budgetallocation"):
            self.actions.append(
                {
                    "action": _("Edit"),
                    "icon": "create-outline",
                    "attrs": """
                        class="oh-btn oh-btn--light-bkg w-100"
                        hx-get='{get_update_url}?instance_ids={ordered_ids}'
                        hx-target="#genericModalBody"
                        data-toggle="oh-modal-toggle"
                        data-target="#genericModal"
                    """,
                }
            )
        if self.request.user.has_perm("budget.delete_budgetallocation"):
            self.actions.append(
                {
                    "action": _("Delete"),
                    "icon": "trash-outline",
                    "attrs": """
                        class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
                        hx-get="{get_delete_url}?model=budget.BudgetAllocation&pk={pk}"
                        data-toggle="oh-modal-toggle"
                        data-target="#deleteConfirmation"
                        hx-target="#deleteConfirmationBody"
                    """,
                }
            )

    columns = [
        (_("Item"), "item"),
        (_("FY"), "fiscal_year"),
        (_("Period"), "period_label"),
        (_("Allocated (₦)"), "allocated_amount"),
        (_("Committed (₦)"), "committed_amount"),
        (_("Approved (₦)"), "approved_amount"),
        (_("Disbursed (₦)"), "disbursed_amount"),
        (_("Balance"), "balance_display"),
        (_("Status"), "overrun_indicator"),
    ]

    sortby_mapping = [
        ("Fiscal Year", "fiscal_year"),
        ("Allocated", "allocated_amount"),
        ("Disbursed", "disbursed_amount"),
    ]

    header_attrs = {
        "fiscal_year": """ style="width:90px !important" """,
        "allocated_amount": """ style="width:150px !important" """,
        "committed_amount": """ style="width:150px !important" """,
        "approved_amount": """ style="width:150px !important" """,
        "disbursed_amount": """ style="width:150px !important" """,
        "action": """ style="width:160px !important" """,
    }

    row_attrs = """
        id="budgetAllocationTr{get_delete_instance}"
    """

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs).select_related("item__sub_head__head")
        item_pk = self.request.GET.get("item")
        if item_pk:
            qs = qs.filter(item_id=item_pk)
        return qs

    records_per_page = 25


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.add_budgetallocation"), name="dispatch")
class BudgetAllocationFormView(HorillaFormView):
    model = BudgetAllocation
    form_class = BudgetAllocationForm
    new_display_title = _("Add Budget Allocation")
    template_name = "cbv/allocation/allocation_form.html"

    def get_initial(self):
        initial = super().get_initial()
        item_pk = self.request.GET.get("item") or self.request.POST.get("item")
        if item_pk:
            initial["item"] = item_pk
        return initial

    def form_valid(self, form: BudgetAllocationForm) -> HttpResponse:
        if form.is_valid():
            if form.instance.pk:
                messages.success(self.request, _("Allocation updated."))
            else:
                messages.success(self.request, _("Allocation created."))
            form.save()
            return self.HttpResponse()
        return super().form_valid(form)
