from datetime import date
from django import http
from django.conf import settings
from django.contrib import auth, messages
from django.core.urlresolvers import reverse
from django.http import Http404
from django.utils.translation import ugettext as _
from django.views import generic

from mahjong_ranking.models import KyuDanRanking, SeasonRanking
from utils import mixins
from . import forms, models


class ActivateRegistration(generic.DetailView):
    """
    Activates the Registration of an User and logs him in
    """
    template_name = 'membership/activation_error.html'

    def get(self, request, **kwargs):
        activation_key = self.kwargs.get('activation_key')
        user = self.get_user(activation_key)
        if user:
            return self.login(user)
        else:
            self.object = user
            context = self.get_context_data()
            return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        context = generic.DetailView.get_context_data(self, **kwargs)
        context.update({
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
            'activation_key': self.kwargs.get('activation_key'),

        })
        return context

    def get_user(self, activation_key):
        user = models.ActivationRequest.objects.activate(activation_key)
        if user:
            return user
        elif self.request.user.is_authenticated():
            return self.request.user
        else:
            return None

    def login(self, user):
        backend = auth.get_backends()[0]
        user.backend = "%s.%s" % (
        backend.__module__, backend.__class__.__name__)  # @IgnorePep8
        auth.login(self.request, user)
        messages.success(self.request, _('Activation successful. \
        You can now login anytime with you username and password.'))
        redirect_url = reverse('membership-edit', args=(user.username,))
        return http.HttpResponseRedirect(redirect_url)  # @IgnorePep8


class ActivationSent(generic.TemplateView):
    template_name = 'membership/activation_sent.html'


class EditMembership(mixins.LoginRequiredMixin, generic.UpdateView):
    form_class = forms.MembershipForm

    def get_object(self, queryset=None):
        if self.request.user.has_perm('membership.change_membership'):
            return models.Membership.objects.get(username=self.kwargs['username'])
        else:
            return models.Membership.objects.get(username=self.request.user)

    def form_valid(self, form):
        messages.success(self.request, _('User Profile changed successfully'))
        return generic.UpdateView.form_valid(self, form)


class MembershipDetail(mixins.LoginRequiredMixin, generic.DetailView):
    model = models.Membership

    def get_object(self, queryset=None):
        try:
            if self.kwargs.get('username'):
                return models.Membership.objects.get(username=self.kwargs['username'])
            elif self.request.user.is_authenticated():
                return self.request.user
        except models.Membership.DoesNotExist:
            raise Http404(_("No %(verbose_name)s found matching the query") %
                          {'verbose_name': self.model._meta.verbose_name})

    def get_context_data(self, **kwargs):
        context = generic.DetailView.get_context_data(self, **kwargs)
        try:
            context['kyu_dan_ranking'] = KyuDanRanking.objects.get(
                user=self.object)
        except KyuDanRanking.DoesNotExist:
            context['kyu_dan_ranking'] = None
        try:
            context['ladder_ranking'] = SeasonRanking.objects.get(
                user=self.object,
                season=date.today().year)
        except SeasonRanking.DoesNotExist:
            context['ladder_ranking'] = SeasonRanking(user=self.object)
        return context


class RegisterForm(generic.FormView):
    form_class = forms.RegistrationForm
    success_url = '/membership/activation_sent/'
    template_name = 'membership/register_form.html'

    def form_valid(self, form):
        form.save()
        return generic.FormView.form_valid(self, form)
