from datetime import timedelta

from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.db.models import F
from django.db.transaction import atomic
from django.shortcuts import redirect
from django.utils import timezone
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect

from misago.core.decorators import require_POST
from misago.core.uiviews import uiview
from misago.users.decorators import deny_guests

from misago.threads.models import Thread
from misago.threads.permissions import exclude_invisible_threads
from misago.threads.views.generic.threads import Threads, ThreadsView


class UnreadThreads(Threads):
    def get_queryset(self):
        cutoff_days = settings.MISAGO_FRESH_CONTENT_PERIOD
        cutoff_date = timezone.now() - timedelta(days=cutoff_days)
        if cutoff_date < self.user.reads_cutoff:
            cutoff_date = self.user.reads_cutoff
        if cutoff_date < self.user.unread_threads_cutoff:
            cutoff_date = self.user.unread_threads_cutoff

        queryset = Thread.objects.filter(last_post_on__gte=cutoff_date)
        queryset = queryset.select_related('forum')
        queryset = queryset.filter(threadread__user=self.user)
        queryset = queryset.filter(
            threadread__last_read_on__lt=F('last_post_on'))
        queryset = exclude_invisible_threads(queryset, self.user)
        return queryset


class UnreadThreadsView(ThreadsView):
    link_name = 'misago:unread_threads'
    template = 'misago/threads/unread.html'

    Threads = UnreadThreads

    def process_context(self, request, context):
        context['show_threads_locations'] = True
        context['fresh_period'] = settings.MISAGO_FRESH_CONTENT_PERIOD

        if request.user.unread_threads != context['threads_count']:
            request.user.unread_threads.set(context['threads_count'])
        return context

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_anonymous():
            message = _("You have to sign in to see your list of "
                        "threads with unread replies.")
            raise PermissionDenied(message)

        return super(UnreadThreadsView, self).dispatch(
            request, *args, **kwargs)


@deny_guests
@require_POST
@csrf_protect
@never_cache
@atomic
def clear_unread_threads(request):
    request.user.unread_threads_cutoff = timezone.now()
    request.user.save(update_fields=['unread_threads_cutoff'])

    request.user.unread_threads.set(0)

    messages.success(request, _("Unread threads list has been cleared."))
    return redirect('misago:unread_threads')


@uiview("unread_threads")
@deny_guests
def event_sender(request, resolver_match):
    return int(request.user.unread_threads)