from rest_framework import mixins, viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from .models import User, Department
from .serializers import (
    UserSerializer, UserListSerializer, ChangePasswordSerializer, 
    UserRestoreSerializer, DepartmentSerializer
)
from .permissions import CanCreateUsers, CanEditUsers, IsOwnerOrAdmin


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    """Custom token serializer to include user data"""

    def validate(self, attrs):
        data = super().validate(attrs)

        # Add user data to response
        data['user'] = {
            'id': self.user.id,
            'email': self.user.email,
            'name': self.user.name,
            'is_superuser': self.user.is_superuser,
            'permissions': self.user.get_permissions_dict(),
        }

        return data


class CustomTokenObtainPairView(TokenObtainPairView):
    """Custom token view"""
    serializer_class = CustomTokenObtainPairSerializer


class UserViewSet(viewsets.ModelViewSet):
    """ViewSet for User model with soft delete"""

    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_permissions(self):
        """
        Define permissions based on action
        """
        if self.action == 'create':
            return [permissions.IsAuthenticated(), CanCreateUsers()]
        elif self.action in ['update', 'partial_update', 'destroy', 'restore', 'toggle_active']:
            return [permissions.IsAuthenticated(), CanEditUsers()]
        elif self.action in ['list', 'retrieve']:
            # Para listar usuarios, solo los que pueden crear usuarios pueden ver todos
            # Los usuarios normales solo pueden ver su propio perfil
            return [permissions.IsAuthenticated()]
        elif self.action in ['me', 'update_profile', 'change_password']:
            # Acciones personales
            return [permissions.IsAuthenticated()]
        elif self.action == 'deleted':
            # Solo usuarios con can_create_users pueden ver usuarios eliminados
            return [permissions.IsAuthenticated(), CanCreateUsers()]
        return [permissions.IsAuthenticated()]

    def get_queryset(self):
        """
        Filtra los usuarios según los permisos del usuario actual
        """
        user = self.request.user
        
        # Superusuarios ven todos los usuarios
        if user.is_superuser:
            return User.objects.all()
        
        # Usuarios con permiso can_create_users ven todos los usuarios activos
        if user.can_create_users:
            return User.objects.all()
        
        # Usuarios normales solo ven su propio perfil
        return User.objects.filter(id=user.id)

    def get_serializer_class(self):
        """Return appropriate serializer class"""
        if self.action in ['list', 'retrieve', 'me', 'deleted']:
            return UserListSerializer
        elif self.action == 'restore':
            return UserRestoreSerializer
        return UserSerializer

    def perform_destroy(self, instance):
        """Override destroy to use soft delete"""
        # Verificar si el usuario tiene permiso para eliminar
        if not self.request.user.can_create_users and not self.request.user.is_superuser:
            if instance != self.request.user:
                raise permissions.PermissionDenied("No tienes permisos para eliminar este usuario")
        instance.delete()

    @action(detail=False, methods=['get'])
    def me(self, request):
        """Get current user profile"""
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)

    @action(detail=False, methods=['put', 'patch'])
    def update_profile(self, request):
        """Update current user profile (only non-permission fields)"""
        serializer = self.get_serializer(request.user, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

    @action(detail=False, methods=['post'])
    def change_password(self, request):
        """Change current user password"""
        serializer = ChangePasswordSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({'message': 'Contraseña actualizada exitosamente'}, status=status.HTTP_200_OK)

    @action(detail=True, methods=['post'])
    def toggle_active(self, request, pk=None):
        """Toggle user active status"""
        user = self.get_object()
        current_user = request.user

        # Verificar permisos
        if not current_user.can_create_users and not current_user.is_superuser:
            return Response(
                {'error': 'No tienes permisos para realizar esta acción'},
                status=status.HTTP_403_FORBIDDEN
            )

        # No permitir desactivarse a sí mismo
        if user == current_user:
            return Response(
                {'error': 'No puedes desactivar tu propia cuenta'},
                status=status.HTTP_400_BAD_REQUEST
            )

        user.is_active = not user.is_active
        user.save()

        return Response({
            'message': f'Usuario {"activado" if user.is_active else "desactivado"} exitosamente',
            'is_active': user.is_active
        })

    @action(detail=True, methods=['post'])
    def restore(self, request, pk=None):
        """Restore a soft-deleted user"""
        user = self.get_object()

        if user.deleted_at is None:
            return Response({'message': 'El usuario no está eliminado'}, status=status.HTTP_400_BAD_REQUEST)

        user.restore()
        return Response({'message': 'Usuario restaurado exitosamente'})
    
    @action(detail=False, methods=['get'])
    def deleted(self, request):
        """List soft-deleted users - solo para usuarios con can_create_users"""
        deleted_users = User.all_objects.dead()
        serializer = UserListSerializer(deleted_users, many=True)
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        """Override create to validate permission assignments"""
        current_user = request.user
        
        permission_fields = [
            'can_add_documents', 'can_create_folders', 'can_download',
            'can_share_by_email',
            'can_view', 'can_edit_folders', 'can_edit_documents',
            'can_delete_documents', 'can_delete_folders', 'can_create_users'
        ]
        
        # Si no es superusuario, verificar que no asigne permisos que no tiene
        if not current_user.is_superuser:
            for field in permission_fields:
                if request.data.get(field) and not getattr(current_user, field, False):
                    return Response(
                        {field: 'No tienes permiso para asignar este permiso'},
                        status=status.HTTP_403_FORBIDDEN
                    )
        
        return super().create(request, *args, **kwargs)

    def update(self, request, *args, **kwargs):
        """Override update to validate permission assignments"""
        current_user = request.user
        user_to_update = self.get_object()
        
        permission_fields = [
            'can_add_documents', 'can_create_folders', 'can_download',
            'can_share_by_email',
            'can_view', 'can_edit_folders', 'can_edit_documents',
            'can_delete_documents', 'can_delete_folders', 'can_create_users'
        ]
        
        # Si no es superusuario, verificar que no asigne permisos que no tiene
        if not current_user.is_superuser:
            for field in permission_fields:
                if field in request.data:
                    new_value = request.data.get(field)
                    current_value = getattr(user_to_update, field, False)
                    
                    # Si está intentando cambiar un permiso
                    if str(new_value).lower() != str(current_value).lower():
                        if not getattr(current_user, field, False):
                            return Response(
                                {field: 'No tienes permiso para modificar este permiso'},
                                status=status.HTTP_403_FORBIDDEN
                            )
        
        return super().update(request, *args, **kwargs)