from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import check_password, make_password
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import Group, Permission
from django.contrib.auth.views import PasswordChangeView
from django.db.models import Q
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.contrib import messages
from django.views import View
from django.views.generic import UpdateView, ListView, CreateView, DeleteView

from apps.usuarios.mixin import ValidatePermissionRequiredMixin
from apps.usuarios.models import Usuario
from apps.usuarios.forms import PerfilForm, ChangePwdForm, CreateUserForm, GroupForm


# Create your views here.
class ViewProfile(SuccessMessageMixin,UpdateView):
    model = Usuario
    template_name = 'profile.html'
    form_class = PerfilForm
    success_url = reverse_lazy('perfil')
    success_message = 'Perfil Actualizado'

    def get_object(self, queryset=None):
        return self.request.user

    def get_context_data(self, **kwargs):
        # print("get_context_data UserPerfilView")
        context = super(ViewProfile, self).get_context_data(**kwargs)
        identicador = self.request.user.id
        queryset = Usuario.objects.filter(id=identicador).first()
        context['img_profile'] = queryset.img_profile
        return context

    def post(self, request, *args, **kwargs):
        objt = get_object_or_404(Usuario, pk=self.request.user.id)
        pid = self.request.user.id
        img_profile = objt.img_profile
        obj = Usuario.objects.filter(pk=pid).first()
        form = PerfilForm(request.POST, request.FILES, instance=obj)
        if form.is_valid():
            registro = form.save(commit=False)
            print('form valido : ', registro)
            registro.save()
        else:
            print('Formulario de mierda ==>>', form)
            print(form.errors)
            messages.error(request, form.errors)
        return render(request, self.template_name, context={'form':form, 'img_profile':img_profile})

class EditPaswordProfile(SuccessMessageMixin,UpdateView):
    model = Usuario
    form_class = ChangePwdForm
    template_name = 'updatePass.html'
    success_message = 'Perfil Actualizado'

    def get_context_data(self, **kwargs):
        context = super(EditPaswordProfile, self).get_context_data(**kwargs)
        identicador = self.kwargs['pk']
        context['name'] = identicador
        return context

    def post(self, request, *args, **kwargs):
        objt = get_object_or_404(Usuario, pk=self.kwargs['pk'])
        pid = self.kwargs['pk']
        obj = Usuario.objects.all().filter(pk=pid)
        form = ChangePwdForm(request.POST, instance=objt)
        if form.is_valid():
            contra = form.cleaned_data.get('old_password')
            if check_password(contra, obj[0].password):
                if form.cleaned_data.get('new_password1') == form.cleaned_data.get('new_password2'):
                    new_password = form.cleaned_data.get('new_password2')
                    hashed_password = make_password(new_password)
                    obj.update(password=hashed_password)
                    return HttpResponseRedirect(reverse_lazy('close'))
                else:
                    messages.error(request, ('Las nuevas contraseñas no coinciden'))
            else:
                messages.error(request, ('Las antigua contraseña no coincide'))
        return render(request, self.template_name, context={'form':form})

class listausuarios(ValidatePermissionRequiredMixin, ListView):
    template_name = 'UserList.html'
    model = Usuario
    permission_required = 'usuarios.view_usuario'

    def get(self, request, *args, **kwargs):
        queryset = Usuario.objects.filter(is_superuser='0')
        return render(request, self.template_name, context={'lista': queryset})

class CreateUser(SuccessMessageMixin,LoginRequiredMixin,ValidatePermissionRequiredMixin, CreateView):
    model = Usuario
    form_class = CreateUserForm
    template_name = 'Create_user.html'
    success_url = reverse_lazy("gestor_usuarios")
    permission_required = 'usuarios.add_usuario'

    def get_context_data(self, **kwargs):
        context = super(CreateUser, self).get_context_data(**kwargs)
        context['img_profile'] = 'profile.png'
        return context

    def post(self, request, *args, **kwargs):
        form = CreateUserForm(request.POST or None, request.FILES or None)
        if form.is_valid():
            seleccion = form.cleaned_data['tipo_usuario']
            grupos_seleccionados = Group.objects.filter(name=seleccion)
            form.instance.tipo_usuario = form.cleaned_data.get('tipo_usuario')
            form.instance.set_password(form.cleaned_data.get('password'))
            form.save()
            form.instance.groups.set(grupos_seleccionados)
            return HttpResponseRedirect(reverse_lazy('gestor_usuarios'))  # listado_clientes
        else:
            messages.error(request, form.errors)
            print(form.errors)
            return HttpResponseRedirect(reverse_lazy('list_group'))  # listado_clientes



class DeleteUser(ValidatePermissionRequiredMixin, DeleteView):
    template_name = 'delete_user.html'
    model = Usuario
    permission_required = 'usuarios.delete_usuario'
    success_url = reverse_lazy('gestor_usuarios')




class UpdateUser(SuccessMessageMixin, ValidatePermissionRequiredMixin, UpdateView):
    model = Usuario
    form_class = CreateUserForm
    template_name = 'update_user.html'
    success_url = reverse_lazy('gestor_usuarios')
    permission_required = 'usuarios.change_usuario'


    def form_valid(self, form):
        messages.success(self.request, 'Usuario modificado correctamente.')
        return super().form_valid(form)

    def form_invalid(self, form):
        messages.error(self.request, 'Hubo un error al modificar el usuario. Por favor, verifica los datos.')
        return super().form_invalid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user_id = self.kwargs.get('pk')
        User_Select = Usuario.objects.get(id=user_id)
        context['img_profile'] = User_Select.img_profile
        print("TP USE", User_Select.tipo_usuario )
        context['tipo_usuario_1'] = User_Select.tipo_usuario
        return context

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        # Establecer el valor por defecto para el campo tipo_usuario
        form.fields['tipo_usuario'].initial = self.object.tipo_usuario
        return form

