"""
budget/cbv/item.py
==================
CBV views for BudgetItem 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 BudgetItemFilter
from budget.forms import BudgetItemForm
from budget.models import BudgetItem
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_budgetitem"), name="dispatch")
class BudgetItemViewPage(TemplateView):
    template_name = "cbv/item/item_home.html"


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

    nav_title = _("Budget Items")
    filter_instance = BudgetItemFilter()
    filter_body_template = "cbv/item/filter.html"
    filter_form_context_name = "form"


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.view_budgetitem"), name="dispatch")
class BudgetItemListView(HorillaListView):
    model = BudgetItem
    filter_class = BudgetItemFilter

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

        self.actions = []
        if self.request.user.has_perm("budget.change_budgetitem"):
            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_budgetitem"):
            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.BudgetItem&pk={pk}"
                        data-toggle="oh-modal-toggle"
                        data-target="#deleteConfirmation"
                        hx-target="#deleteConfirmationBody"
                    """,
                }
            )

    columns = [
        (_("Code"), "code"),
        (_("Head"), "sub_head__head"),
        (_("Sub-Head"), "sub_head"),
        (_("Name"), "name"),
        (_("Allocations"), "allocation_count"),
        (_("Active"), "is_active"),
    ]

    sortby_mapping = [
        ("Code", "code"),
        ("Name", "name"),
        ("Sub-Head", "sub_head__name"),
    ]

    header_attrs = {
        "code": """ style="width:160px !important" """,
        "sub_head__head": """ style="width:180px !important" """,
        "sub_head": """ style="width:180px !important" """,
        "allocation_count": """ style="width:120px !important" """,
        "is_active": """ style="width:100px !important" """,
        "action": """ style="width:160px !important" """,
    }

    row_attrs = """
        id="budgetItemTr{get_delete_instance}"
    """

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs).select_related("sub_head__head")
        sub_head_pk = self.request.GET.get("sub_head")
        if sub_head_pk:
            qs = qs.filter(sub_head_id=sub_head_pk)
        return qs

    records_per_page = 25


@method_decorator(login_required, name="dispatch")
@method_decorator(permission_required("budget.add_budgetitem"), name="dispatch")
class BudgetItemFormView(HorillaFormView):
    model = BudgetItem
    form_class = BudgetItemForm
    new_display_title = _("Add Budget Item")
    template_name = "cbv/item/item_form.html"

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

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