from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from .models import Limit
from invitation.models import Invitation
from purist.models import AccountType
from limitmonitor.common import active_subscription


@login_required
def userlimit(request):
    username = request.user.get_username()
    limits = Limit.objects.filter(user__username=username).order_by('id')

    # get flags for each limit
    has_limit = {}
    action_function = {}
    none_limit = True
    for limit in limits:
        label = limit.service_label().upper()
        has_limit[label] = limit.is_enabled()
        # Default action for services
        action_function[label] = '.'
        if limit.is_active:
            none_limit = False

    has_limit["NONE"] = none_limit  # true if no limits are active

    action_function["TUNNEL"] = reverse("toggle_tunnel")

    # Prepare context variables for Group service
    invitations = {'list': []}
    inv_all = request.user.invitation_set.all()
    used_inv = 0
    for inv in inv_all:
        if inv.consumed or (not inv.consumed and not inv.expired()):
            used_inv += 1
    invitations['full'] = used_inv >= 4
    invitations['no_members'] = True
    invitations['links_not_used'] = False
    for inv in inv_all:
        inv_dict = {}
        inv_dict['link'] = request.build_absolute_uri(
            reverse('register_invitation', kwargs={'msg_hash': inv.msg_hash})
        )
        inv_dict['consumed'] = inv.consumed
        if inv.guest is not None:
            inv_dict['guest'] = inv.guest.username
            invitations['no_members'] = False
        else:
            inv_dict['guest'] = '---'
        inv_dict['expired'] = inv.expired()
        if not inv.expired() and not inv.consumed:
            invitations['links_not_used'] = True
        invitations['list'].append(inv_dict)

    sub = active_subscription(request.user)
    haspaid = sub is not None

    if request.user.account_type != AccountType.INVITED and sub is not None:
        can_upgrade = len(sub.upgrade_choices(add_downgrade=True)) > 0
    else:
        can_upgrade = False

    if hasattr(request.user, 'chosenreward'):
        reward_url = request.user.chosenreward.url
    else:
        reward_url = ''

    pending_upgrade = request.user.bundlechange_set.filter(is_pending=True)
    render_data = {
        "DEBUG_CHANGE_PASSWORD": settings.DEBUG_CHANGE_PASSWORD,
        "username": username,
        "site_title": settings.SITE_TITLE,
        "site_byline": settings.SITE_BYLINE,
        "site_provider": settings.SITE_PROVIDER,
        "site_provider_link": settings.SITE_PROVIDER_LINK,
        "limits": limits,
        "has_limit": has_limit,
        "link_profile_ordered_dict": settings.LINK_PROFILE_ORDERED_DICT,
        "action_function": action_function,
        "invitations": invitations,
        "haschosenreward": hasattr(request.user, 'chosenreward'),
        "complete_signup_url": reward_url,
        "haspaid": haspaid,
        "can_upgrade": can_upgrade,
        "pending_upgrade": len(pending_upgrade) >= 1
    }

    return render(request, 'limitmonitor/userlimit.html', render_data)


@login_required
def toggle_tunnel(request):
    tunnel_limit = request.user.limit_set.filter(
        service=settings.LM_SERVICES.TUNNEL).first()
    if tunnel_limit.service_activable_by_user():
        if not request.user.has_tunnel_account():
            request.user.generate_tunnel_account()
        tunnel_limit.is_active = not tunnel_limit.is_active
        tunnel_limit.save()
    return HttpResponseRedirect(reverse('profile'))


@login_required
def new_invitation(request):
    if request.user.account_type == AccountType.GROUP:
        all_invs = request.user.invitation_set.all()
        # Counter for invitations consumed and not consumed but
        # not expired
        used = 0
        for inv in all_invs:
            if inv.consumed or (not inv.consumed and not inv.expired()):
                used += 1
        if used < 4:
            new_inv = Invitation.create(request.user)
            new_inv.save()
    return HttpResponseRedirect(reverse('profile'))
