from django.db import models
from django.utils import timezone
from django.shortcuts import render, redirect
from django.contrib import messages
from django.views.generic import View, DetailView
from django.shortcuts import get_object_or_404
from review.models import Review, Reply
from review.forms import ReplyForm
from gauth.models import Location
from review.review_utils import reply_review
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin


class ReviewListByLocationView(LoginRequiredMixin, View):

    def get(self, request, location_id, *args, **kwargs):
        reviews = Review.objects.filter(location_id=location_id).order_by('-update_time')
        locations = Location.objects.all()
        page = request.GET.get('page', 1)
        paginator = Paginator(reviews, 50)
        try:
            reviews = paginator.page(page)
        except PageNotAnInteger:
            reviews = paginator.page(1)
        except EmptyPage:
            reviews = paginator.page(paginator.num_pages)
        context = {'reviews': reviews, 'locations': locations}

        return render(request, 'review_list.html', context)


class ReviewListView(LoginRequiredMixin, View):

    def get(self, request, *args, **kwargs):
        reviews = Review.objects.all().order_by('-update_time')
        locations = Location.objects.all()
        page = request.GET.get('page', 1)
        paginator = Paginator(reviews, 50)
        try:
            reviews = paginator.page(page)
        except PageNotAnInteger:
            reviews = paginator.page(1)
        except EmptyPage:
            reviews = paginator.page(paginator.num_pages)
        context = {'reviews': reviews, 'locations': locations}

        return render(request, 'review_list.html', context)


class UnRepliedReviewList(LoginRequiredMixin, PermissionRequiredMixin, View):
    permission_required = 'is_admin'

    def post(self, request, *args, **kwargs):
        form = ReplyForm(self.request.POST)
        if form.is_valid():
            replied_text = form.cleaned_data.get('reply')
        review_id = self.request.POST['review_id']
        review = get_object_or_404(Review, pk=review_id)
        response = reply_review(review=review, replied_text=replied_text)
        if response.status_code == 200:
            review_reply = Reply(replied_text=replied_text, create_time=timezone.now())
            review_reply.save()
            review.reply = review_reply
            review.save()
            messages.success(request, f'Your reply has been posted!')
        elif response.status_code == 404:
            review_reply = Reply(replied_text=replied_text, create_time=timezone.now())
            review_reply.save()
            review.reply = review_reply
            review.save()
            messages.warning(request, f'User might remove this review. Reply has been saved in database!')
        elif response.status_code == 400:
            messages.error(request, f'The request was unacceptable, often due to missing a required parameter.')
        elif response.status_code == 401:
            messages.error(request, f'No valid access token has provided. Please authorize again')
        elif response.status_code == 402:
            messages.info(request, f'The parameters were valid but the request failed.')
        elif response.status_code == 403:
            messages.error(request, f'The access token doesn\'t have permissions to perform the request.failed.')
        elif response.status_code in [500, 502, 503, 504]:
            messages.info(request, f'Something went wrong on Google\'s end. (These are rare.)')
        elif response.status_code == 501:
            messages.info(request, f'This service is off/postpond on Google\'s end. (These are rare.)')
        else:
            messages.info(request, f'Something went wrong on Byte Trek end. (Notify the Devs)')
        return redirect('un-replied-review')

    def get(self, request, *args, **kwargs):
        now = timezone.now()
        form = ReplyForm()
        date = now - timezone.timedelta(days=30)
        reviews = Review.objects.filter(reply=None, update_time__gte=date)\
            .exclude(comment=None, star_rating=5)\
            .order_by('update_time')

        page = request.GET.get('page', 1)
        paginator = Paginator(reviews, 10)
        try:
            reviews = paginator.page(page)
        except PageNotAnInteger:
            reviews = paginator.page(1)
        except EmptyPage:
            reviews = paginator.page(paginator.num_pages)
        context = {'reviews': reviews, 'form': form}
        return render(request, 'dashboard.html', context=context)



class DeleteReview(LoginRequiredMixin, PermissionRequiredMixin, View):
    permission_required = 'is_admin'
    
    def get(self, requset, review_id, *args, **kwargs):
        review = Review.objects.filter(review_id=review_id).first()
        res = review.delete()
        return redirect('un-replied-review')


class ReviewDetails(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
    permission_required = 'is_admin'
    model = Review
    template_name='review_details.html'
    context_object_name='review'