import logging
import json

from django.shortcuts import render, get_object_or_404
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from django.contrib.gis.geoip2 import GeoIP2

# Create your views here.
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated
from rest_framework.decorators import api_view, permission_classes, action

from ipware import get_client_ip

from stats.models import StatsLog
from companies.models import Company
from companies.serializers import CompanySerializer
from utils.tag_filters import CompanyTagFilter
from rest_framework import filters
from back_latienda.permissions import IsCompanyOwner, IsSiteAdmin

from utils import woocommerce


class CompanySearchViewSet(viewsets.ModelViewSet):
    queryset = Company.objects.filter(is_validated=True).order_by('-created')
    serializer_class = CompanySerializer
    permission_classes = [IsAuthenticatedOrReadOnly, IsCompanyOwner]
    filter_backends = (filters.SearchFilter, )
    # search_fields = ['company_name__unaccent__icontains', 'short_name__unaccent__icontains']
    search_fields = ['@company_name', '@short_name']


class CompanyViewSet(viewsets.ModelViewSet):
    queryset = Company.objects.filter(is_validated=True).order_by('-created')
    serializer_class = CompanySerializer
    permission_classes = [IsAuthenticatedOrReadOnly, IsCompanyOwner]
    filterset_class = CompanyTagFilter

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user)

    @action(detail=True, methods=['POST', ])
    def email_manager(self, request, **kwargs):
        """
        Send email to company.creator
        """
        try:
            instance = self.queryset.filter(pk=kwargs['pk']).first()
            if instance:
                # IP stuff
                client_ip, is_routable = get_client_ip(request)
                g = GeoIP2()

                # deserialize payload
                data = json.loads(request.body)
                if request.user.is_authenticated:
                    # send email to manager
                    company_message = render_to_string('company_contact.html', {
                        'company': instance,
                        'email': request.user.email,
                        'full_name': request.user.full_name,
                        'quantity': data['quantity'],
                        'phone_number': data.get('phone_number'),
                        'comments': data['comments'],
                        'product_info': data['product_info'],
                    })
                    user_message = render_to_string('confirm_company_contact.html', {
                        'company': instance,
                        'username': request.user.full_name,
                        'data': data,
                    })
                    # send email to company
                    subject = "Contacto de usuario"
                    email = EmailMessage(subject, company_message, to=[instance.creator.email])
                    email.content_subtype = "html"
                    email.send()
                    logging.info(f"Email sent to {instance.creator.email} as manager of {instance.name}")
                    # send confirmation email to user
                    subject = 'Confirmación de contacto'
                    email = EmailMessage(subject, message, to=[request.user.email])
                    email.content_subtype = "html"
                    email.send()
                    logging.info(f"Contact confirmation email sent to {request.user.email}")
                    stats_data = {
                        'action_object': instance,
                        'user': None,
                        'anonymous': True,
                        'ip_address': client_ip,
                        'geo': g.geos(client_ip),
                        'contact': True,
                        'shop': instance.shop,
                    }
                else:
                    # for unauthenticated users
                    company_message = render_to_string('company_contact.html', {
                        'company': instance,
                        'email': data['email'],
                        'full_name': data['full_name'],
                        'quantity': data['quantity'],
                        'phone_number': data.get('phone_number'),
                        'comments': data['comments'],
                        'product_info': data['product_info'],
                    })
                    user_message = render_to_string('confirm_company_contact.html', {
                        'company': instance,
                        'username': data['full_name'],
                    })
                    # send email to company
                    email = EmailMessage(subject, company_message, to=[instance.creator.email])
                    email.content_subtype = "html"
                    email.send()
                    logging.info(f"Email sent to {instance.creator.email} as manager of {instance.name}")
                    # send confirmation email to user
                    email = EmailMessage(subject, user_message, to=[data['email']])
                    email.content_subtype = "html"
                    email.send()
                    logging.info(f"Contact confirmation email sent to anonymous user {data['email']}")
                    # statslog  data to register interaction
                    stats_data = {
                        'action_object': instance,
                        'user': request.user,
                        'anonymous': False,
                        'ip_address': client_ip,
                        'geo': g.geos(client_ip),
                        'contact': True,
                        'shop': instance.shop,
                    }
                #  create statslog instance to register interaction
                StatsLog.objects.create(**stats_data)

                return Response(data=data)
            else:
                return Response({"errors":{"details": f"No instance of company with id {kwargs['pk']}",}})
        except Exception as e:
                return Response({"errors":{"details": str(e),}}, status=500)

    @action(detail=True, methods=['GET', ])
    def import_products(self, request, **kwargs):
        instance = self.queryset.filter(pk=kwargs['pk']).first()
        # check if it's a shop
        if instance.shop is not True:
                return Response({'error': 'This company is not a shop'})
        # check required credentials
        credentials = instance.credentials
        if credentials is None or credentials == {}:
                return Response({'error': 'This company has no registered credentials'})
        # check what platform
        platform = instance.platform
        if platform is None:
                message = {'error': 'This company is not registered with any platforms'}
        elif platform == 'WOO_COMMERCE':
                # recheck credentials
                if 'key' in credentials.keys() and 'secret' in credentials.keys():
                    # execute import
                    products = woocommerce.migrate_shop_products(
                            instance.web_link,
                            credentials['key'],
                            credentials['secret'],
                            request.user,
                            )
                    message = {'details': f'{len(products)} products added for {instance.company_name}'}
                else:
                    message = {"error": 'Credentials have wrong format'}
        else:
                message = {'error': f'Platform {plaform} not registered'}
        return Response(message)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def my_company(request):
    if request.user.company:
        serializer = CompanySerializer(request.user.company)
        return Response({'company': serializer.data})
    else:
        return Response(status=status.HTTP_406_NOT_ACCEPTABLE)

'''
class MyCompanyViewSet(viewsets.ModelViewSet):
    model = Company
    serializer_class = CompanySerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.model.objects.filter(company=self.request.user.company)

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user)
'''

class AdminCompanyViewSet(viewsets.ModelViewSet):
    """ Allows user with role 'SITE_ADMIN' to access all company instances
    """
    queryset = Company.objects.all()
    serializer_class = CompanySerializer
    permission_classes = [IsSiteAdmin]

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user)


@api_view(['GET',])
@permission_classes([IsAuthenticatedOrReadOnly,])
def random_company_sample(request):
    """Return an slice of a randomized list of companies

    Takes optional parameter size (int)
    """
    try:
        size = request.GET.get('size', 6)
        size = int(size)
    except:
        return Response({"error": "Wrong value for size, must be a  number"}, status=status.HTTP_406_NOT_ACCEPTABLE)

    queryset = Company.objects.filter(is_validated=True).order_by('?')[:size]
    serializer = CompanySerializer(queryset, many=True, context={'request': request})
    return Response(serializer.data)
