"""Views to display the Mai-Star Ladder an Mai-Star game scores."""

from datetime import date

from django.contrib import auth
from django.urls import reverse
from django.shortcuts import get_object_or_404
from django.views import generic

from events.models import Event
from events.mixins import EventDetailMixin
from django.contrib.auth.mixins import PermissionRequiredMixin
from mahjong_ranking.views import PlayerScore
from . import forms, models


class GameForm(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
    model = models.Game
    permission_required = 'maistar_ranking.add_game'
    form_class = forms.GameForm

    def get_object(self, queryset=None):
        if 'game' in self.kwargs:
            game = get_object_or_404(models.Game, pk=self.kwargs['game'])
        elif 'event' in self.kwargs:
            self.event = get_object_or_404(Event, pk=self.kwargs['event'])
            game = models.Game(event=self.event)
        return game


class DeleteGame(EventDetailMixin, PermissionRequiredMixin, generic.DeleteView):
    """
    Fragt zuerst nach, ob die Hanchan wirklich gelöscht werden soll.
    Wir die Frage mit "Ja" beantwortet, wird die die Hanchan gelöscht.
    """
    model = models.Game
    permission_required = 'maistar_ranking.delete_game'
    pk_url_kwarg = 'hanchan'

    def get_success_url(self):
        return reverse(
            'maistar_ranking-game-list',
            kwargs={'event': self.object.event.pk}
        )


class UpdateGame(EventDetailMixin, PermissionRequiredMixin, generic.UpdateView):
    """
    Ein Formular um eine neues Spiel anzulegen, bzw. eine bestehendes zu
    bearbeiten.
    """
    model = models.Game
    permission_required = 'maistar_ranking.update_game'

    def get_object(self, queryset=None):  # @UnusedVariable
        game = models.Game.objects.get(id=self.kwargs['game'])
        self.event = game.event
        return game

    def get_context_data(self, **kwargs):
        context = generic.UpdateView.get_context_data(self, **kwargs)
        context['event'] = self.event
        return context


class ListGames(EventDetailMixin, generic.ListView):
    """
    Auflistung aller Spiele welche während einer Veranstaltung gespielt wurden.
    """
    model = models.Game

    def get_queryset(self):
        self.event = get_object_or_404(models.Event, pk=self.kwargs['event'])
        return models.Game.objects.filter(event=self.event).select_related()


class ListPlayerGames(PlayerScore):
    template_name = 'maistar_ranking/player_game_list.html'
    paginate_by = 25
    context_object_name = 'game_list'
    user = None
    season = None

    def get_context_data(self, **kwargs):
        context = super(ListPlayerGames, self).get_context_data()
        context['membership'] = self.user
        context['season_list'] = models.Ranking.objects.filter(
            user=self.user).values_list('season', flat=True)
        context['season'] = self.season
        return context

    def get_queryset(self, **kwargs):
        self.user = get_object_or_404(auth.get_user_model(),
                                      username=self.kwargs.get('username'))
        self.season = self.kwargs.get('season', date.today().year)
        return models.Game.objects.player_games(player=self.user,
                                                season=self.season)


class ListRankings(generic.ListView):
    model = models.Ranking
    paginate_by = 50
    season = None
    is_archive = False

    def get_queryset(self):
        self.season = int(self.kwargs.get('season', date.today().year))
        queryset = models.Ranking.objects.filter(
            season=self.season,
            placement__isnull=False
        )
        queryset = queryset.select_related()
        return queryset

    def get_context_data(self, **kwargs):
        context = generic.ListView.get_context_data(self, **kwargs)
        context['is_archive'] = self.is_archive
        context['season'] = self.season
        context['season_list'] = models.Ranking.objects.get_seasons()
        context['latest_games'] = models.Game.objects.filter(confirmed=True)[
            :3]
        context['latest_events'] = Event.objects.upcoming(limit=3)
        return context
