import datetime
import json
import logging

import jwt
import pytz
import tldextract
from django.conf import settings
from django.contrib.auth import get_user_model
# from django.db.models import Subquery, OuterRef, Count
from django.db.models import F, CharField, Value
from django.db.models.functions import Lower, Substr, Upper
from django.http import HttpResponseRedirect
from django_rest_passwordreset.models import ResetPasswordToken
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from pyparsing import Combine
from rest_framework import status, views
from rest_framework.decorators import action
from rest_framework.exceptions import ValidationError
from rest_framework.mixins import CreateModelMixin
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from urllib.parse import urlparse
from verify_trusted.companies.api.serializers import CompanySerializer, SocialSerializer
from verify_trusted.companies.models import Company, Review, Social, SourceSocial
from verify_trusted.crawlers.facebook.crawler import FacebookCrawler
from verify_trusted.crawlers.googlemap.crawler import GoogleMapCrawler
from verify_trusted.reviews.models import ReviewSource
from verify_trusted.users.api.params import email_config_param, token_param
from verify_trusted.users.api.serializers import (
    EmailVerificationSerializer,
    ResendEmailSerializer,
)
from verify_trusted.users.api.serializers.registration import UserRegistrationSerializer
from verify_trusted.utils import send_activation_email, send_welcome_email

from .admin import AdminUserViewSet  # noqa
from .me import CurrentUserViewSet  # noqa
from ...tasks import reminder
from verify_trusted.users.tasks import send_email


# from bulk_update.helper import bulk_update

User = get_user_model()
logging.config.dictConfig(settings.LOGGING)
logger = logging.getLogger(__name__)

class UserRegistrationViewSet(CreateModelMixin, GenericViewSet):
    throttle_scope = 'user_registration'
    serializer_class = UserRegistrationSerializer
    queryset = User.objects.all()
    permission_classes = [
        AllowAny,
    ]

    def get_serializer_class(self):
        if self.action == 'change_password':
            return ResendEmailSerializer
        return super().get_serializer_class()

    # def perform_create(self, serializer):
    #     super().perform_create(serializer)
    #     # Sending email after creating user
    #     user = serializer.data
    #     # redirect_url = 'https://%s/login' % settings.ADMIN_CLIENT_NAME
    #     send_welcome_email(user['email'])

    def perform_create(self, serializer):
        super().perform_create(serializer)
        user = serializer.data
        # Sending email after creating user
        send_welcome_email(user['email'])

    def create(self, request, *args, **kwargs):
        white_list = ['82.21.178.108']
        if self.request.data['ip'] in white_list:
            return super().create(request, *args, **kwargs)
        user_check = User.objects.filter(ip=self.request.data['ip']).first()
        company_array = self.request.data['company']
        company_request = company_array[0]
        company_url = company_request['url_display']
        string_value = Value(company_url, output_field=CharField())
        company = Company.objects.filter(url_display__icontains=company_url).first()
        if company is not None and company.is_verified is not True:
            return super().create(request, *args, **kwargs)
        if user_check is None:
            return super().create(request, *args, **kwargs)
        else:
            message = 'Your IP ('+self.request.data['ip']+') created at least 1 company. Please contact info@VerifyTrusted to validate you have  permission to create this company'
            return Response({'error': {
                'message': message,
                'ip': "MSG018"
                }}, status=status.HTTP_400_BAD_REQUEST)

    @swagger_auto_schema(manual_parameters=[email_config_param])
    @action(detail=False, methods=['GET'], url_path='resend-email')
    def resend_mail(self, request):
        email = self.request.query_params.get(email_config_param.name, None)
        if not email:
            raise ValidationError({'email': "MSG005"})
        user = User.objects.filter(email=email).first()
        if not user:
            raise ValidationError({'email': 'No such user, please register first!'})
        if user.is_active:
            return Response({'message': 'User is already verified'})
        send_activation_email(user.email)
        return Response({'message': 'The verification email has been sent'})

    @swagger_auto_schema(
        method='GET',
        manual_parameters=[token_param],
    )
    @action(methods=['GET'], detail=False, url_path='check-register')
    def check_register(self, request):
        query_params = self.request.query_params
        token_filter = query_params.get(token_param.name, None)
        token = ResetPasswordToken.objects.filter(key=token_filter).first()
        if token is not None:
            password = token.user.password
            if len(password) < 1:
                return Response({'is_register': False}, status=status.HTTP_200_OK)
        return Response({'is_register': True}, status=status.HTTP_200_OK)


