from django.http import Http404
from django.shortcuts import render, redirect
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.contrib import messages
from .forms import UserRegisterForm, StaffRegistrationForm, StaffSheetDateForm
from .models import UserAccount
from gauth.models import Location
from review.models import Review
from facebook_app.models import FacebookReview
from yelp.models import YelpReview
from name_extractor.models import Staff
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from name_extractor.utils import extract_names_from_reviews, make_all_staffs_point_zero

from django.contrib.auth.mixins import LoginRequiredMixin
from .utils import (
    get_google_review_report,
    get_facebook_report,
    get_yelp_review_report,
    get_this_month_analytics,
    get_review_count_by_month,
    date_str2datetime
)
from rest_framework.views import APIView
from rest_framework.response import Response


class RegistrationView(View):

    def get(self, request, *args, **kwargs):
        form = UserRegisterForm()
        return render(request, 'signup.html', {'form': form})

    def post(self, request, *args, **kwargs):
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            location = Location.objects.filter(recipient_email=email).first()
            if location:
                user = form.save()
                UserAccount.objects.create(user=user, location=location)
                messages.success(request, f'Your account has been created! You are now able to log in')
                return redirect('login')
            else:
                messages.warning(request, f'Sorry, We don\'t have any location with this email!')

        return render(request, 'signup.html', {'form': form})


@method_decorator([login_required], name='dispatch')
class LoginRedirectURL(View):

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('login')
        elif request.user.is_staff:
            return redirect('un-replied-review')
        else:
            return redirect('location-analytics')


class LocationAnalytics(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        # print(dir(request.user))
        user_location_id = request.user.useraccount.location_id

        google_report = get_google_review_report(user_location_id)
        facebook_report = get_facebook_report(user_location_id)
        yelp_report = get_yelp_review_report(user_location_id)

        context = {
            'google_pos': google_report.get('positive'),
            'google_pos_gr': google_report.get('positive_growth'),
            'google_neg': google_report.get('negative'),
            'google_neg_gr': google_report.get('negative_growth'),
            'google_total': google_report.get('total'),
            'google_total_growth': google_report.get('total_growth'),
            'yelp_pos': yelp_report.get('positive'),
            'yelp_pos_gr': yelp_report.get('positive_growth'),
            'yelp_neg': yelp_report.get('negative'),
            'yelp_neg_gr': yelp_report.get('negative_growth'),
            'yelp_total': yelp_report.get('total'),
            'yelp_total_growth': yelp_report.get('total_growth'),
            'facebook_pos': facebook_report.get('positive'),
            'facebook_pos_gr': facebook_report.get('positive_growth'),
            'facebook_neg': facebook_report.get('negative'),
            'facebook_neg_gr': facebook_report.get('negative_growth'),
            'facebook_total': facebook_report.get('total'),
            'facebook_total_growth': facebook_report.get('total_growth'),
        }
        return render(request, 'user-dashboard.html', context=context)


class ChartDataThisMonth(APIView):
    def get(self, request, *args, **kwargs):
        location_id = request.GET['location_id']
        res = get_this_month_analytics(location_id)
        return Response(res)


class ChartDataAllPlatform(APIView):
    def get(self, request, *args, **kwargs):
        location_id = request.GET['location_id']
        g_res = get_review_count_by_month(location_id, 'google')
        f_res = get_review_count_by_month(location_id, 'facebook')
        y_res = get_review_count_by_month(location_id, 'yelp')
        res = {
            'google': g_res,
            'facebook': f_res,
            'yelp': y_res
        }
        return Response(res)


class ReviewListLocationWise(View):
    def get(self, request, platform,  *args, **kwargs):
        location_id = request.user.useraccount.location_id
        if platform == 'google':
            reviews = Review.objects.filter(location_id=location_id).order_by('-update_time')
        elif platform == 'facebook':
            reviews = FacebookReview.objects.filter(page__location_id=location_id).order_by('-create_time')
        elif platform == 'yelp':
            reviews = YelpReview.objects.filter(location__location_id=location_id).order_by('-date_posted')
        else:
            raise Http404()

        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, 'platform': platform}
        return render(request, 'review-list.html', context=context)


class ReviewAnalyticsGraph(View):

    def get(self, requests, *args, **kwargs):
        return render(requests, 'location-wise-reviews.html')


class StaffLeaderBoard(View):

    def get(self, request, *args, **kwargs):
        staffs = Staff.objects.filter(location=request.user.useraccount.location).order_by('-total_units')
        form = StaffRegistrationForm()
        date_form = StaffSheetDateForm()

        context = {
            'staffs': staffs,
            'date_form': date_form,
            'form': form
        }
        return render(request, 'staff_list.html', context)

    def post(self, request, *args, **kwargs):
        form = StaffRegistrationForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data.get('name')
            department = form.cleaned_data.get('department')
            nick_names = form.cleaned_data.get('nick_names')
            location_id = request.user.useraccount.location_id
            staff = Staff.objects.create(
                name=name,
                location_id=location_id,
                department=department,
                nick_names=nick_names
            )
            messages.success(request, f'A new staff {staff} has been created!')
        return redirect('location-analytics')


class SyncStaffLeaderBoard(View):

    def post(self, request, *args, **kwargs):
        start_date = date_str2datetime(request.POST.get('start_date'))
        end_date = date_str2datetime(request.POST.get('end_date'))
        location_id = request.user.useraccount.location_id

        extract_names_from_reviews(
            start_date=start_date,
            end_date=end_date,
            location_id=location_id
        )
        return redirect('staff-leaderboard')