from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken, AccessToken
from django.contrib.auth.hashers import check_password, make_password
from django.utils import timezone
from .models import Usuario
from .serializers import LoginSerializer, UsuarioSerializer, TokenVerifySerializer, UsuarioUpdateSerializer, UsuarioDeleteSerializer
from Models.RolUsuario import RolUsuario
from rest_framework import serializers

class RolUsuarioSerializer(serializers.ModelSerializer):
    class Meta:
        model = RolUsuario
        fields = ['id', 'nombre_rol']

class AuthViewSet(viewsets.GenericViewSet):
    """
    ViewSet de autenticación y usuarios.
    """

    def get_queryset(self):
        # Por defecto devolvemos un queryset vacío
        return Usuario.objects.none()

    def get_serializer_class(self):
        if self.action == 'login':
            return LoginSerializer
        elif self.action == 'create_usuario':
            return UsuarioSerializer
        elif self.action == 'modificar_usuario':
            return UsuarioUpdateSerializer
        elif self.action == 'eliminar_usuario':
            return UsuarioDeleteSerializer 
        elif self.action == 'verify_token':
            return TokenVerifySerializer
        return UsuarioSerializer

    # ------------------ ENDPOINT LOGIN ------------------
    @action(detail=False, methods=['post'], url_path='login', permission_classes=[AllowAny])
    def login(self, request):
        serializer = self.get_serializer_class()(data=request.data)
        if serializer.is_valid():
            email = serializer.validated_data['email']
            password = serializer.validated_data['password']

            try:
                user = Usuario.objects.get(email=email)
            except Usuario.DoesNotExist:
                return Response({"mensaje": "Credenciales inválidas", "estado": 0},
                                status=status.HTTP_401_UNAUTHORIZED)

            if check_password(password, user.password):
                refresh = RefreshToken.for_user(user)
                # Claims personalizados
                refresh['email'] = user.email
                if user.rol_usuario:
                    refresh['rol'] = user.rol_usuario.nombre_rol

                user_data = UsuarioSerializer(user).data

                return Response({
                    "mensaje": "Login exitoso",
                    "estado": 1,
                    "usuario": user_data,
                    "tokens": {
                        "access": str(refresh.access_token),
                        "refresh": str(refresh)
                    }
                })
            else:
                return Response({"mensaje": "Credenciales inválidas", "estado": 0},
                                status=status.HTTP_401_UNAUTHORIZED)

        return Response({"mensaje": "Datos inválidos", "estado": 0, "errores": serializer.errors},
                        status=status.HTTP_400_BAD_REQUEST)

    # ------------------ LISTAR USUARIOS ------------------
    @action(detail=False, methods=['get'], url_path='listar', permission_classes=[IsAuthenticated])
    def listar_usuarios(self, request):
        usuarios = Usuario.objects.filter(deleted_at__isnull=True)
        
        limit = request.query_params.get('limit')
        if limit and limit.isdigit():
            usuarios = usuarios.order_by('-fecha_creacion')[:int(limit)]
            
        serializer = UsuarioSerializer(usuarios, many=True)
        # Agrega el campo nombre_rol con el nombre del rol
        for usuario in serializer.data:
            usuario_obj = Usuario.objects.get(id=usuario['id'])
            usuario['nombre_rol'] = usuario_obj.rol_usuario.nombre_rol if usuario_obj.rol_usuario else None
            usuario['rol_usuario_id'] = usuario_obj.rol_usuario.id if usuario_obj.rol_usuario else None

        return Response(serializer.data)

    # ------------------ CREAR USUARIO ------------------
    # ------------------ CREAR USUARIO ------------------
    @action(detail=False, methods=['post'], url_path='create', permission_classes=[AllowAny])
    def create_usuario(self, request):
        data = request.data.copy()
        
        # Manejo de Rol por nombre
        nombre_rol = data.get('nombre_rol')
        if nombre_rol:
            try:
                rol = RolUsuario.objects.get(nombre_rol=nombre_rol)
                data['rol_usuario_id'] = rol.id
            except RolUsuario.DoesNotExist:
                return Response({"mensaje": f"El rol '{nombre_rol}' no existe"}, status=status.HTTP_400_BAD_REQUEST)

        serializer = self.get_serializer_class()(data=data)
        if serializer.is_valid():
            usuario = serializer.save(password=make_password(serializer.validated_data['password']))
            return Response({"mensaje": "Usuario creado", "id": usuario.id}, status=status.HTTP_201_CREATED)

        return Response({"mensaje": "Datos inválidos", "errores": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

    # ------------------ VERIFY TOKEN ------------------
    @action(detail=False, methods=['post', 'get'], url_path='verify-token', permission_classes=[AllowAny])
    def verify_token(self, request):
        token = request.data.get('token') if request.method == 'POST' else request.GET.get('token')
        if not token:
            return Response({"mensaje": "Token no proporcionado"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            token_obj = AccessToken(token)
            payload = dict(token_obj.payload)
            return Response({"mensaje": "Token válido", "payload": payload})
        except Exception as e:
            return Response({"mensaje": "Token inválido", "error": str(e)}, status=status.HTTP_400_BAD_REQUEST)

    # ------------------ DEBUG AUTH ------------------
    @action(detail=False, methods=['get'], url_path='debug-auth', permission_classes=[IsAuthenticated])
    def debug_auth(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        response_data = {
            "mensaje": "Información de autenticación",
            "esta_autenticado": request.user.is_authenticated,
            "auth_header": auth_header,
            "auth_header_starts_with_bearer": auth_header.startswith('Bearer '),
        }
        if hasattr(request.user, 'id'):
            response_data["usuario_id"] = request.user.id
        if hasattr(request.user, 'email'):
            response_data["email"] = request.user.email
        if hasattr(request.user, 'rol_usuario') and request.user.rol_usuario:
            response_data["rol_id"] = request.user.rol_usuario.id
            response_data["rol_nombre"] = request.user.rol_usuario.nombre_rol
        return Response(response_data)

    # ------------------ MODIFICAR USUARIO ------------------
    @action(detail=False, methods=['patch'], url_path='modificar_usuario', permission_classes=[IsAuthenticated])
    def modificar_usuario(self, request):
        usuario_id = request.data.get('id')
        
        if not usuario_id:
            return Response({"mensaje": "ID de usuario requerido"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            usuario = Usuario.objects.get(id=usuario_id)
        except Usuario.DoesNotExist:
            return Response({"mensaje": "Usuario no encontrado"}, status=status.HTTP_404_NOT_FOUND)
            
        data = request.data.copy()
        
        # Manejo de Rol por nombre
        nombre_rol = data.get('nombre_rol')
        if nombre_rol:
            try:
                rol = RolUsuario.objects.get(nombre_rol=nombre_rol)
                data['rol_usuario_id'] = rol.id
            except RolUsuario.DoesNotExist:
                return Response({"mensaje": f"El rol '{nombre_rol}' no existe"}, status=status.HTTP_400_BAD_REQUEST)

        # Manejo de estado (asegurar que se pase si viene)
        # estado_usuario_id ya debería venir como entero del front, o verificamos si viene
        
        serializer = UsuarioUpdateSerializer(usuario, data=data, partial=True)
        if serializer.is_valid():
            if 'password' in serializer.validated_data:
                serializer.validated_data['password'] = make_password(serializer.validated_data['password'])
            
            serializer.save()
            return Response({"mensaje": "Usuario modificado", "id": usuario.id}, status=status.HTTP_200_OK)
        return Response({"mensaje": "Datos inválidos", "errores": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

    # ------------------ RESPONSABLE USUARIO ------------------
    @action(detail=False, methods=['get'], url_path='responsable_usuario', permission_classes=[IsAuthenticated])
    def responsable_usuario(self, request):
        """
        Devuelve todos los usuarios cuyo rol_usuario_id = 2.
        """
        responsables = Usuario.objects.filter( deleted_at__isnull=True)
        serializer = UsuarioSerializer(responsables, many=True)
        for usuario in serializer.data:
            usuario_obj = Usuario.objects.get(id=usuario['id'])
            usuario['nombre_rol'] = usuario_obj.rol_usuario.nombre_rol if usuario_obj.rol_usuario else None
        return Response(serializer.data)
    # ------------------ ELIMINAR USUARIO ------------------
    @action(detail=False, methods=['post'], url_path='eliminar_usuario', permission_classes=[IsAuthenticated])
    def eliminar_usuario(self, request):
        usuario_id = request.data.get('id')
        if not usuario_id:
            return Response({"mensaje": "ID de usuario requerido"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            usuario = Usuario.objects.get(id=usuario_id)
        except Usuario.DoesNotExist:
            return Response({"mensaje": "Usuario no encontrado"}, status=status.HTTP_404_NOT_FOUND)

        usuario.deleted_at = timezone.now()
        usuario.save(update_fields=['deleted_at'])
        return Response({"mensaje": "Usuario eliminado (soft delete)", "id": usuario.id}, status=status.HTTP_200_OK)

    # ------------------ MOSTRAR ROLES ------------------
    @action(detail=False, methods=['get'], url_path='show_roles', permission_classes=[IsAuthenticated])
    def show_roles(self, request):
        """
        Devuelve todos los roles de usuario.
        """
        roles = RolUsuario.objects.all()
        serializer = RolUsuarioSerializer(roles, many=True)
        return Response(serializer.data)
    # ------------------ Eliminar Usuario ------------------
    @action(detail=False, methods=['post'], url_path='eliminar_usuario', permission_classes=[IsAuthenticated])
    def eliminar_usuario(self, request):
        usuario_id = request.data.get('id')
        if not usuario_id:
            return Response({"mensaje": "ID de usuario requerido"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            usuario = Usuario.objects.get(id=usuario_id)
        except Usuario.DoesNotExist:
            return Response({"mensaje": "Usuario no encontrado"}, status=status.HTTP_404_NOT_FOUND)

        usuario.deleted_at = timezone.now()
        usuario.save(update_fields=['deleted_at'])
        return Response({"mensaje": "Usuario eliminado (soft delete)", "id": usuario.id}, status=status.HTTP_200_OK)

# Función opcional para generar tokens personalizados
def get_tokens_for_custom_user(user):
    refresh = RefreshToken.for_user(user)
    refresh['email'] = user.email
    if hasattr(user, 'rol_usuario') and user.rol_usuario:
        refresh['rol'] = user.rol_usuario.nombre_rol
    return {"refresh": str(refresh), "access": str(refresh.access_token)}
