from django.shortcuts import render

# Create your views here.
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.utils import timezone
from accounts.branch_utils import get_active_branch, get_branch_context, resolve_write_branch, scope
from accounts.permissions import company_admin_required
from .models import ExpenseCategory, Expense
from .forms import ExpenseCategoryForm, ExpenseForm


def gc(request):
    return request.user.company


@company_admin_required
def expense_category_list(request):
    return render(
        request,
        "expenses/expense_category_list.html",
        {"categories": ExpenseCategory.objects.filter(company=gc(request))},
    )


@company_admin_required
def expense_category_create(request):
    if request.method == "POST":
        form = ExpenseCategoryForm(request.POST)
        if form.is_valid():
            c = form.save(commit=False)
            c.company = gc(request)
            c.save()
            return redirect("expense_category_list")
    else:
        form = ExpenseCategoryForm()
    return render(
        request,
        "expenses/expense_category_form.html",
        {"form": form, "title": "Create Category"},
    )


@company_admin_required
def expense_category_update(request, pk):
    c = get_object_or_404(ExpenseCategory, pk=pk, company=gc(request))
    if request.method == "POST":
        form = ExpenseCategoryForm(request.POST, instance=c)
        if form.is_valid():
            form.save()
            return redirect("expense_category_list")
    else:
        form = ExpenseCategoryForm(instance=c)
    return render(
        request,
        "expenses/expense_category_form.html",
        {"form": form, "title": "Update Category"},
    )


@company_admin_required
def expense_category_delete(request, pk):
    get_object_or_404(ExpenseCategory, pk=pk, company=gc(request)).delete()
    return redirect("expense_category_list")


@company_admin_required
def expense_list(request):
    branch = get_active_branch(request)
    expenses = scope(
        Expense.objects.filter(company=gc(request)).select_related("category"), branch
    )
    return render(request, "expenses/expense_list.html", {"expenses": expenses})


def _expense_form_kwargs(request, default_branch=None):
    ctx = get_branch_context(request)
    return {"branches": ctx.branches, "default_branch": default_branch or resolve_write_branch(request) or ctx.main}


@company_admin_required
def expense_create(request):
    if request.method == "POST":
        form = ExpenseForm(request.POST, **_expense_form_kwargs(request))
        if form.is_valid():
            e = form.save(commit=False)
            e.company = gc(request)
            e.created_by = request.user
            e.branch_id = form.cleaned_data["branch"]
            e.save()
            messages.success(request, "Expense added.")
            return redirect("expense_list")
    else:
        form = ExpenseForm(
            initial={"date": timezone.now().date()}, **_expense_form_kwargs(request)
        )
    return render(
        request,
        "expenses/expense_form.html",
        {"form": form, "title": "Add Expense"},
    )


@company_admin_required
def expense_update(request, pk):
    e = get_object_or_404(Expense, pk=pk, company=gc(request))
    ctx = get_branch_context(request)
    current = ctx.get(e.branch_id) if e.branch_id else ctx.main
    kwargs = _expense_form_kwargs(request, default_branch=current)
    if request.method == "POST":
        form = ExpenseForm(request.POST, instance=e, **kwargs)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.branch_id = form.cleaned_data["branch"]
            obj.save()
            return redirect("expense_list")
    else:
        form = ExpenseForm(instance=e, **kwargs)
    return render(
        request,
        "expenses/expense_form.html",
        {"form": form, "title": "Update Expense"},
    )


@company_admin_required
def expense_delete(request, pk):
    get_object_or_404(Expense, pk=pk, company=gc(request)).delete()
    return redirect("expense_list")
