from django.shortcuts import render

from allauth.account.models import EmailConfirmation, EmailAddress

from django.http import JsonResponse
from django.urls import reverse_lazy, reverse
from django.core.mail import send_mail

from Sistemas.models import Sistema, BitacoraErrores
from .models import Sistemas_por_cliente_A24, ClientesA24
from django.views.generic.edit import CreateView
from django.views.generic.list import ListView
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

from .forms import ClienteForm_IMMEX
from .serializers import ClientesA24Serailizer,SerialiazerA24

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from .serializers import SignupSerializer
from Sistemas.permissions import ItsAdminToken, HasAuthorizationHeader

from django.utils import timezone

import urllib.parse
import traceback

class Sistemas_xCliente_IMMEX_ListView(UserPassesTestMixin,LoginRequiredMixin, ListView):
    model = Sistemas_por_cliente_A24
    paginate_by = 100
    template_name = 'IMMEX/xclientes/lista.html'
    def test_func(self):
        res = self.request.user.groups.filter(name= 'admin_soft')
        if not res:
            messages.error(self.request, 'Lo sentimos. La página que buscas no está disponible o no cuentas con los permisos.')
        return res

class Sistemas_xCliente_IMMEX_CreateView(UserPassesTestMixin,LoginRequiredMixin,CreateView):
    model = Sistemas_por_cliente_A24
    fields = ['id_sistema', 'cliente', 'num_licencias']
    template_name = 'IMMEX/xclientes/sistema_create_IMMEX.html'
    success_url = reverse_lazy('sistemasXcli_IMMEX')
    def test_func(self):
        res = self.request.user.groups.filter(name= 'admin_soft')
        if not res:
            messages.error(self.request, 'Lo sentimos. La página que buscas no está disponible o no cuentas con los permisos.')
        return res

class ClientesIMMEX_CreateView(CreateView):
    model = ClientesA24
    form_class = ClienteForm_IMMEX
    success_url = '/IMMEX/'
    template_name = 'IMMEX/xclientes/edit_cliente.html'
    def form_valid(self, form):
        
        response = super().form_valid(form)
        if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            data={
                'id':self.object.id,
                'RFC':self.object.RFC,
                'Nombre':self.object.Nombre,
                'Activo':self.object.Activo,                
            }
            return JsonResponse(data)
        else:
            return response

    def form_invalid(self,form):
        response = super().form_invalid(form)
        if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            errors = form.errors.as_text()
            return JsonResponse({'errors':f'{errors}'},status=200,content_type='application/json')
        else:
            return response

"""---------API VIEWS---------"""
class LoginIMMEX(APIView):
    pass
class RegistroUsuarios(APIView):
    permission_classes = [ItsAdminToken]
    
    def post(self,request, *args, **kwargs):
        try:
            print(request.data)
            

            serializer = SignupSerializer(data=request.data,context={'request':request})
            if serializer.is_valid():
                user = serializer.save()
                # Generar la confirmación de correo electrónico
                email_address = EmailAddress.objects.get(user=user, email=user.email)
                email_confirmation = EmailConfirmation.create(email_address)
                self.send_email_confirmation(request, email_confirmation)
                
                return Response({'message': 'Registro exitoso'})
            else:           
                print(f'SERIALIZER ERROR {serializer.errors}')     
                return Response({'message': 'Error de validación', 'errors': serializer.errors})
        except Exception as E:
            print(f'ERROR {E}')
            return Response({'Error':f'Error al registro con datos del usuario {E}', 'isError':True})
    def send_email_confirmation(self, request, email_confirmation):
        email_address = email_confirmation.email_address
        email = email_address.email

        email_confirmation.sent = timezone.now()
        email_confirmation.save()
        
        email_confirmation_url = request.build_absolute_uri(reverse('account_confirm_email', args=[email_confirmation.key]))
        message = f"Por favor, confirma tu correo electrónico en el siguiente enlace: {email_confirmation_url}"
        
        send_mail(
            subject='Confirmación de correo electrónico',
            message=message,
            from_email='aduanasoftpruebas@gmail.com',
            recipient_list=[email],
        )
class Check_IMMEX_RFC(APIView):
    """Verifica que el cliente pueda Timbrar"""
    permission_classes = [IsAuthenticated,ItsAdminToken]

    def post(self,request,*args, **kwargs):
        rfc= request.data.get('RFC')
        try:
            clienteA24 , created = ClientesA24.objects.get_or_create(RFC=rfc)
            serializer = ClientesA24Serailizer(clienteA24)

            if created:
                clienteA24.Activo =True
                clienteA24.Nombre = rfc
                clienteA24.save()
            if not serializer.is_valid:
                return Response({'Error':f'{serializer.errors}','isError':True},status=200)
            return Response(serializer.data)
        except Exception as E:
            return Response({'Error':f'check_RFC:{E} RFC:{rfc}','isError':True})

class RegisterIMMEX_Device_APIView(APIView):
    """Register IMMEX Devices"""
    permissions_classes=[IsAuthenticated, ItsAdminToken]
    def post(self,request):
        try:
            serializer = SerialiazerA24(data=request.data, context={'request':request})
        except Exception as ex:
            BitacoraErrores.objects.create(level=2, message=str(ex), traceback=traceback.format_exc(), 
            view='Sistemas.RegisterDeviceView')
            return Response({'Error':f'{ex}','isError':True}, status=status.HTTP_200_OK)            
