from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.urls import reverse

from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.mailer import Mailer
from konova.utils.message_templates import FORM_INVALID
from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm
from user.forms.modals.user import UserContactForm
from user.forms.team import TeamDataForm
from user.forms.user import UserNotificationForm, UserAPITokenForm
from user.models import User, Team
from django.http import HttpRequest, Http404
from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import gettext_lazy as _

from konova.contexts import BaseContext
from konova.decorators import any_group_check, default_group_required, login_required_modal


@login_required
@any_group_check
def index_view(request: HttpRequest):
    """ Renders the user's data index view

    Args:
        request ():

    Returns:

    """
    template = "user/index.html"
    context = {
        "user": request.user,
        TAB_TITLE_IDENTIFIER: _("User settings"),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required
@any_group_check
def notifications_view(request: HttpRequest):
    """ Renders the notifications settings view

    Args:
        request ():

    Returns:

    """
    template = "user/notifications.html"
    user = request.user

    form = UserNotificationForm(user=user, data=request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            form.save()
            messages.success(
                request,
                _("Notifications edited")
            )
            return redirect("user:index")
    elif request.method == "GET":
        # Implicit
        pass
    else:
        raise NotImplementedError

    context = {
        "user": user,
        "form": form,
        TAB_TITLE_IDENTIFIER: _("User notifications"),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required
@default_group_required
def api_token_view(request: HttpRequest):
    """ Handles the request for user api frontend settings

    Args:
        request (HttpRequest): The incoming request

    Returns:

    """
    template = "user/token.html"
    user = request.user
    form = UserAPITokenForm(request.POST or None, instance=user)
    if request.method == "POST":
        if form.is_valid():
            token = form.save()
            messages.info(request, _("New token generated. Administrators need to validate."))
            mailer = Mailer()
            mailer.send_mail_verify_api_token(user)
            return redirect("user:api-token")
        else:
            messages.error(request, FORM_INVALID, extra_tags="danger")
    elif request.method != "GET":
        raise NotImplementedError
    context = {
        "user": user,
        "form": form,
        TAB_TITLE_IDENTIFIER: _("User API token"),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required_modal
@login_required
def contact_view(request: HttpRequest, id: str):
    """ Renders contact modal view of a users contact data

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

    Returns:

    """
    user = get_object_or_404(User, id=id)
    form = UserContactForm(request.POST or None, instance=user, request=request)
    template = "modal/modal_form.html"
    context = {
        "form": form,
    }
    context = BaseContext(request, context).context
    return render(
        request,
        template,
        context
    )


@login_required_modal
@login_required
def data_team_view(request: HttpRequest, id: str):
    """ Renders team data

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

    Returns:

    """
    team = get_object_or_404(Team, id=id)
    form = TeamDataForm(request.POST or None, instance=team, request=request)
    template = "modal/modal_form.html"
    context = {
        "form": form,
    }
    context = BaseContext(request, context).context
    return render(
        request,
        template,
        context
    )


@login_required
def index_team_view(request: HttpRequest):
    template = "user/team/index.html"
    user = request.user
    context = {
        "teams": user.shared_teams,
        "tab_title": _("Teams"),
    }
    context = BaseContext(request, context).context
    return render(request, template, context)


@login_required_modal
@login_required
def new_team_view(request: HttpRequest):
    form = NewTeamModalForm(request.POST or None, request=request)
    return form.process_request(
        request,
        _("New team added"),
        redirect_url=reverse("user:team-index")
    )


@login_required_modal
@login_required
def edit_team_view(request: HttpRequest, id: str):
    team = get_object_or_404(Team, id=id)
    user_is_admin = team.is_user_admin(request.user)
    if not user_is_admin:
        raise Http404()
    form = EditTeamModalForm(request.POST or None, instance=team, request=request)
    return form.process_request(
        request,
        _("Team edited"),
        redirect_url=reverse("user:team-index")
    )


@login_required_modal
@login_required
def remove_team_view(request: HttpRequest, id: str):
    team = get_object_or_404(Team, id=id)
    user_is_admin = team.is_user_admin(request.user)
    if not user_is_admin:
        raise Http404()
    form = RemoveTeamModalForm(request.POST or None, instance=team, request=request)
    return form.process_request(
        request,
        _("Team removed"),
        redirect_url=reverse("user:team-index")
    )


@login_required_modal
@login_required
def leave_team_view(request: HttpRequest, id: str):
    team = get_object_or_404(Team, id=id)
    user = request.user

    is_user_team_member = team.users.filter(id=user.id).exists()
    if not is_user_team_member:
        messages.info(
            request,
            _("You are not a member of this team")
        )
        return redirect("user:team-index")

    form = LeaveTeamModalForm(request.POST or None, instance=team, request=request)
    return form.process_request(
        request,
        _("Left Team"),
        redirect_url=reverse("user:team-index")
    )