import json
from django.shortcuts import render, reverse, HttpResponseRedirect, HttpResponse
from django.views.generic import ListView, DetailView, CreateView
from django.db.models import Q
import json
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.db.models import Max, Min
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from .models import News, WpEsiMedia, WpEsiTag
from .forms import NewsForm


@method_decorator(login_required, name='post')
class ListNewsView(ListView):
    template_name = 'list_news.html'

    def get(self, request, *args, **kwargs):
        media = request.GET.get('media')
        from_date = request.GET.get('from_date')
        to_date = request.GET.get('to_date')
        search = request.GET.get('search')
        news = News.objects.filter(is_accepted=False).order_by('-id')#.order_by
        tag = request.GET.get('tag')
        if tag:
            tag = WpEsiTag.objects.get(name=tag)
            news = news.filter(tags_id__contains='{},'.format(tag.id))

        order_by = request.GET.get('order_by')
        if order_by in ('media_id', 'type_id', 'region_id', 'publish_date', 'title'):
            news = news.order_by('-' + order_by)
            if request.GET.get('reverse') == '1':
                news = news.reverse()

        if search:
            news = news.filter(Q(title__icontains=search) | Q(description__icontains=search))
        if from_date:
            news = news.filter(publish_date__gte=from_date)
        if to_date:
            news = news.filter(publish_date__lte=to_date)
        if media:
            news = self._filter_by_media(news, media)
        media = WpEsiMedia.objects.all()
        min_max_date = News.objects.aggregate(Min('publish_date'), Max('publish_date'))
        min_max_date['publish_date__min'] = str(min_max_date['publish_date__min'].date())
        min_max_date['publish_date__max'] = str(min_max_date['publish_date__max'].date())

        return render(request, self.template_name, {'news': news,
                                                    'media': media,
                                                    'date': min_max_date})

    def post(self, request, *args, **kwargs):
        if request.is_ajax():
            data = json.loads(request.body.decode('utf-8'))
            type_request = data['type']
            ids = data['id']
            if type_request in ['delete', 'deleteAll']:
                self._delete(ids)
            if type_request == 'edit':
                return HttpResponse({'ids': ids})

            if type_request == 'exportAll':
                for i in News.objects.filter(pk__in=ids):
                    i.export_news()
            return HttpResponse(200)
        return HttpResponse(200)

    def paginate(self, query, page):
        paginator = Paginator(query, 25)
        try:
            return paginator.page(page)
        except PageNotAnInteger:
            return paginator.page(1)
        except EmptyPage:
            return paginator.page(paginator.num_pages)

    def _delete(self, id):
        if isinstance(id, list):
            News.objects.filter(id__in=id).update(is_accepted=True)
        else:
            News.objects.filter(id=id).update(is_accepted=True)

    def _filter_by_media(self, news, media):
        if media == 'All':
            return news
        else:
            m = WpEsiMedia.objects.get(name=media)
            news = news.filter(media_id=m.pk)
            return news


@method_decorator(login_required, name='dispatch')
class EditNewsView(DetailView):
    template_name = 'edit_news.html'

    def test_func(self):
        return self.request.user.groups.filter(name='admin').exists()

    def get(self, request, *args, **kwargs):
        news = News.objects.get(id=kwargs.get('id'))
        return render(request, self.template_name, {'news': news})

    def post(self, request, *args, **kwargs):
        form = NewsForm(request.POST)
        if form.is_valid():
            form.update()

        return HttpResponseRedirect('/news')


class ViewNewsView(DetailView):
    template_name = 'view_news.html'

    def get(self, request, *args, **kwargs):
        news_id = kwargs.get('id')
        news = News.objects.get(id=news_id)

        return render(request, self.template_name, {'news': news})

    def post(self, request, *args, **kwargs):
        delete_news = request.POST.get('delete')
        export_news = request.POST.get('export')

        if delete_news:
            News.objects.filter(id=delete_news).update(is_accepted=True)
            return HttpResponseRedirect(reverse('view_news', kwargs={'id': delete_news}))

        if export_news:
            news = News.objects.get(id=export_news)
            news.export_news()
            return HttpResponseRedirect(reverse('view_news', kwargs={'id': export_news}))


@method_decorator(login_required, name='dispatch')
class AddNewsView(CreateView):
    template_name = 'add_news.html'

    def get(self, request, *args, **kwargs):
        return render(request, template_name=self.template_name)

    def post(self, request, *args, **kwargs):
        form = NewsForm(request.POST)
        if form.is_valid():
            form.create()

        return HttpResponseRedirect(reverse('list_news'))