class CreateGroup(ValidatePermissionRequiredMixin, CreateView):
    model = Group
    form_class = GroupForm
    permission_required = 'auth.add_group'
    template_name = "grupo_permiso.html"

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        context = {'form': GroupForm()}
        return render(request, 'grupo_permiso.html', context= context)

    def post(self, request, *args, **kwargs):
        form = GroupForm(request.POST)
        registro = form.save(commit=False)
        if form.is_valid():
            print("form.is_valid()")
            box = form.cleaned_data
            data = []

            for i in box:
                campo = box.get(i)
                if campo != "" and campo != form.cleaned_data.get('name'):
                    for j in campo:
                        data.append(Permission.objects.get(codename=j))

            print("El dato: ", data)
            name = form.cleaned_data.get('name')
            print("---", name)

            if Group.objects.filter(name=name).exists():
                print("existe")
                messages.error(request,"El grupo ya existe")
            else:
                print("..............")
                Group.objects.create(name=name)

                grupo = Group.objects.get(name=name)
                print("Grupazo: ", grupo, " --- ", name)
                if grupo.name == name:
                    print("-->")
                grupo.permissions.set(data)
            return HttpResponseRedirect(reverse_lazy('list_group'))
        else:
            print("ERROR", form.errors)
            # form = ConfigForm()
            return render(self.request, self.template_name, context={'form': form, 'err': form.errors})


class ListaGrupos(ValidatePermissionRequiredMixin, ListView):
    model = Group
    form_class = GroupForm
    permission_required = 'auth.view_group'
    template_name = "listar_grupos.html"

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        qs = Group.objects.all().order_by().all()
        context = {'form': GroupForm(), 'object_list': qs}
        return render(request, self.template_name, context)

class UpdateGroup(ValidatePermissionRequiredMixin,UpdateView):
    model = Group
    form_class = GroupForm
    print("-->", model)
    permission_required = 'auth.change_group'
    template_name = "grupo_permiso.html"
    success_message = 'Grupo actualizado satisfactoriamente'
    success_url = reverse_lazy('list_group')


    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        contexto = super(UpdateGroup, self).get_context_data(**kwargs)
        qs = Group.objects.all().filter(pk=self.kwargs['pk'])
        #print('qs', qs.first(), 'qs---' )
        formulario = []
        formut = ""
        for i in qs:
            permisos = i.permissions.all()
            #print("name", permisos, " )))" , i.name)
            formulario.append(i.name)
            formut = i.name
            for j in permisos:
                #print("permisos_appp", j.codename)
                formulario.append(j.codename)
        #print('Code names: ', formulario)
        context = {'form': self.form_class, 'formulario': formulario, 'nombre': formut}
        return context

    def get_object(self, queryset=None):
        # Recupera el objeto Group que se está actualizando
        return get_object_or_404(Group, pk=self.kwargs['pk'])

    def form_valid(self, form):
        # Guarda el objeto Group actualizado con los datos del formulario
        cleaned_data = form.cleaned_data
        form.save()
        return super().form_valid(form)

    def post(self, request, *args, **kwargs):
        form = GroupForm(request.POST, instance=self.get_object())
        print(" form.cleaned_data")
        print("form", form.is_valid(), ' ' , "--->>>>" ,  self.get_object().name)
        if form.is_valid():
            box = form.cleaned_data
            data = []

            for i in box:
                campo = box.get(i)
                print("campo ", campo)
                if campo != "" and campo != form.cleaned_data.get('name'):
                    print(")()()(", form.cleaned_data.get('name'))
                    for j in campo:
                        data.append(Permission.objects.get(codename=j))
            name = form.cleaned_data.get('name')
            #Group.objects.create(name=name)
            print("El dato: ", data , " name " , name)
            if name == self.get_object().name:
                print("No se actulizo el nombre")
                grupo = Group.objects.get(name=form.cleaned_data.get('name'))
                grupo.permissions.set(data)
            else:
                print("Se cambio el nombre ", self.kwargs['pk'] ,  " --- " , form.cleaned_data.get('name'))
                grupof = self.get_object()
                grupof.delete()
                # El nombre del grupo se ha cambiado, crea un nuevo grupo
                nuevo_nombre = form.cleaned_data.get('name')
                nuevo_grupo, creado = Group.objects.get_or_create(name=nuevo_nombre)
                nuevo_grupo.permissions.set(data)

            return HttpResponseRedirect(self.success_url)
        else:
            return render(self.request, self.template_name, context={'form': form, 'err': form.errors})

class DeleteGrupo(ValidatePermissionRequiredMixin, DeleteView):
    template_name = 'delete_group.html'
    model = Group
    form_class = GroupForm
    permission_required = 'auth.delete_group'
    success_url = reverse_lazy('list_group')

    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

class CheckPermisosAjax(View):

    @staticmethod
    def get(request, *args, **kwargs):
        consult = Group.objects.all().filter(Q(id=request.GET.get('id',None))).first()

        formulario = []
        for i in consult:
            permisos = i.permissions.all()
            formulario.append({'name':i.name})
            if permisos != "":
                for j in permisos:
                    formulario.append({j.content_type.app_label : j.codename})
                print('Code names =  ', formulario)
        return JsonResponse({'dictionary': {'datos_json': formulario}})


