from django.contrib.auth.decorators import login_required
from django.db.models import Sum
from django.http import HttpRequest
from django.shortcuts import render, get_object_or_404
from django.utils.translation import gettext_lazy as _

from compensation.forms import NewStateModalForm, NewDeadlineModalForm, NewActionModalForm
from compensation.models import Compensation, CompensationState, CompensationAction
from compensation.tables import CompensationTable
from konova.contexts import BaseContext
from konova.decorators import *
from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm
from konova.utils.user_checks import in_group


@login_required
@any_group_check
def index_view(request: HttpRequest):
    """
    Renders the index view for compensation

    Args:
        request (HttpRequest): The incoming request

    Returns:
        A rendered view
    """
    template = "generic_index.html"
    compensations = Compensation.objects.filter(
        deleted=None,  # only show those which are not deleted individually
        intervention__deleted=None,  # and don't show the ones whose intervention has been deleted
    )
    table = CompensationTable(
        request=request,
        queryset=compensations
    )
    context = {
        "table": table,
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required
@default_group_required
def new_view(request: HttpRequest):
    # ToDo
    pass


@login_required
@default_group_required
def edit_view(request: HttpRequest, id: str):
    # ToDo
    pass


@login_required
@any_group_check
def open_view(request: HttpRequest, id: str):
    """ Renders a detail view for a compensation

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id

    Returns:

    """
    template = "compensation/detail/compensation/view.html"
    comp = get_object_or_404(Compensation, id=id)
    geom_form = SimpleGeomForm(instance=comp)
    _user = request.user
    is_data_shared = comp.intervention.is_shared_with(_user)

    # Order states according to surface
    before_states = comp.before_states.all().order_by("-surface")
    after_states = comp.after_states.all().order_by("-surface")

    # Precalculate logical errors between before- and after-states
    # Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
    sum_before_states = before_states.aggregate(Sum("surface"))["surface__sum"] or 0
    sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
    diff_states = abs(sum_before_states - sum_after_states)

    context = {
        "obj": comp,
        "geom_form": geom_form,
        "has_access": is_data_shared,
        "before_states": before_states,
        "after_states": after_states,
        "sum_before_states": sum_before_states,
        "sum_after_states": sum_after_states,
        "diff_states": diff_states,
        "is_default_member": in_group(_user, DEFAULT_GROUP),
        "is_zb_member": in_group(_user, ZB_GROUP),
        "is_ets_member": in_group(_user, ETS_GROUP),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required
def log_view(request: HttpRequest, id: str):
    """ Renders a log view using modal

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id

    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    template = "modal/modal_generic.html"
    body_template = "log.html"

    context = {
        "modal_body_template": body_template,
        "log": comp.log.all().order_by("-timestamp"),
        "modal_title": _("Log"),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required
def remove_view(request: HttpRequest, id: str):
    """ Renders a modal view for removing the compensation

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id

    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    form = RemoveModalForm(request.POST or None, instance=comp, user=request.user)
    return form.process_request(
        request=request,
        msg_success=_("Compensation removed"),
        redirect_url="",
    )


@login_required
def new_document_view(request: HttpRequest, id: str):
    """ Renders a form for uploading new documents

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id to which the new document will be related
    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    form = NewDocumentForm(request.POST or None, request.FILES or None, instance=comp, user=request.user)
    return form.process_request(
        request,
        msg_success=_("Document added")
    )


@login_required
def state_new_view(request: HttpRequest, id: str):
    """ Renders a form for adding new states for a compensation

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id to which the new state will be related

    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    form = NewStateModalForm(request.POST or None, instance=comp, user=request.user)
    return form.process_request(
        request,
        msg_success=_("State added")
    )


@login_required
def action_new_view(request: HttpRequest, id: str):
    """ Renders a form for adding new actions for a compensation

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id to which the new state will be related

    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    form = NewActionModalForm(request.POST or None, instance=comp, user=request.user)
    return form.process_request(
        request,
        msg_success=_("Action added")
    )


@login_required
def deadline_new_view(request: HttpRequest, id: str):
    """ Renders a form for adding new states for a compensation

    Args:
        request (HttpRequest): The incoming request
        id (str): The compensation's id to which the new state will be related

    Returns:

    """
    comp = get_object_or_404(Compensation, id=id)
    form = NewDeadlineModalForm(request.POST or None, instance=comp, user=request.user)
    return form.process_request(
        request,
        msg_success=_("Deadline added")
    )


@login_required
def state_remove_view(request: HttpRequest, id: str):
    """ Renders a form for removing a compensation state

    Args:
        request (HttpRequest): The incoming request
        id (str): The state's id

    Returns:

    """
    state = get_object_or_404(CompensationState, id=id)
    form = RemoveModalForm(request.POST or None, instance=state, user=request.user)
    return form.process_request(
        request,
        msg_success=_("State removed")
    )


@login_required
def action_remove_view(request: HttpRequest, id: str):
    """ Renders a form for removing a compensation action

    Args:
        request (HttpRequest): The incoming request
        id (str): The action's id

    Returns:

    """
    action = get_object_or_404(CompensationAction, id=id)
    form = RemoveModalForm(request.POST or None, instance=action, user=request.user)
    return form.process_request(
        request,
        msg_success=_("Action removed")
    )