class VerifyEmail(views.APIView):
    serializer_class = EmailVerificationSerializer
    permission_classes = [
        AllowAny,
    ]

    token_param_config = openapi.Parameter(
        'token',
        in_=openapi.IN_QUERY,
        description='Description',
        type=openapi.TYPE_STRING,
    )

    @swagger_auto_schema(manual_parameters=[token_param_config])
    def get(self, request):
        token = request.GET.get('token')
        try:
            payload = jwt.decode(token, algorithms='HS256', key=settings.SECRET_KEY)
            local_tz = pytz.timezone(settings.TIME_ZONE)
            exp = datetime.datetime.fromtimestamp(int(payload['exp']), local_tz)
            if exp < datetime.datetime.now(tz=local_tz):
                return Response(
                    {'email': 'Token is expired'}, status=status.HTTP_200_OK
                )
            user = User.objects.get(id=payload['user_id'])
            if user.is_active:
                # return Response(
                #     {'email': 'User is activated'}, status=status.HTTP_200_OK
                # )
                return HttpResponseRedirect(
                    redirect_to='https://%s' % settings.ADMIN_CLIENT_NAME
                )

            user.is_active = True
            user.save()
            # send_welcome_email(user.email)
            # return Response(
            #     {'email': 'Successfully activated'}, status=status.HTTP_200_OK
            # )
            return HttpResponseRedirect(
                redirect_to='https://%s' % settings.ADMIN_CLIENTNAME
            )
        except jwt.ExpiredSignatureError as identifier:  # noqa
            # return Response(
            #     {'error': 'Activation Expired'}, status=status.HTTP_400_BAD_REQUEST
            # )
            return HttpResponseRedirect(
                redirect_to='https://%s' % settings.ADMIN_CLIENT_NAME
            )

        except jwt.exceptions.DecodeError as identifier:  # noqa
            # return Response(
            #     {'error': 'Invalid token'}, status=status.HTTP_400_BAD_REQUEST
            # )
            return HttpResponseRedirect(
                redirect_to='https://%s' % settings.ADMIN_CLIENT_NAME
            )


class TestWelcomeEmail(views.APIView):
    serializer_class = EmailVerificationSerializer
    permission_classes = [
        AllowAny,
    ]

    def get(self, request):
        print('send email')
        fields = ['name', 'email', 'name']
        email_1_days = User.objects.filter(email='nhuyentrang.test001@gmail.com').values_list(*fields).distinct()
        send_email(email_1_days, "users/email/day1_tpl.html", "Welcome to VerifyTrusted!", "name")
        send_email(email_1_days, "users/email/day2_tpl.html", "Your VerifyTrusted page is live and ready for you")
        send_email(email_1_days, "users/email/day3_tpl.html", "How to attract customer eyeballs")
        send_email(email_1_days, "users/email/day4_tpl.html", "How to gain customer trust in 27 seconds")
        send_email(email_1_days, "users/email/day5_tpl.html", "How to get more clicks on your reviews")
        send_email(email_1_days, "users/email/day6_tpl.html", "How’s it going?")
        send_email(email_1_days, "users/email/day7_tpl.html", "your 7 day trial has gone fast!", "company_name")
        # FB = FacebookCrawler()
        # FB.get_reviews(access_token='EAAMDxWeqdg0BACDfcbPB1E1Xc9T30a2amvY7FPn5PrZA3If5pg7FiMPN3FBngMXrBSCF6Mt9LwCiXHXXQalDVcoULb1ZCQQQ9NDMzrvxtaq8OHB53sihsmt4kIvRftolR5QhsezcmyVuuZBC6qm9rj0lgZCabB46RTcgGT68rsA2OTZCu14ByYJuRM2AMZA8iZCMXlvgxur2gHYpMhcOr3gzd2hISmJR1RXBomsR2GgFgZDZD',
        #                page_id='104660292431903')
        # c= Company.objects.filter(email__isnull=False)
        # print(len(c))
        # Company.objects.filter(search_vector__isnull=True).update(
        #     search_vector=Company.get_search_vector(),
        #     first_letter=Subquery(
        #         Company.objects.filter(id=OuterRef('id')).annotate(fl_name=Upper(Substr('name', 1, 1))).values(
        #             'fl_name')[:1])
        # )
        # for i in Company.objects.filter(review_sources__platform_id=3, other__isnull=False).order_by('id')[:10]:
        #     print(i.id)
        #
        #
        # companies = Company.objects.filter(review_sources__platform_id=3, other__isnull=False).order_by('id')[10:30000]
        # for company in companies:
        #     other = company.other
        #     if 'social_links' in other.keys():
        #         socials = other['social_links'].split(',')
        #         for s in socials:
        #             if len(s.strip()) != 0:
        #                 source_social = urlparse(s).hostname
        #                 try:
        #                     source = SourceSocial.objects.filter(url__contains=source_social)[0]
        #                 except:
        #                     continue
        #                 data = {}
        #                 data['company'] = company.id
        #                 data['source'] = source.id
        #                 data['url'] = s
        #                 social_serializer = SocialSerializer(data=data)
        #                 if social_serializer.is_valid():
        #                     social_serializer.create(social_serializer.validated_data)
        return Response(status=status.HTTP_200_OK)


class SendReminderEmail(views.APIView):
    permission_classes = [
        AllowAny,
    ]

    def get(self, request):
        reminder()
        return Response(status=status.HTTP_200_OK)


user_verify_email = VerifyEmail.as_view()
test_welcome_email = TestWelcomeEmail.as_view()
send_reminder = SendReminderEmail.as_view()
