### Django Rest Framework Libs ###
from rest_framework import viewsets, permissions, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.parsers import MultiPartParser, FormParser
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from rest_framework.permissions import AllowAny
from rest_framework.permissions import IsAuthenticatedOrReadOnly

### Django Libs ###
from django.conf import settings
from django_filters import rest_framework as django_filters
from django.contrib.auth.hashers import check_password
import time
import os
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

### App Libs ###
from .utils import build_aggregation_pipeline, build_absolute_uri, handle_uploaded_file, save_query_params
from .models import *
from .serializers import *
from accounts.permissions import HasGroupOrPermission

# Create a logger'
import logging
logger = logging.getLogger('panel.views')
# Set the logger level to DEBUG (or INFO, depending on your preference)
logger.setLevel(logging.DEBUG)

# Define the file path
logging_file = os.path.join(settings.LOGGING_FILE_ROOT, 'panel_views.log')

# Create a file handler specific for this logger
file_handler = logging.FileHandler(logging_file)
file_handler.setLevel(logging.DEBUG)

# Create a logging format
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)

# Add the file handler to the logger
if not logger.handlers:
    logger.addHandler(file_handler)
    
#logger.info("Logger initialized for panel.views")


class CustomViewSet(viewsets.ModelViewSet):
    ### Custom ViewSet for all models

    permission_classes = [IsAuthenticated, HasGroupOrPermission]
    authentication_classes = [JWTAuthentication]
    
    
    swagger_general_manual_parameters = {
        "page_size_param": openapi.Parameter(
            'page_size', 
            openapi.IN_QUERY, 
            description="Number of items per page", 
            type=openapi.TYPE_INTEGER, 
            required=False, 
            example=10
        ),
        "fields_param": openapi.Parameter(
            'fields', 
            openapi.IN_QUERY, 
            description="Fields to include in the response", 
            type=openapi.TYPE_STRING, 
            required=False, 
            example='id,nome,email'
        ),
    }

    
    def get_required_permissions(self):
        action_permissions = {
            'list': 'view',
            'retrieve': 'view',
            'create': 'add',
            'update': 'change',
            'partial_update': 'change',
            'destroy': 'delete',
        }
        model_name = self.model._meta.object_name.lower()
        action = action_permissions.get(self.action, '')
        codename = f"{action}_{model_name}" if action else ''

        # print(f"Action: {self.action}")
        # print(f"Codename: {codename}")
        
        return ('panel', codename)
    

    def apply_field_filters(self, data):
        """
        Filter fields based on exclude_fields and query parameters.
        Exclude specified fields and include only fields listed in query parameters if provided.
        """
        try:
            # Ensure the data is a list of dictionaries
            if not isinstance(data, list) or not all(isinstance(item, dict) for item in data):
                raise ValueError("Data should be a list of dictionaries")

            # Exclude specified fields
            if hasattr(self, 'exclude_fields'):
                data = [{k: v for k, v in item.items() if k not in self.exclude_fields} for item in data]
                
            # ### if a field is object id, convert to string
            # for item in data:
            #     for key, value in item.items():
            #         if key=='created_by' or key=='updated_by':
            #             print(f"Value {value}{type(value)}")
            #             try:
            #                 item[key] = value.split("'")[1]
            #             except:
            #                 pass 
            
            if 'medias_limit' in self.request.query_params:
                medias_limit = int(self.request.query_params.get('medias_limit', 0))
                for item in data:
                    if 'medias' in item:
                        item['medias'] = item['medias'][:medias_limit]
                    for key, value in item.items():
                        if key=='medias':
                            item[key] = item[key][:medias_limit]
                        for media in item[key]:
                            if 'medias' in media:
                                media['medias'] = media['medias'][:medias_limit]

            # Include only fields listed in query parameters if provided
            if 'fields' in self.request.query_params:
                fields = self.request.query_params['fields'].split(',')
                #print(f"Fields: {fields}")

                # Prepare a structure to handle nested fields
                nested_fields = {}
                for field in fields:
                    if '__' in field:
                        parent, child = field.split('__', 1)
                        if parent not in nested_fields:
                            nested_fields[parent] = []
                        nested_fields[parent].append(child)
                    else:
                        nested_fields[field] = None

                def filter_dict(d, keys):
                    """ Recursively filter dictionary based on the given keys. """
                    result = {}
                    for k, v in d.items():
                        if k in keys:
                            if isinstance(v, dict) and nested_fields[k]:
                                result[k] = filter_dict(v, nested_fields[k])
                            elif isinstance(v, list) and nested_fields[k]:
                                result[k] = [filter_dict(item, nested_fields[k]) for item in v]
                            else:
                                result[k] = v
                    return result
                

                # Apply the filtering logic
                data = [filter_dict(item, nested_fields) for item in data]

            return data

        except Exception as e:
            logger.error(f"Error applying field filters: {e}")
            return data

    # def handle_uploaded_file(self, file, instance):
    #     logger.info(f"Uploading file {file.name} for {instance.__class__.__name__}")
    #     # Ensure the directory exists
    #     directory = f'{instance.__class__.__name__.lower()}s/img/{instance.id}/'
    #     os.makedirs(directory, exist_ok=True)
    #     logger.info(f"Directory created: {directory}")
    #     file_content = file.read()
    #     file.seek(0)  # Reset file pointer
    #     logger.info(f"File content read: {file_content}")
        
    #     file_path = default_storage.save(os.path.join(directory, file.name), ContentFile(file_content))
    #     logger.info(f"File saved to: {file_path}")
    #     if file_path:
    #         media = settings.MEDIA_URL
    #         return file_path.split(media)[-1]

    def get_queryset(self):
        ### method for building the queryset
        # get the user
        user = self.request.user
        model = self.model._meta.model_name
        pipeline, pipeline_filter = build_aggregation_pipeline(self.request, self.exclude_fields, self.search_fields, user=user, model=model)
        results = list(self.model.objects.mongo_aggregate(pipeline))
        total = list(self.model.objects.mongo_aggregate(pipeline_filter))
        ids = [r['_id'] for r in results]
        queryset = self.model.objects.filter(id__in=ids)
        queryset.total = total[0]['total'] if total else 0
        
        return queryset
    
    def create(self, request):
        ### method for creating a single item
        try:
            context={'request': request}
            serializer = self.serializer_class(data=request.data, context=context if context else None)
            if serializer.is_valid():
                serializer.save()
                filtered_data = self.apply_field_filters([serializer.data])[0]
                return Response({'message':'Item Successfully inserted!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters = [fields_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def retrieve(self, request, pk=None):
        ### method for retrieving a single item
        try:
            from bson import ObjectId
            serializer = self.serializer_class(self.queryset.get(id=ObjectId(pk)))
            if not serializer:
                return Response({'message': 'No item found'}, status=status.HTTP_404_NOT_FOUND)
            if serializer:
                filtered_data = self.apply_field_filters([serializer.data])[0]
                return Response({'results':filtered_data}, status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(f"Error retrieving item => {e}")
            return Response({'message': f'Item {pk} not found => {e}'}, status=status.HTTP_404_NOT_FOUND)

    

    def list(self, request):
        ### method for listing all items
        try:
            start_time = time.time()
            queryset = self.get_queryset()
            try:
                #serializer = self.get_serializer(queryset, many=True)
                serializer = self.get_serializer(self.filter_queryset(queryset), many=True)
                
                # Save query params if requested and data is available
                if len(serializer.data) > 0:
                    if 'save_params' in self.request.query_params:
                        query_params = dict(self.request.query_params)
                        save_query_params(query_params=query_params, user=request.user, url=request.build_absolute_uri(), model=self.model._meta.model_name)

                try:
                    default_page_size = settings.REST_FRAMEWORK.get('PAGE_SIZE', 10)
                    page_size = int(request.query_params.get('page_size', default_page_size))
                    page = int(request.query_params.get('page', 1))
                    total = queryset.total
                    total_per_page = len(queryset)
                    total_pages = (total // page_size) + (1 if total % page_size > 0 else 0)

                    if page >= total_pages:
                        next_page = None
                    else:
                        next_page = build_absolute_uri(request, {'page': page + 1})

                    if page <= 1:
                        previous_page = None
                    else:
                        previous_page = build_absolute_uri(request, {'page': page - 1})
                    
                    filtered_data = self.apply_field_filters(serializer.data)

                    response = {
                        'count': total,
                        'num_pages': total_pages,
                        'current_count': total_per_page,
                        'next': next_page,
                        'previous': previous_page,
                        'response_time': time.time() - start_time,
                        'results': filtered_data               
                    }
                    # Remove empty or None values from the response
                    response = {key: value for key, value in response.items() if value is not None and value != ''}
                    if len(serializer.data) > 0:
                        return Response(response, status=status.HTTP_200_OK)
                    else:
                        return Response({'message': 'No item found'}, status=status.HTTP_404_NOT_FOUND)
                        
                except Exception as e:
                    logger.error(f"Error generating response => {e}")
                    return Response({'message': f'Error generating response => {e}'}, status=status.HTTP_400_BAD_REQUEST)
            except Exception as e:
                logger.error(f"Error listing items => {e}")
                return Response({'message': 'No Item found'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"Error listing items => {e}")
            response = {'message': 'Error listing items', 'Error': str(e)}
            return Response(response, status=status.HTTP_400_BAD_REQUEST)
    
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context={'request': request}
            serializer = self.serializer_class(instance, data=request.data, context=context if context else None, partial=True)
            #print(serializer)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully Updated!', 'results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context={'request': request}
            serializer = self.serializer_class(instance, data=request.data, context=context if context else None, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully Updated!', 'results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, Example='Bearer <access_token>')
    @swagger_auto_schema(manual_parameters=[jwt_token_param])
    def destroy(self, request, pk=None):
        ### method for deleting a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            instance.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except Exception as e:
            logger.error(f"Error deleting item => {e}")
            return Response({'message': f'Error deleting item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    

class FavoritoViewSet(CustomViewSet):
    model = Favorito
    queryset = model.objects.all()
    #serializer_class = FavoritoReadOnlySerializer
    serializer_class = FavoritoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    # def get_permissions(self):
    #     if self.action in ['list']:
    #         return [AllowAny()]
    #     return super().get_permissions()
    
    # def get_authentication_classes(self):
    #     if self.action in ['list']:
    #         return []
    
    
    filter_fields = {
        'cliente__id': ['in', 'exact'],
        'tipo_imovel__id': ['in', 'exact'],
        'imovel__id': ['in', 'exact'],
    }
    
    
    # def create(self, request):
    #     try:
    #         serializer = FavoritoWriteOnlySerializer(data=request.data)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = FavoritoReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
    #             return Response({'message':'Item Successfully inserted!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error creating item => {e}")
    #         return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # def update(self, request, pk=None):
    #     ### method for updating a single item
    #     try:
    #         instance = self.queryset.get(id=ObjectId(pk))
    #         serializer = FavoritoWriteOnlySerializer(instance, data=request.data, partial=True)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = FavoritoReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
    #             return Response({"message": "Item updated successfully", 'results':serializer.data}, status=status.HTTP_200_OK)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error updating item => {e}")
    #         return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



    # def partial_update(self, request, pk=None):
    #     ### method for partially updating a single item
    #     try:
    #         instance = self.queryset.get(id=ObjectId(pk))
    #         serializer = FavoritoWriteOnlySerializer(instance, data=request.data, partial=True)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = FavoritoReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
    #             return Response({"message": "Item updated successfully", 'results':serializer.data}, status=status.HTTP_200_OK)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error updating item => {e}")
    #         return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""List data.""",
        manual_parameters=manual_parameters,
        operation_summary='List data', 
        operation_id='favoritos_list', tags=['favoritos'],
        responses={200: openapi.Response('Data successfully listed', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        
        )
    def list(self, request):
        return super().list(request)
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Retrieve data.""",
        manual_parameters=manual_parameters,
        operation_summary='Retrieve data', 
        operation_id='favoritos_retrieve', tags=['favoritos'],
        responses={200: openapi.Response('Data successfully retrieved', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        
        )
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)
    

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Create a new register.""",
        manual_parameters=manual_parameters,
        operation_summary='Create a new register', 
        operation_id='favoritos_create', tags=['favoritos'],
        responses={200: openapi.Response('Data successfully created', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        request_body=FavoritoSerializer
        
        ) 
    def create(self, request):
        return super().create(request)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Update a register', 
        operation_id='favoritos_update', tags=['favoritos'],
        responses={200: openapi.Response('Data successfully updated', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        request_body=FavoritoSerializer
        
        )
    def update(self, request, pk=None):
        return super().update(request, pk)
    

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Partial update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Partial update a register', 
        operation_id='favoritos_partial_update', tags=['favoritos'],
        responses={200: openapi.Response('Data successfully partial updated', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        request_body=FavoritoSerializer
        
        )
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)
    
    # jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    # manual_parameters=[jwt_token_param]
    # @swagger_auto_schema(
    #     operation_description="""Delete a register.""",
    #     manual_parameters=manual_parameters,
    #     operation_summary='Delete a register', 
    #     operation_id='favoritos_delete', tags=['favoritos'],
    #     responses={204: openapi.Response('No Content', FavoritoSerializer),
    #                     400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
    #     request_body=FavoritoSerializer
        
    #     )
    # def destroy(self, request, pk=None):
    #     return super().destroy(request, pk)


    #endpoints specific for clients access
    from accounts.authentication import ClienteTokenAuthentication
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""List my data.""",
        manual_parameters=manual_parameters,
        operation_summary='List my data', 
        operation_id='favoritos-my_list', tags=['favoritos-my'],
        responses={200: openapi.Response('Data successfully listed', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        
        )
    @action(detail=False, methods=['get'], url_path='me', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def my_favorites(self, request, pk=None):
        """List all favorites for the authenticated Cliente or retrieve a specific one."""
        try:
                # 🔍 List all contacts for the authenticated Cliente
                queryset = self.filter_queryset(self.get_queryset().filter(cliente=request.user))
                page = self.paginate_queryset(queryset)
                if page is not None:
                    serializer = self.get_serializer(page, many=True)
                    return self.get_paginated_response(serializer.data)
                serializer = self.get_serializer(queryset, many=True)
                return Response({'count': queryset.count(), 'results': serializer.data}, status=status.HTTP_200_OK)
        except Favorito.DoesNotExist:
            return Response({'message': 'Favorit Property not found'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"Error listing items => {e}")
            return Response({'message': f'Error listing items => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        
        
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Retrieve my data.""",
        manual_parameters=manual_parameters,
        operation_summary='Retrieve my data', 
        operation_id='favoritos-my_retrieve', tags=['favoritos-my'],
        responses={200: openapi.Response('Data successfully listed', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        
        )
    @action(detail=False, methods=['get'], url_path='me/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def my_favorite(self, request, pk=None):
        """List all favorites for the authenticated Cliente or retrieve a specific one."""
        try:
            if pk:
                # 🔍 Retrieve a specific favorite by ID
                instance = self.queryset.get(id=ObjectId(pk), cliente=request.user)
                serializer = FavoritoSerializer(instance)
                return Response({'result': serializer.data}, status=status.HTTP_200_OK)
        except Favorito.DoesNotExist:
            return Response({'message': 'Favorit Property not found'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"Error retrieving item => {e}")
            return Response({'message': f'Error retrieving items => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Create a new register.""",
        manual_parameters=manual_parameters,
        operation_summary='Create a new register', 
        operation_id='favoritos-my_create', tags=['favoritos-my'],
        responses={200: openapi.Response('Data successfully created', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        request_body=FavoritoAddSerializer
        
        ) 
    @action(detail=False, methods=['post'], url_path='add', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])  
    def add_favorites(self, request):
        try:
            request.data['cliente_id'] = str(request.user.id)
            serializer = FavoritoSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = FavoritoSerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully inserted!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Update a register', 
        operation_id='favoritos-my_update', tags=['favoritos-my'],
        responses={200: openapi.Response('Data successfully updated', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', FavoritoSerializer)},
        request_body=FavoritoAddSerializer
        
        )
    @action(detail=False, methods=['put'], url_path='update/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def update_favorite(self, request, pk=None):
        """Update an existing favorite property."""
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            request.data['cliente_id'] = str(request.user.id)  # Ensure cliente_id matches the authenticated user

            serializer = FavoritoSerializer(instance, data=request.data, partial=True)
            
            if serializer.is_valid():
                serializer.save()
                return Response({'message': 'Item Successfully Updated!', 'results': serializer.data}, status=status.HTTP_200_OK)

            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Delete a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Delete a register', 
        operation_id='favoritos-my_delete', tags=['favoritos-my'],
        responses={204: openapi.Response('No Content', FavoritoSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=FavoritoDeleteSerializer
        
        )
    @action(detail=False, methods=['delete'], url_path='delete/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def delete_favorite(self, request, pk=None):
        """Delete a specific favorite."""
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            instance.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except Exception as e:
            logger.error(f"Error deleting item => {e}")
            return Response({'message': f'Error deleting item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class ContatoClienteViewSet(CustomViewSet):
    model = ContatoCliente
    queryset = model.objects.all()
    #serializer_class = ContatoClienteReadOnlySerializer
    serializer_class = ContatoClienteSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'tipo_imovel__id': ['in', 'exact'],
        'imovel__id': ['in', 'exact'],
        'cliente__id': ['in', 'exact'],
    }
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['create']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    # def create(self, request):
    #     try:
    #         serializer = ContatoClienteWriteOnlySerializer(data=request.data)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = ContatoClienteReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
    #             return Response({'message':'Item Successfully inserted!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error creating item => {e}")
    #         return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # def update(self, request, pk=None):
    #     ### method for updating a single item
    #     try:
    #         instance = self.queryset.get(id=ObjectId(pk))
    #         serializer = ContatoClienteWriteOnlySerializer(instance, data=request.data, partial=True)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = ContatoClienteReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
    #             return Response({'messagem':'Item successfully updated!','results':serializer.data}, status=status.HTTP_200_OK)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error updating item => {e}")
    #         return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



    # def partial_update(self, request, pk=None):
    #     ### method for partially updating a single item
    #     try:
    #         instance = self.queryset.get(id=ObjectId(pk))
    #         serializer = ContatoClienteWriteOnlySerializer(instance, data=request.data, partial=True)
    #         if serializer.is_valid():
    #             serializer.save()
    #             serializer = ContatoClienteReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
    #             return Response({'messagem':'Item successfully updated!','results':serializer.data}, status=status.HTTP_200_OK)
    #         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #     except Exception as e:
    #         logger.error(f"Error updating item => {e}")
    #         return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""List data.""",
        manual_parameters=manual_parameters,
        operation_summary='List data', 
        operation_id='contatos-cliente_list', tags=['contatos-cliente'],
        responses={200: openapi.Response('Data successfully listed', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        
        )
    def list(self, request):
        return super().list(request)
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Retrieve data.""",
        manual_parameters=manual_parameters,
        operation_summary='Retrieve data', 
        operation_id='contatos-cliente_retrieve', tags=['contatos-cliente'],
        responses={200: openapi.Response('Data successfully retrieved', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        
        )
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)
    

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Create a new register.""",
        manual_parameters=manual_parameters,
        operation_summary='Create a new register', 
        operation_id='contatos-cliente_create', tags=['contatos-cliente'],
        responses={200: openapi.Response('Data successfully created', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteSerializer
        
        ) 
    def create(self, request):
        return super().create(request)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Update a register', 
        operation_id='contatos-cliente_update', tags=['contatos-cliente'],
        responses={200: openapi.Response('Data successfully updated', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteSerializer
        
        )
    def update(self, request, pk=None):
        return super().update(request, pk)
    

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Partial update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Partial update a register', 
        operation_id='contatos-cliente_partial_update', tags=['contatos-cliente'],
        responses={200: openapi.Response('Data successfully partial updated', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteSerializer
        
        )
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)

    
    #endpoints specific for clients access
    from accounts.authentication import ClienteTokenAuthentication
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""List my data.""",
        manual_parameters=manual_parameters,
        operation_summary='List my data', 
        operation_id='contatos-clientes-my_list', tags=['contatos-clientes-my'],
        responses={200: openapi.Response('Data successfully listed', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        
        )
    @action(detail=False, methods=['get'], url_path='me', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def my_contacts(self, request, pk=None):
        """List all contacts for the authenticated Cliente or retrieve a specific one."""
        try:
                # 🔍 List all contacts for the authenticated Cliente
                queryset = self.filter_queryset(self.get_queryset().filter(cliente=request.user))
                page = self.paginate_queryset(queryset)
                if page is not None:
                    serializer = self.get_serializer(page, many=True)
                    return self.get_paginated_response(serializer.data)
                serializer = self.get_serializer(queryset, many=True)
                return Response({'count': queryset.count(), 'results': serializer.data}, status=status.HTTP_200_OK)

        except ContatoCliente.DoesNotExist:
            return Response({'message': 'Contact not found'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"Error listing items => {e}")
            return Response({'message': f'Error listing items => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Retrieve my data.""",
        manual_parameters=manual_parameters,
        operation_summary='Retrieve my data', 
        operation_id='contatos-clientes-my_retrieve', tags=['contatos-clientes-my'],
        responses={200: openapi.Response('Data successfully retrieved', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        
        )
    @action(detail=False, methods=['get'], url_path='me/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def my_contact(self, request, pk=None):
        """Retrieve a specific contact for the authenticated Cliente."""
        try:
            if pk:
                # 🔍 Retrieve a specific contact by ID
                instance = self.queryset.get(id=ObjectId(pk), cliente=request.user)
                serializer = ContatoClienteSerializer(instance)
                return Response({'result': serializer.data}, status=status.HTTP_200_OK)
            return Response({'message': 'Contact not found'}, status=status.HTTP_404_NOT_FOUND)
        except ContatoCliente.DoesNotExist:
            return Response({'message': 'Contact not found'}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"Error listing items => {e}")
            return Response({'message': f'Error listing items => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Create a new register.""",
        manual_parameters=manual_parameters,
        operation_summary='Create a new register', 
        operation_id='contatos-clientes-my_create', tags=['contatos-clientes-my'],
        responses={200: openapi.Response('Data successfully created', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteAddSerializer
        
        )
    @action(detail=False, methods=['post'], url_path='add', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])  
    def add_contact(self, request):
        try:
            request.data['cliente_id'] = str(request.user.id)
            serializer = ContatoClienteSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = ContatoClienteSerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully inserted!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Update a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Update a register', 
        operation_id='contatos-clientes-my_update', tags=['contatos-clientes-my'],
        responses={200: openapi.Response('Data successfully updated', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteAddSerializer
        
        )
    @action(detail=False, methods=['put'], url_path='update/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def update_contact(self, request, pk=None):
        """Update an existing contact."""
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            request.data['cliente_id'] = str(request.user.id)  # Ensure cliente_id matches the authenticated user

            serializer = ContatoClienteSerializer(instance, data=request.data, partial=True)
            
            if serializer.is_valid():
                serializer.save()
                return Response({'message': 'Item Successfully Updated!', 'results': serializer.data}, status=status.HTTP_200_OK)

            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(
        operation_description="""Delete a register.""",
        manual_parameters=manual_parameters,
        operation_summary='Delete a register', 
        operation_id='contatos-clientes-my_delete', tags=['contatos-clientes-my'],
        responses={204: openapi.Response('No Content', ContatoClienteSerializer),
                        400: openapi.Response('Error Generating Response', ContatoClienteSerializer)},
        request_body=ContatoClienteDeleteSerializer
        
        )
    @action(detail=False, methods=['delete'], url_path='delete/(?P<pk>[^/.]+)', permission_classes=[IsAuthenticated], authentication_classes=[ClienteTokenAuthentication])
    def delete_contact(self, request, pk=None):
        """Delete a specific contact."""
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            instance.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except Exception as e:
            logger.error(f"Error deleting item => {e}")
            return Response({'message': f'Error deleting item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class CategoriaViewSet(CustomViewSet):
    model = Categoria
    queryset = model.objects.all()
    serializer_class = CategoriaSerializer
    parser_classes = (MultiPartParser, FormParser)
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
    }
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    
    def create(self, request):
        try:
            data = request.data.copy()  # Create a mutable copy of request data
            if 'imagem' in data:
                data.pop('imagem')
            serializer = CategoriaSerializer(data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                instance = self.queryset.get(id=ObjectId(serializer.data['id']))
                data = request.data.copy()  # Create a mutable copy of request data
                # Handle file upload
                if 'imagem' in request.FILES:
                    if not request.FILES['imagem'].content_type.startswith('image'):
                        return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                    
                    file = request.FILES['imagem']
                    folder_name = 'categorias'
                    instance_id = instance.id
                    
                    file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                    if file_url:
                        data['imagem'] = file_url  # Update data with the file URL
                    
                    serializer = CategoriaSerializer(instance, data=data, partial=True)
                    if serializer.is_valid():
                        serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'imagem' in request.FILES:
                if not request.FILES['imagem'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['imagem']
                folder_name = 'categorias'
                instance_id = instance.id
                    
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:    
                    data['imagem'] = file_url  # Update data with the file URL
                
            serializer = CategoriaSerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item2 => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'imagem' in request.FILES:
                if not request.FILES['imagem'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['imagem']
                folder_name = 'categorias'
                instance_id = instance.id
                    
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:
                    data['imagem'] = file_url  # Update data with the file URL
            
            serializer = CategoriaSerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    

class PostViewSet(CustomViewSet):
    model = Post
    queryset = model.objects.all()
    serializer_class = PostReadOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    search_fields = ['titulo', 'subtitulo', 'conteudo', 'tags']
    
    filter_fields = {
        'id': ['in', 'exact'],
        'titulo': ['icontains', 'exact'],
        'subtitulo': ['icontains', 'exact'],
        'conteudo': ['icontains', 'exact'],
        'data': ['exact', 'range'],
        'data_cadastro':['exact', 'range'],
        'data_atualizacao':['exact', 'range'],
        'tags': ['icontains', 'exact'],
        'categorias__id': ['in', 'exact'],
        'autor__id': ['in', 'exact'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    def create(self, request):
        try:
            data = request.data.copy()  # Create a mutable copy of request data
            if 'imagem_principal' in data:
                # Only if the parser_classes are set to MultiPartParser
                data.pop('imagem_principal')
            else:
                return Response({'message': 'Main image is required'}, status=status.HTTP_400_BAD_REQUEST)
            serializer = PostWriteOnlySerializer(data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                instance = self.queryset.get(id=ObjectId(serializer.data['id']))
                data = request.data.copy()  # Create a mutable copy of request data
                # Handle file upload
                if 'imagem_principal' in request.FILES:
                    # Only if the parser_classes are set to MultiPartParser
                    #print(f"File Content: {request.FILES['imagem_principal'].content_type}")
                    if not request.FILES['imagem_principal'].content_type.startswith('image'):
                        return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                    file = request.FILES['imagem_principal']
                    folder_name = 'posts'
                    instance_id = instance.id
                    
                    file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                    if file_url:
                        data['imagem_principal'] = file_url
                    
                    serializer = PostWriteOnlySerializer(instance, data=data, partial=True)
                    if serializer.is_valid():
                        serializer.save()
                
                serializer = PostReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'imagem_principal' in request.FILES:
                if not request.FILES['imagem_principal'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['imagem_principal']
                folder_name = 'posts'
                instance_id = instance.id
                    
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:
                    data['imagem_principal'] = file_url
                
            serializer = PostWriteOnlySerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = PostReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item2 => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'imagem_principal' in request.FILES:
                if not request.FILES['imagem_principal'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['imagem_principal']
                folder_name = 'posts'
                instance_id = instance.id
                    
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:
                    data['imagem_principal'] = file_url
            
            serializer = PostWriteOnlySerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = PostReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    

class BannerMosaicoViewSet(CustomViewSet):
    model = BannerMosaico
    queryset = model.objects.all()
    serializer_class = BannerMosaicosReadOnlySerializer
    parser_classes = [MultiPartParser, FormParser]
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'ordem': ['in', 'exact'],
        'template': ['in', 'exact'],
        'posts__id': ['in', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    
    def create(self, request):
        try:
            #logger.info(f"Data from BannerMosaico: {request.data}")
            data = request.data.copy()  # Create a mutable copy of request data
            if 'template' in data:
                data.pop('template')
            serializer = BannerMosaicosWriteOnlySerializer(data=data, partial=True)
            if serializer.is_valid():
                #ogger.info(f"Serializer data from BannerMosaico: {serializer.data}")
                serializer.save()
                instance = self.queryset.get(id=ObjectId(serializer.data['id']))
                data = request.data.copy()  # Create a mutable copy of request data
                # Handle file upload
                if 'template' in request.FILES:
                    #logger.info(f"File Content from BannerMosaico: {request.FILES['template'].content_type}")
                    if not request.FILES['template'].content_type.startswith('image'):
                        return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                    file = request.FILES['template']
                    folder_name = 'banner_mosaicos'
                    instance_id = instance.id
                        
                    file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                    if file_url:
                        data['template'] = file_url
                    
                    serializer = BannerMosaicosWriteOnlySerializer(instance, data=data, partial=True)
                    if serializer.is_valid():
                        serializer.save()
                
                serializer = BannerMosaicosReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'template' in request.FILES:
                if not request.FILES['template'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['template']
                folder_name = 'banner_mosaicos'
                instance_id = instance.id
                    
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:
                    data['template'] = file_url
                
            serializer = BannerMosaicosWriteOnlySerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = BannerMosaicosReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item2 => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            
            data = request.data.copy()  # Create a mutable copy of request data
            # Handle file upload
            if 'template' in request.FILES:
                if not request.FILES['template'].content_type.startswith('image'):
                    return Response({'message': 'Invalid file type. Only images are allowed.'}, status=status.HTTP_400_BAD_REQUEST)
                
                file = request.FILES['template']
                folder_name = 'banner_mosaicos'
                instance_id = instance.id
                        
                file_url = handle_uploaded_file(file=file, folder_name=folder_name,instance_id=instance_id)
                if file_url:
                    data['template'] = file_url
            
            serializer = BannerMosaicosWriteOnlySerializer(instance, data=data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = BannerMosaicosReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
        
class SimulacaoViewSet(CustomViewSet):
    model = Simulacao
    queryset = model.objects.all()
    serializer_class = SimulacaoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []  
    
    filter_fields = {
        'id': ['in', 'exact'],
        'tipo': ['icontains', 'exact'],
        'renda_familiar_mensal': ['range', 'gte', 'lt', 'lte', 'gt'],
        'valor_maximo_parcelas': ['range', 'gte', 'lt', 'lte', 'gt'],
        'entrada_disponivel': ['range', 'gte', 'lt', 'lte', 'gt'],
        'fgts': ['range', 'gte', 'lt', 'lte', 'gt'],
        'nome': ['icontains', 'exact'],
        'email': ['exact'],
        'telefone': ['exact'],
    }
    
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
  

class AssuntoViewSet(CustomViewSet):
    model = Assunto
    queryset = model.objects.all()
    serializer_class = AssuntoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
        'email': ['exact'],
    }
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    
    
class ContatoViewSet(CustomViewSet):
    model = Contato
    queryset = model.objects.all()
    serializer_class = ContatoReadOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'assunto__id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
        'email': ['exact'],
        'telefone': ['exact'],
        'estado': ['icontains', 'exact'],
        'cidade': ['icontains', 'exact'],
        'news': ['exact'],
        'mensagem': ['icontains', 'exact'],  
    }
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['create', ]:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    def create(self, request):
        try:
            serializer = ContatoWriteOnlySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = ContatoReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = ContatoWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = ContatoReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = ContatoWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = ContatoReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


class ImprensaViewSet(CustomViewSet):
    model = Imprensa
    queryset = model.objects.all()
    serializer_class = ImprensaSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = ImprensaSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = ImprensaSerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = ImprensaSerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class AssuntoOuvidoriaViewSet(CustomViewSet):
    model = AssuntoOuvidoria
    queryset = model.objects.all()
    serializer_class = AssuntoOuvidoriaSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
        'email': ['exact'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
        


class OuvidoriaViewSet(CustomViewSet):
    model = Ouvidoria
    queryset = model.objects.all()
    serializer_class = OuvidoriaReadOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'assunto__id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
        'email': ['exact'],
        'telefone': ['exact'],
        'estado': ['icontains', 'exact'],
        'cidade': ['icontains', 'exact'],
        'mensagem': ['icontains'],
    }
    
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    def create(self, request):
        try:
            serializer = OuvidoriaWriteOnlySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = OuvidoriaReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = OuvidoriaWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = OuvidoriaReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = OuvidoriaWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = OuvidoriaReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        


class GrupoPerguntaFrequenteViewSet(CustomViewSet):
    model = GrupoPerguntaFrequente
    queryset = model.objects.all()
    serializer_class = GrupoPerguntaFrequentesSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'ordem': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
        

class PerguntaFrequenteViewSet(CustomViewSet):
    model = PerguntaFrequente
    queryset = model.objects.all()
    serializer_class = PerguntaFrequenteReadOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'ordem': ['in', 'exact'],
        'grupo__id': ['in', 'exact'],
        'pergunta': ['icontains', 'exact'],
        'resposta': ['icontains'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    def create(self, request):
        try:
            serializer = PerguntaFrequenteWriteOnlySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = PerguntaFrequenteReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = PerguntaFrequenteWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = PerguntaFrequenteReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = PerguntaFrequenteWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = PerguntaFrequenteReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    

class PorqueRemaxViewSet(CustomViewSet):
    model = PorqueRemax
    queryset = model.objects.all()
    serializer_class = PorqueRemaxSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class RemaxNoBrasilViewSet(CustomViewSet):
    model = RemaxNoBrasil
    queryset = model.objects.all()
    serializer_class = RemaxNoBrasilReadOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
        'texto_simplificado': ['icontains', 'exact'],
        'agencias__id': ['in', 'exact'],
        'corretores__id': ['in', 'exact'],
        'imoveis_exclusivos__id': ['in', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    

    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = RemaxNoBrasilWriteOnlySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                serializer = RemaxNoBrasilReadOnlySerializer(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = RemaxNoBrasilWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = RemaxNoBrasilReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = RemaxNoBrasilWriteOnlySerializer(instance, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = RemaxNoBrasilReadOnlySerializer(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        

class ReconhecimentoViewSet(CustomViewSet):
    model = Reconhecimento
    queryset = model.objects.all()
    serializer_class = ReconhecimentosSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'ordem': ['in', 'exact'],
        'selo': ['icontains', 'exact'],
        'titulo': ['icontains', 'exact'],
        'status': ['exact'],
    }
    
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()


class RemaxNoMundoViewSet(CustomViewSet):
    model = RemaxNoMundo
    queryset = model.objects.all()
    serializer_class = RemaxNoMundoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
        'texto_simplificado': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class UniversidadeViewSet(CustomViewSet):
    model = Universidade
    queryset = model.objects.all()
    serializer_class = UniversidadeSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        


class ParceiroViewSet(CustomViewSet):
    model = Parceiro
    queryset = model.objects.all()
    serializer_class = ParceiroSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class RelacaoInvestidorViewSet(CustomViewSet):
    model = RelacaoInvestidor
    queryset = model.objects.all()
    serializer_class = RelacaoInvestidorSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'texto': ['icontains', 'exact'],
    }
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    def create(self, request):
        if len(self.model.objects.all()) > 0:
            return Response({'message': 'Only one item is allowed in this collection.'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



############################################################################################################
############################### Estados, Cidades, Bairros Detalhes #########################################
############################################################################################################

class EstadoDetalheViewSet(CustomViewSet):
    model = EstadoDetalhe
    queryset = model.objects.all()
    serializer_class = EstadoDetalheReadOnlySerializer
    serializer_write_class = EstadoDetalheWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    filter_fields = {
        'id': ['in', 'exact'],
        'estado_id': ['in', 'exact'],
        'texto': ['icontains'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()


    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    estado_id_param = openapi.Parameter('estado_id__in', openapi.IN_QUERY, description="Comma-separated list of Estado IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    texto_id_param=  openapi.Parameter('texto__icontains', openapi.IN_QUERY, description="Text to search for in the 'texto' field (uses `__icontains` lookup)", type=openapi.TYPE_STRING, required=False, example="Lorem ipsum")
    @swagger_auto_schema(manual_parameters=[page_size_param, fields_param,  estado_id_param, texto_id_param])
    def list(self, request):
        return super().list(request)
    
    # estado_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=True, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, estado_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Create a new Estado object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Estado object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Estado created',
                    400: 'Error while creating Estado', }, \
             operation_id='estados-detalhes_create',  operation_summary='Create a Estado register', tags=['estados-detalhes'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # estado_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, estado_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Estado object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Estado object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Estado updated',
                    400: 'Error while updating Estado', }, \
             operation_id='estados-detalhes_update',  operation_summary='Update a Estado register', tags=['estados-detalhes'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # estado_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, estado_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Estado object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Estado object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Estado updated',
                    400: 'Error while updating Estado', }, \
             operation_id='estados-detalhes_partial_update',  operation_summary='Update a Estado register', tags=['estados-detalhes'])
    def partial_update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    

class CidadeDetalheViewSet(CustomViewSet):
    model = CidadeDetalhe
    queryset = model.objects.all()
    serializer_class = CidadeDetalheReadOnlySerializer
    serializer_write_class = CidadeDetalheWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    filter_fields = {
        'id': ['in', 'exact'],
        'cidade_id': ['in', 'exact'],
        'texto': ['icontains'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()


    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    cidade_id_param = openapi.Parameter('cidade_id__in', openapi.IN_QUERY, description="Comma-separated list of Cidade IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    texto_id_param=  openapi.Parameter('texto__icontains', openapi.IN_QUERY, description="Text to search for in the 'texto' field (uses `__icontains` lookup)", type=openapi.TYPE_STRING, required=False, example="Lorem ipsum")
    @swagger_auto_schema(manual_parameters=[page_size_param, fields_param, cidade_id_param, texto_id_param])
    def list(self, request):
        return super().list(request)
    
    # cidade_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=True, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, cidade_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Create a new Cidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Cidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Cidade created',
                    400: 'Error while creating Cidade', }, \
             operation_id='cidades-detalhes_create',  operation_summary='Create a Cidade register', tags=['cidades-detalhes'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # cidade_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, cidade_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Cidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Cidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Cidade updated',
                    400: 'Error while updating Cidade', }, \
             operation_id='cidades-detalhes_update',  operation_summary='Update a Cidade register', tags=['cidades-detalhes'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # cidade_partial_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, cidade_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Cidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Cidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Cidade updated',
                    400: 'Error while updating Cidade', }, \
             operation_id='cidades-detalhes_partial_update',  operation_summary='Update a Cidade register', tags=['cidades-detalhes'])
    def partial_update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



class BairroDetalheViewSet(CustomViewSet):
    model = BairroDetalhe
    queryset = model.objects.all()
    serializer_class = BairroDetalheReadOnlySerializer
    serializer_write_class = BairroDetalheWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    filter_fields = {
        'id': ['in', 'exact'],
        'bairro_id': ['in', 'exact'],
        'texto': ['icontains'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()


    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    bairro_id_param = openapi.Parameter('bairro_id__in', openapi.IN_QUERY, description="Comma-separated list of Bairro IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    texto_id_param=  openapi.Parameter('texto__icontains', openapi.IN_QUERY, description="Text to search for in the 'texto' field (uses `__icontains` lookup)", type=openapi.TYPE_STRING, required=False, example="Lorem ipsum")
    @swagger_auto_schema(manual_parameters=[page_size_param, fields_param, bairro_id_param, texto_id_param])
    def list(self, request):
        return super().list(request)
    
    # bairro_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=True, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, bairro_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Create a new Bairro object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Bairro object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Bairro created',
                    400: 'Error while creating Bairro', }, \
             operation_id='bairros-detalhes_create',  operation_summary='Create a Bairro register', tags=['bairros-detalhes'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                return Response({'message':'Item Successfully created!', 'results':serializer.data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # bairro_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, bairro_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Bairro object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Bairro object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Bairro updated',
                    400: 'Error while updating Bairro', }, \
             operation_id='bairros-detalhes_update',  operation_summary='Update a Bairro register', tags=['bairros-detalhes'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # bairro_partial_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=False, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    texto_param = openapi.Parameter('texto', openapi.IN_FORM, description="Texto", type=openapi.TYPE_STRING, required=False, example='Lorem ipsum')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, bairro_id_param, texto_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Bairro object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Bairro object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Bairro updated',
                    400: 'Error while updating Bairro', }, \
             operation_id='bairros-detalhes_partial_update',  operation_summary='Update a Bairro register', tags=['bairros-detalhes'])
    def partial_update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        

################################################################################################################
################################################################################################################



class ConstrutoraViewSet(CustomViewSet):
    model = Construtora
    queryset = model.objects.all()
    serializer_class = ConstrutoraSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    filter_fields = {
        'id': ['in', 'exact'],
        'nome': ['icontains', 'exact'],
        'descricao': ['icontains'],
        'status': ['exact'],
        'logo': ['exists'],
    }
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()

class PoliticaPrivacidadeTextoViewSet(CustomViewSet):
    model = PoliticaPrivacidadeTexto
    queryset = model.objects.all()
    serializer_class = PoliticaPrivacidadeTextoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()


class TermosDeUsoViewSet(CustomViewSet):
    model = TermosDeUso
    queryset = model.objects.all()
    serializer_class = TermosDeUsoSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()



    

# class FotoLancamentoViewSet(CustomViewSet):
#     model = FotoLancamento
#     queryset = model.objects.all()
#     serializer_class = FotoLancamentoSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = [] 
#     parser_classes = [MultiPartParser, FormParser]
    

#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()
    


# class PlantaLancamentoViewSet(CustomViewSet):
#     model = PlantaLancamento
#     queryset = model.objects.all()
#     serializer_class = PlantaLancamentoSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = [] 
#     parser_classes = [MultiPartParser, FormParser]
    

#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()
    

# class UnidadeLancamentoViewSet(CustomViewSet):
#     model = UnidadeLancamento
#     queryset = model.objects.all()
#     serializer_class = UnidadeLancamentoSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = []
#     parser_classes = [MultiPartParser, FormParser]
    

#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()


# class FotoUnidadeLancamentoViewSet(CustomViewSet):
#     model = FotoUnidadeLancamento
#     queryset = model.objects.all()
#     serializer_class = FotoUnidadeLancamentoSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = [] 
#     parser_classes = [MultiPartParser, FormParser]
    

#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()
    
    

# class AgenciaBannerViewSet(CustomViewSet):
#     model = AgenciaBanner
#     queryset = model.objects.all()
#     serializer_class = AgenciaBannerSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = [] 
#     parser_classes = [MultiPartParser, FormParser]
    

#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()


# class LancamentoSimpleViewSet2(viewsets.ModelViewSet):
#     queryset = Lancamento.objects.all()
#     serializer_class = LancamentoSerializer
#     permission_classes = [AllowAny]
#     parser_classes = [MultiPartParser, FormParser]
    
#     def retrieve(self, request, *args, **kwargs):
#         if 'pk' not in kwargs:
#             return Response({'message': 'Item ID is required'}, status=status.HTTP_400_BAD_REQUEST)
#         else:
#             pk = kwargs['pk']
#             try:
#                 instance = Lancamento.objects.get(id=ObjectId(pk))
#                 serializer = self.get_serializer(instance)
#                 return Response(serializer.data)
#             except Exception as e:
#                 return Response({'message': f'Error retrieving item {pk}=> {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
#     def update(self, request, *args, **kwargs):
#         if 'pk' not in kwargs:
#             return Response({'message': 'Item ID is required'}, status=status.HTTP_400_BAD_REQUEST)
#         else:
#             pk = kwargs['pk']
#             try:
#                 instance = Lancamento.objects.get(id=ObjectId(pk))
#                 serializer = self.get_serializer(instance, data=request.data, partial=True)
#                 if serializer.is_valid():
#                     serializer.save()
#                     return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
#                 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#             except Exception as e:
#                 return Response({'message': f'Error updating item {pk}=> {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
#     def partial_update(self, request, *args, **kwargs):
#         if 'pk' not in kwargs:
#             return Response({'message': 'Item ID is required'}, status=status.HTTP_400_BAD_REQUEST)
#         else:
#             pk = kwargs['pk']
#             try:
#                 instance = Lancamento.objects.get(id=ObjectId(pk))
#                 serializer = self.get_serializer(instance, data=request.data, partial=True)
#                 if serializer.is_valid():
#                     serializer.save()
#                     return Response({'message':'Item successfully updated','results':serializer.data}, status=status.HTTP_200_OK)
#                 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#             except Exception as e:
#                 return Response({'message': f'Error updating item {pk}=> {e}'}, status=status.HTTP_400_BAD_REQUEST)


### Lancamentos ViewSet
class LancamentoViewSet(CustomViewSet):
    model = Lancamento
    queryset = model.objects.all()
    serializer_class = LancamentoReadOnlySerializer
    serializer_write_class = LancamentoWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    image_field = 'logo'
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve', 'get_unique_construtoras']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve', 'get_unique_construtoras']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters = [fields_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def retrieve(self, request, pk=None):
        ### method for retrieving a single item
        try:
            try:
                from bson import ObjectId
                pk = ObjectId(pk)
                if isinstance(pk, ObjectId):
                    instance = self.queryset.get(id=ObjectId(pk))
            except:
                if isinstance(pk, str):
                    instance = self.queryset.get(slug=str(pk))
            
            serializer = self.serializer_class(instance)
            filtered_data = self.apply_field_filters([serializer.data])[0]
            return Response({'results': filtered_data}, status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(f"Error retrieving item => {e}")
            return Response({'message': f'Item {pk} not found => {e}'}, status=status.HTTP_404_NOT_FOUND)

    
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    cidade_id_param = openapi.Parameter('cidade_id__in', openapi.IN_QUERY, description="Comma-separated list of Cidade IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    estado_id_param = openapi.Parameter('estado_id__in', openapi.IN_QUERY, description="Comma-separated list of Estado IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    bairro_id_param = openapi.Parameter('bairro_id__in', openapi.IN_QUERY, description="Comma-separated list of Bairro IDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="11,12")
    construtora_id_param = openapi.Parameter('construtora_id__in', openapi.IN_QUERY, description="Comma-separated list of Construtora ObjectIDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4")
    caracteristicas_id_param = openapi.Parameter('caracteristicas_id', openapi.IN_QUERY, description="List of feature_id", type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_INTEGER), required=False, example="[1,2,3]")
    @swagger_auto_schema(manual_parameters=[page_size_param, fields_param, cidade_id_param, estado_id_param, bairro_id_param, construtora_id_param, caracteristicas_id_param])
    def list(self, request):
        return super().list(request)
    
    
    # lancamento_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=True, example='11')
    construtora_id_param = openapi.Parameter('construtora_id', openapi.IN_FORM, description="Construtora ObjectID", type=openapi.TYPE_STRING, required=True, example='66e8b69a6402c25be75b23e2')
    caracteristicas_id_param = openapi.Parameter(
        'caracteristicas_id', 
        openapi.IN_FORM, 
        description="List of feature_id", 
        type=openapi.TYPE_ARRAY, 
        items=openapi.Items(type=openapi.TYPE_INTEGER), 
        required=True,
        example="[1,2,3]"
    )
    manual_parameters = [jwt_token_param, bairro_id_param, cidade_id_param, estado_id_param, caracteristicas_id_param, construtora_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Lancamento object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Lancamento object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Lancamento created',
                    400: 'Error while creating Lancamento', }, \
             operation_id='lancamentos_create',  operation_summary='Create a Lancamento register', tags=['lancamentos'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    #lancamento_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    construtora_id_param = openapi.Parameter('construtora_id', openapi.IN_FORM, description="Construtora ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    caracteristicas_id_param = openapi.Parameter(
        'caracteristicas_id', 
        openapi.IN_FORM, 
        description="List of feature_id", 
        type=openapi.TYPE_ARRAY, 
        items=openapi.Items(type=openapi.TYPE_INTEGER), 
        required=False,
        example="[1,2,3]"
    )
    nome_do_empreendimento_param = openapi.Parameter('nome_do_empreendimento', openapi.IN_FORM, description="Nome do Empreendimento", type=openapi.TYPE_STRING, required=False, example='Empreendimento X')
    estagio_de_obra_param = openapi.Parameter(
        'estagio_de_obra', 
        openapi.IN_FORM, 
        description="Estágio da Obra", 
        type=openapi.TYPE_STRING, 
        required=False, 
        enum=['Lançamento', 'Em obras', 'Pronto'], 
        example='Lançamento'
    )
    pais_param = openapi.Parameter('pais', openapi.IN_FORM, description="País", type=openapi.TYPE_STRING, required=False, example='Brasil')
    manual_parameters = [jwt_token_param, bairro_id_param, cidade_id_param, estado_id_param, caracteristicas_id_param, nome_do_empreendimento_param, estagio_de_obra_param, pais_param, construtora_id_param]
    @swagger_auto_schema(operation_description="""
            Update a Lancamento object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the Lancamento object updated as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Lancamento updated',
                    400: 'Error while updating Lancamento', }, \
             operation_id='lancamentos_update',  operation_summary='Update a Lancamento register', tags=['lancamentos'])        
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            context = {'request': request}    
            serializer = self.serializer_write_class(instance, context=context, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item2 => {e}")
            return Response({'message': f'Error updating item2 => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        
        
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado ID", type=openapi.TYPE_INTEGER, required=False, example='11')
    construtora_id_param = openapi.Parameter('construtora_id', openapi.IN_FORM, description="Construtora ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    caracteristicas_id_param = openapi.Parameter(
        'caracteristicas_id', 
        openapi.IN_FORM, 
        description="List of feature_id", 
        type=openapi.TYPE_ARRAY, 
        items=openapi.Items(type=openapi.TYPE_INTEGER), 
        required=False,
        example="[1,2,3]"
    )
    nome_do_empreendimento_param = openapi.Parameter('nome_do_empreendimento', openapi.IN_FORM, description="Nome do Empreendimento", type=openapi.TYPE_STRING, required=False, example='Empreendimento X')
    estagio_de_obra_param = openapi.Parameter(
        'estagio_de_obra', 
        openapi.IN_FORM, 
        description="Estágio da Obra", 
        type=openapi.TYPE_STRING, 
        required=False, 
        enum=['Lançamento', 'Em obras', 'Pronto'], 
        example='Lançamento'
    )
    pais_param = openapi.Parameter('pais', openapi.IN_FORM, description="País", type=openapi.TYPE_STRING, required=False, example='Brasil')
    manual_parameters = [jwt_token_param, bairro_id_param, cidade_id_param, estado_id_param, caracteristicas_id_param, nome_do_empreendimento_param, estagio_de_obra_param, pais_param, construtora_id_param]
    @swagger_auto_schema(operation_description="""
            Partial Update a Lancamento object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the Lancamento object updated as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Lancamento updated',
                    400: 'Error while updating Lancamento', }, \
             operation_id='lancamentos_partial_update',  operation_summary='Partial Update a Lancamento register', tags=['lancamentos'])    
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, context=context, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['get'], url_path='construtoras', url_name='construtoras', permission_classes=[AllowAny])
    def get_unique_construtoras(self, request):
        try:
            # Apply the same filtering logic as in list
            filtered_queryset = self.filter_queryset(self.get_queryset())
            
            # Extract distinct 'construtora_id' from the filtered queryset
            construtoras = [
                obj_id for obj_set in filtered_queryset.values_list('construtora_id', flat=True).distinct()
                if obj_set for obj_id in obj_set
            ]
            
            # Query Construtora model with these unique IDs
            serializer = ConstrutoraSerializer(Construtora.objects.filter(id__in=construtoras), many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'message': f'Error retrieving construtoras => {e}'}, status=status.HTTP_400_BAD_REQUEST)


class LancamentoImagemViewSet(CustomViewSet):
    model = LancamentoImagem
    queryset = model.objects.all()
    serializer_class = LancamentoImagemReadOnlySerializer
    serializer_write_class = LancamentoImagemWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    image_field = 'imagem'
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    lancamento_id_param = openapi.Parameter('lancamento_id__in', openapi.IN_QUERY, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [page_size_param, fields_param, lancamento_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)
    
    # lancamento_imagens_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=True, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [jwt_token_param, lancamento_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Lancamento Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Lancamento Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Lancamento Imagem created',
                    400: 'Error while creating Lancamento Imagem', }, \
             operation_id='lancamentos_imagens_create',  operation_summary='Create a Lancamento Imagem register', tags=['lancamentos-imagens'])
    def create(self, request):
        try:
            # Check if the request contains files
            if 'imagem' not in request.FILES:
                return Response({'message': 'No images provided'}, status=status.HTTP_400_BAD_REQUEST)
            
            context = {'request': request}

            serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # lancamento_imagens_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, lancamento_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Lancamento Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Lancamento Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Lancamento Imagem updated',
                    400: 'Error while updating Lancamento Imagem', }, \
             operation_id='lancamentos_imagens_update',  operation_summary='Update a Lancamento Imagem register', tags=['lancamentos-imagens'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            context = {'request': request}
                
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


    # lancamento_imagens_partial_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, lancamento_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Lancamento Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Lancamento Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Lancamento Imagem updated',
                    400: 'Error while updating Lancamento Imagem', }, \
             operation_id='lancamentos_imagens_partial_update',  operation_summary='Update a Lancamento Imagem register', tags=['lancamentos-imagens'])
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    
    #lancamentos-imagens_upload_multiple
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem files", type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_FILE), required=False)
    manual_parameters = [jwt_token_param, lancamento_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Create a new Lancamento Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Lancamento Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                request_body=LancamentoImagemUploadMultipleSerializer,\
                responses={
                    201: 'Lancamento Imagem created',
                    400: 'Error while creating Lancamento Imagem', }, \
             operation_id='lancamentos-imagens_upload_multiple',  operation_summary='Create a Lancamento Imagem register', tags=['lancamentos-imagens'])
    @action(detail=False, methods=['post'], parser_classes=[MultiPartParser, FormParser], url_path='upload-multiple')
    def upload_multiple(self, request):
        """
        Custom action to upload multiple images.
        """
        try:
            # Check if the request contains files
            if 'imagem' not in request.FILES:
                return Response({'message': 'No images provided'}, status=status.HTTP_400_BAD_REQUEST)
            
            # Extract the lancamento_id from request data
            lancamento_id = request.data.get('lancamento_id')
            if not lancamento_id:
                return Response({'message': 'Lancamento ID is required'}, status=status.HTTP_400_BAD_REQUEST)

            #logger.info(f'Uploading images for lancamento_id: {lancamento_id}')
            images = request.FILES.getlist('imagem')  # Get list of uploaded images
            #logger.info(f'Images: {images}')
            created_images = []
            not_created_images = []
            for image in images:
                # Reset the file pointer to the beginning
                image.seek(0)  # Reset the file pointer
                # Create a dictionary for each image
                image_data = {
                    'imagem': image,
                    'lancamento_id': lancamento_id,
                }
                #logger.info(f'Image data: {image_data}')

                # Create the serializer with each image's data
                serializer = self.serializer_write_class(data=image_data, context={'request': request, 'multiple': True})
                if serializer.is_valid():
                    #logger.info(f'Image data is valid')
                    serializer.save()
                    created_images.append({**serializer.data, 'id': str(serializer.data['id']), 'lancamento_id': lancamento_id, 'imagem':serializer.data['imagem'], 'created_by': str(list(serializer.data['created_by'])[0])})  # Add created image data to the list with id and lancamento_id as str
                else:
                    not_created_images.append({**image_data, 'errors': serializer.errors})
                    #return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

            # If all images were created successfully, return the response
            errors = {}
            if len(created_images) > 0:
                return Response({
                    'message': f'{len(created_images)} images successfully uploaded',
                    'errors': f'{len(not_created_images)} images failed to upload. {not_created_images}' if len(not_created_images) > 0 else None,
                    'results': created_images
                }, status=status.HTTP_201_CREATED)
            else:
                return Response({
                    'message': f'Error uploading images',
                    'results': not_created_images
                }, status=status.HTTP_400_BAD_REQUEST)
        
        except Exception as e:
            logger.error(f'Error uploading images => {e}')
            return Response({'message': f'Error uploading images => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    
# class LancamentoPlantaViewSet(CustomViewSet):
#     model = LancamentoPlanta
#     queryset = model.objects.all()
#     serializer_class = LancamentoPlantaReadOnlySerializer
#     serializer_write_class = LancamentoPlantaWriteOnlySerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = [] 
#     parser_classes = [MultiPartParser, FormParser]
#     image_field = 'imagem'
    
    
#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()

    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []  # No authentication required
#         return super().get_authentication_classes()
    
#     page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
#     fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
#     lancamento_id_param = openapi.Parameter('lancamento_id__in', openapi.IN_QUERY, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
#     manual_parameters = [page_size_param, fields_param, lancamento_id_param]
#     @swagger_auto_schema(manual_parameters=manual_parameters)
#     def list(self, request):
#         return super().list(request)
    
    
#     # lancamento_plantas_create
#     jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
#     lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=True, example='66e8b69a6402c25be75b23e2')
#     manual_parameters = [jwt_token_param, lancamento_id_param]
#     @swagger_auto_schema(operation_description="""
#             Create a new Lancamento Planta object.

#             Arguments:
#             request -- The HTTP request object.

#             Returns:
#             A Response object containing the created Lancamento Planta object as JSON.
#             """, manual_parameters=manual_parameters,\
#                 responses={
#                     201: 'Lancamento Planta created',
#                     400: 'Error while creating Lancamento Planta', }, \
#              operation_id='lancamentos_plantas_create',  operation_summary='Create a Lancamento Planta register', tags=['lancamentos-plantas'])
#     def create(self, request):
#         try:
#             context = {'request': request}

#             serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
#             if serializer.is_valid():
#                 serializer.save()
#                 serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
#                 filtered_data = self.apply_field_filters(serializer.data)
#                 return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
#             return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#         except Exception as e:
#             logger.error(f"Error creating item => {e}")
#             return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

#     # lancamento_plantas_update
#     jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
#     lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
#     imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
#     manual_parameters = [jwt_token_param, lancamento_id_param, imagem_param]
#     @swagger_auto_schema(operation_description="""
#             Update a Lancamento Planta object.

#             Arguments:
#             request -- The HTTP request object.

#             Returns:
#             A Response object containing the updated Lancamento Planta object as JSON.
#             """, manual_parameters=manual_parameters,\
#                 responses={
#                     201: 'Lancamento Planta updated',
#                     400: 'Error while updating Lancamento Planta', }, \
#              operation_id='lancamentos_plantas_update',  operation_summary='Update Lancamento Planta register', tags=['lancamentos-plantas'])
#     def update(self, request, pk=None):
#         ### method for updating a single item
#         try:
#             instance = self.queryset.get(id=ObjectId(pk)) 
#             context = {'request': request}
#             serializer = self.serializer_write_class(instance, data=request.data, context=context, partial=True)
#             if serializer.is_valid():
#                 serializer.save()
#                 serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
#                 filtered_data = self.apply_field_filters(serializer.data)
#                 return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
#             return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#         except Exception as e:
#             logger.error(f"Error updating item => {e}")
#             return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


#     # lancamento_plantas_partial_update
#     jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
#     lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
#     imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
#     manual_parameters = [jwt_token_param, lancamento_id_param, imagem_param]
#     @swagger_auto_schema(operation_description="""
#             Update a Lancamento Planta object.

#             Arguments:
#             request -- The HTTP request object.

#             Returns:
#             A Response object containing the updated Lancamento Planta object as JSON.
#             """, manual_parameters=manual_parameters,\
#                 responses={
#                     201: 'Lancamento Planta updated',
#                     400: 'Error while updating Lancamento Planta', }, \
#              operation_id='lancamentos_plantas_partial_update',  operation_summary='Update Lancamento Planta register', tags=['lancamentos-plantas'])
#     def partial_update(self, request, pk=None):
#         ### method for partially updating a single item
#         try:
#             instance = self.queryset.get(id=ObjectId(pk))
#             context = {'request': request}
#             serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
#             if serializer.is_valid():
#                 serializer.save()
#                 serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
#                 filtered_data = self.apply_field_filters(serializer.data)
#                 return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
#             return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#         except Exception as e:
#             logger.error(f"Error updating item => {e}")
#             return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        

class LancamentoPlantaViewSet(CustomViewSet):
    model = LancamentoPlanta
    queryset = model.objects.all()
    serializer_class = LancamentoPlantaReadOnlySerializer
    serializer_write_class = LancamentoPlantaWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()
    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    lancamento_id_param = openapi.Parameter('lancamento_id__in', openapi.IN_QUERY, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [page_size_param, fields_param, lancamento_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)
    

    # lancamentos_plantas_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lançamento id ObjectID", type=openapi.TYPE_STRING, required=True, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [jwt_token_param, lancamento_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Planta object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Planta object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta created',
                    400: 'Error while creating Planta', }, \
             operation_id='lancamentos_plantas_create',  operation_summary='Create a new Planta', tags=['lancamentos-plantas'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    # lancamentos_plantas_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lançamento id ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [jwt_token_param, lancamento_id_param]
    @swagger_auto_schema(operation_description="""
            Update a Planta object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Planta object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta updated',
                    400: 'Error while updating Planta', }, \
             operation_id='lancamentos_plantas_update',  operation_summary='Update a Planta', tags=['lancamentos-plantas'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            context = {'request': request}
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    # lancamentos_plantas_partial_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    lancamento_id_param = openapi.Parameter('lancamento_id', openapi.IN_FORM, description="Lançamento id ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [jwt_token_param, lancamento_id_param]
    @swagger_auto_schema(operation_description="""
            Update a Planta object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Planta object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta updated',
                    400: 'Error while updating Planta', }, \
             operation_id='lancamentos_plantas_partial_update',  operation_summary='Update a Planta', tags=['lancamentos-plantas'])
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            context = {'request': request}
            instance = self.queryset.get(id=ObjectId(pk))
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)


class LancamentoPlantaImagemViewSet(CustomViewSet):
    model = LancamentoPlantaImagem
    queryset = model.objects.all()
    serializer_class = LancamentoPlantaImagemReadOnlySerializer
    serializer_write_class = LancamentoPlantaImagemWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    image_field = 'imagem'
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()

    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    planta_id_param = openapi.Parameter('planta_id__in', openapi.IN_QUERY, description="Lancamento ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [page_size_param, fields_param, planta_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)


    # lancamentos_plantas_imagens_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    planta_id_param = openapi.Parameter('planta_id', openapi.IN_FORM, description="Planta ObjectID", type=openapi.TYPE_STRING, required=True, example='66e8b69a6402c25be75b23e2')
    manual_parameters = [jwt_token_param, planta_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Planta Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Planta Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta Imagem created',
                    400: 'Error while creating Planta Imagem', }, \
             operation_id='lancamentos_plantas_imagens_create',  operation_summary='Create a new Planta Imagem register', tags=['lancamentos-plantas-imagens'])
    def create(self, request):
        try:
            context = {'request': request}

            serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    # lancamentos_plantas_imagens_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    planta_id_param = openapi.Parameter('planta_id', openapi.IN_FORM, description="Planta ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, planta_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Planta Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Planta Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta Imagem updated',
                    400: 'Error while updating Planta Imagem', }, \
             operation_id='lancamentos_plantas_imagens_update',  operation_summary='Update Planta Imagem register', tags=['lancamentos-plantas-imagens'])
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)

    # lancamentos_plantas_imagens_partial_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    planta_id_param = openapi.Parameter('planta_id', openapi.IN_FORM, description="Planta ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem file", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [jwt_token_param, planta_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Update a Planta Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Planta Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Planta Imagem updated',
                    400: 'Error while updating Planta Imagem', }, \
             operation_id='lancamentos_plantas_imagens_partial_update',  operation_summary='Update Planta Imagem register', tags=['lancamentos-plantas-imagens'])
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        

    #lancamentos-imagens_upload_multiple
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    planta_id_param = openapi.Parameter('planta_id', openapi.IN_FORM, description="Planta ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Imagem files", type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_FILE), required=False)
    manual_parameters = [jwt_token_param, planta_id_param, imagem_param]
    @swagger_auto_schema(operation_description="""
            Create a new Planta Imagem object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Planta Imagem object as JSON.
            """, manual_parameters=manual_parameters,\
                request_body=LancamentoPlantaImagemUploadMultipleSerializer,\
                responses={
                    201: 'Planta Imagem created',
                    400: 'Error while creating Planta Imagem', }, \
             operation_id='lancamentos-plantas-imagens_upload_multiple',  operation_summary='Create a Planta Imagem register', tags=['lancamentos-plantas-imagens'])
    @action(detail=False, methods=['post'], parser_classes=[MultiPartParser, FormParser], url_path='upload-multiple')
    def upload_multiple(self, request):
        """
        Custom action to upload multiple images.
        """
        try:
            # Check if the request contains files
            if 'imagem' not in request.FILES:
                return Response({'message': 'No images provided'}, status=status.HTTP_400_BAD_REQUEST)
            
            # Extract the lancamento_id from request data
            planta_id = request.data.get('planta_id')
            if not planta_id:
                return Response({'message': 'Planta ID is required'}, status=status.HTTP_400_BAD_REQUEST)

            images = request.FILES.getlist('imagem')  # Get list of uploaded images
            created_images = []
            not_created_images = []
            for image in images:
                # Reset the file pointer to the beginning
                image.seek(0)  # Reset the file pointer
                # Create a dictionary for each image
                image_data = {
                    'imagem': image,
                    'planta_id': planta_id,
                }

                # Create the serializer with each image's data
                serializer = self.serializer_write_class(data=image_data, context={'request': request, 'multiple': True})
                if serializer.is_valid():
                    serializer.save()
                    created_images.append({**serializer.data, 'id': str(serializer.data['id']), 'planta_id': planta_id, 'imagem':serializer.data['imagem'], 'created_by': str(list(serializer.data['created_by'])[0])})  # Add created image data to the list with id and lancamento_id as str
                else:
                    not_created_images.append({**image_data, 'errors': serializer.errors})
                    #return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

            # If all images were created successfully, return the response
            errors = {}
            if len(created_images) > 0:
                return Response({
                    'message': f'{len(created_images)} images successfully uploaded',
                    'errors': f'{len(not_created_images)} images failed to upload. {not_created_images}' if len(not_created_images) > 0 else None,
                    'results': created_images
                }, status=status.HTTP_201_CREATED)
            else:
                return Response({
                    'message': f'Error uploading images',
                    'results': not_created_images
                }, status=status.HTTP_400_BAD_REQUEST)
        
        except Exception as e:
            logger.error(f'Error uploading images => {e}')
            return Response({'message': f'Error uploading images => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        
class LancamentoCaracteristicasViewSet(CustomViewSet):
    model = LancamentoCaracteristicas
    queryset = model.objects.all()
    serializer_class = LancamentoCaracteristicasSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []

    def get_permissions(self):
        return [AllowAny()]

    def get_authentication_classes(self):
        return []  # No authentication required
    




class AgenciaBannerViewSet(CustomViewSet):
    model = AgenciaBanner
    queryset = model.objects.all()
    serializer_class = AgenciasBannerReadOnlySerializer
    serializer_write_class = AgenciasBannerWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    image_field = 'imagem'
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    
    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    agencia_id_param = openapi.Parameter('agencia_id__in', openapi.IN_QUERY, description="Agencia Positive Integer ID", type=openapi.TYPE_STRING, required=False, example='1')
    manual_parameters = [page_size_param, fields_param, agencia_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)
    
    # banners_agencias_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    agencia_id_param = openapi.Parameter('agencia_id', openapi.IN_FORM, description="office_id from Offices", type=openapi.TYPE_INTEGER, required=True, example='1')
    manual_parameters = [jwt_token_param, agencia_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Banner Agencia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Banner Agencia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner Agencia created',
                    400: 'Error while creating Banner Agencia', }, \
             operation_id='banners_agencias_create',  operation_summary='Create a new Banner Agencia register', tags=['banners-agencias'],\
                 request_body=AgenciasBannerWriteOnlySerializer)
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
      
    # banners_agencias_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example="Bearer <access_token>")
    agencia_id_param = openapi.Parameter('agencia_id', openapi.IN_FORM, description="office_id from Offices", type=openapi.TYPE_INTEGER, example='1', required=False)
    link_param = openapi.Parameter('link', openapi.IN_FORM, description="Link to the banner", type=openapi.TYPE_STRING, example='https://www.google.com', required=False)
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Image file", type=openapi.TYPE_FILE, required=False) 
    nova_janela_param = openapi.Parameter('nova_janela', openapi.IN_FORM, description="Open link in a new tab", type=openapi.TYPE_BOOLEAN, required=False)         
    status_param = openapi.Parameter('status', openapi.IN_FORM, description="Banner status", type=openapi.TYPE_STRING, enum=["Ativo", "Inativo"], required=False)
    manual_parameters = [jwt_token_param, agencia_id_param, link_param, imagem_param, nova_janela_param, status_param]
    @swagger_auto_schema(operation_description="""
            Update a Banner Agencia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Banner Agencia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner Agencia updated',
                    400: 'Error while updating Banner Agencia' }, \
             operation_id='banners_agencias_update',  operation_summary='Update a Banner Agencia register', tags=['banners-agencias'],\
                 request_body=AgenciasBannerWriteOnlySerializer)        
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, context=context, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item2 => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    # banners_agencias_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example="Bearer <access_token>")
    agencia_id_param = openapi.Parameter('agencia_id', openapi.IN_FORM, description="office_id from Offices", type=openapi.TYPE_INTEGER, example='1', required=False)
    link_param = openapi.Parameter('link', openapi.IN_FORM, description="Link to the banner", type=openapi.TYPE_STRING, example='https://www.google.com', required=False)
    imagem_param = openapi.Parameter('imagem', openapi.IN_FORM, description="Image file", type=openapi.TYPE_FILE, required=False) 
    nova_janela_param = openapi.Parameter('nova_janela', openapi.IN_FORM, description="Open link in a new tab", type=openapi.TYPE_BOOLEAN, required=False)         
    status_param = openapi.Parameter('status', openapi.IN_FORM, description="Banner status", type=openapi.TYPE_STRING, enum=["Ativo", "Inativo"], required=False)
    manual_parameters = [jwt_token_param, agencia_id_param, link_param, imagem_param, nova_janela_param, status_param]
    @swagger_auto_schema(operation_description="""
            Update a Banner Agencia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Banner Agencia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner Agencia updated',
                    400: 'Error while updating Banner Agencia', }, \
             operation_id='banners_agencias_partial_update',  operation_summary='Update a Banner Agencia register', tags=['banners-agencias'],\
                 request_body=AgenciasBannerWriteOnlySerializer)
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, context=context, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)




class ContatoDiretoViewSet(CustomViewSet):
    model = ContatoDireto
    queryset = model.objects.all()
    serializer_class = ContatoDiretoReadOnlySerializer
    serializer_write_class = ContatoDiretoWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()
    
    def get_authentication_classes(self):
        if self.action in ['create']:
            return []
        return super().get_authentication_classes()
    
    # Methods not allowed
    @swagger_auto_schema(auto_schema=None)
    def update(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    @swagger_auto_schema(auto_schema=None)
    def partial_update(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    @swagger_auto_schema(auto_schema=None)
    def destroy(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters = [fields_param, jwt_token_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)
    
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    agent_id_param = openapi.Parameter('agent_id__in', openapi.IN_QUERY, description="Agent Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    office_id_param = openapi.Parameter('office_id__in', openapi.IN_QUERY, description="Office Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    cliente_id_param = openapi.Parameter('client_id__in', openapi.IN_QUERY, description="Client User ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imovel_id_param = openapi.Parameter('imovel_id__in', openapi.IN_QUERY, description="Property Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    manual_parameters = [page_size_param, jwt_token_param, fields_param, agent_id_param, office_id_param, cliente_id_param, imovel_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)
    

    agent_id_param = openapi.Parameter('agent_id', openapi.IN_FORM, description="Agent Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    office_id_param = openapi.Parameter('office_id', openapi.IN_FORM, description="Office Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    cliente_id_param = openapi.Parameter('cliente_id', openapi.IN_FORM, description="Cliente User Id ObjectID", type=openapi.TYPE_STRING, required=False, example='66e8b69a6402c25be75b23e2')
    imovel_id_param = openapi.Parameter('imovel_id', openapi.IN_FORM, description="Property Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    manual_parameters = [agent_id_param, office_id_param, cliente_id_param, imovel_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new ContatoDireto object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Unidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Contato created',
                    400: 'Error while creating Contato register', }, \
             operation_id='contatodireto_create',  operation_summary='Create a new Contato Register', tags=['contato-direto'],
                 request_body=ContatoDiretoWriteOnlySerializer)
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)





class AnuncieViewSet(CustomViewSet):
    model = Anuncie
    queryset = model.objects.all()
    serializer_class = AnuncieReadOnlySerializer
    serializer_write_class = AnuncieWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    
    def get_permissions(self):
        if self.action in ['create']:
            return [AllowAny()]
        return super().get_permissions()
    
    def get_authentication_classes(self):
        if self.action in ['create']:
            return []
        return super().get_authentication_classes()
    
    # Methods not allowed
    @swagger_auto_schema(auto_schema=None)
    def update(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    @swagger_auto_schema(auto_schema=None)
    def partial_update(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    @swagger_auto_schema(auto_schema=None)
    def destroy(self, request, pk=None):
        return Response({'message': 'Method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
    
    
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters = [fields_param, jwt_token_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)
    
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    office_id_param = openapi.Parameter('office_id__in', openapi.IN_QUERY, description="Office Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    bairro_id_param = openapi.Parameter('bairro_id__in', openapi.IN_QUERY, description="Bairro Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    cidade_id_param = openapi.Parameter('cidade_id__in', openapi.IN_QUERY, description="Cidade Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    estado_id_param = openapi.Parameter('estado_id__in', openapi.IN_QUERY, description="Estado Integer Id", type=openapi.TYPE_INTEGER, required=False, example='1')
    manual_parameters = [page_size_param, jwt_token_param, fields_param, office_id_param, bairro_id_param, cidade_id_param, estado_id_param]
    @swagger_auto_schema(manual_parameters=manual_parameters)
    def list(self, request):
        return super().list(request)
    

    office_id_param = openapi.Parameter('office_id', openapi.IN_FORM, description="Office Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    bairro_id_param = openapi.Parameter('bairro_id', openapi.IN_FORM, description="Bairro Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Cidade Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Estado Integer ID", type=openapi.TYPE_INTEGER, required=False, example='1')
    manual_parameters = [office_id_param, bairro_id_param, cidade_id_param, estado_id_param]
    @swagger_auto_schema(operation_description="""
            Create a new Anuncie object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Unidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Anuncie created',
                    400: 'Error while creating Anuncie register', }, \
             operation_id='anuncie_create',  operation_summary='Create a new Anuncie Register', tags=['anuncie'],
                 request_body=AnuncieWriteOnlySerializer)
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, partial=True, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



#######################################################################
##################### Documentation Views #############################
#######################################################################
from django.shortcuts import render
from django.contrib.admin.views.decorators import staff_member_required

@swagger_auto_schema(auto_schema=None)
@staff_member_required
def api_docs(request):
    return render(request, 'admin/api_docs.html')



#######################################################################
##################### EmailSettings View ##############################
#######################################################################

class EmailSettingsViewSet(CustomViewSet):
    model = EmailSettings
    queryset = model.objects.all()
    serializer_class = EmailSettingsSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    parser_classes = [MultiPartParser, FormParser]
    
    
    # def get_permissions(self):
    #     if self.action in ['list','create','retrieve','update','partial_update']:
    #         return [AllowAny()]
    #     return super().get_permissions()
    
    # def get_authentication_classes(self):
    #     if self.action in ['list','create','retrieve','update','partial_update']:
    #         return []
    #     return super().get_authentication_classes()
    
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    header_image_param = openapi.Parameter('header_image', openapi.IN_FORM, description="Header Image", type=openapi.TYPE_FILE, required=False)
    footer_image_param = openapi.Parameter('footer_image', openapi.IN_FORM, description="Footer Image", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [header_image_param, footer_image_param, jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Create a new EmailSetting object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Email Setting object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Email Setting created',
                    400: 'Error while creating Email Setting register', }, \
             operation_id='email-settings_create',  operation_summary='Create a new Email Settings', tags=['email-settings'],
             request_body=EmailSettingsSerializer)
    def create(self, request):
        # Only 1 register is acceptable
        if self.queryset.count() > 0:
            return Response({'message': 'Only one register is allowed'}, status=status.HTTP_400_BAD_REQUEST)
        return super().create(request)
    
    
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters = [jwt_token_param]
    @swagger_auto_schema(operation_description="""
            List EmailSetting object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Email Setting object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Email Setting listed',
                    400: 'Error while listing Email Setting register', }, \
             operation_id='email-settings_list',  operation_summary='List Email Settings', tags=['email-settings'])
    def list(self, request):
        return super().list(request)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters = [jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Retrieve EmailSetting object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Email Setting object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Email Setting Retrieved',
                    400: 'Error while retrieving Email Setting register', }, \
             operation_id='email-settings_retrieve',  operation_summary='Retrieve Email Settings object', tags=['email-settings'])
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    header_image_param = openapi.Parameter('header_image', openapi.IN_FORM, description="Header Image", type=openapi.TYPE_FILE, required=False)
    footer_image_param = openapi.Parameter('footer_image', openapi.IN_FORM, description="Footer Image", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [header_image_param, footer_image_param, jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a EmailSetting object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Email Setting object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Email Setting updated',
                    400: 'Error while updating Email Setting register', }, \
             operation_id='email-settings_update',  operation_summary='Update a Email Settings', tags=['email-settings'],
             request_body=EmailSettingsUpdateSerializer)
    def update(self, request, pk=None):
        return super().update(request, pk)


    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    header_image_param = openapi.Parameter('header_image', openapi.IN_FORM, description="Header Image", type=openapi.TYPE_FILE, required=False)
    footer_image_param = openapi.Parameter('footer_image', openapi.IN_FORM, description="Footer Image", type=openapi.TYPE_FILE, required=False)
    manual_parameters = [header_image_param, footer_image_param, jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Partial Update a EmailSetting object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Email Setting object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Email Setting partial updated',
                    400: 'Error while partial updating Email Setting register', }, \
             operation_id='email-settings_partial_update',  operation_summary='Partial Update a Email Settings', tags=['email-settings'],
             request_body=EmailSettingsUpdateSerializer)
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)






### BannerPublicidade ViewSet
class BannerPublicidadeViewSet(CustomViewSet):
    model = BannerPublicidade
    queryset = model.objects.all()
    serializer_class = BannerPublicidadeReadOnlySerializer
    serializer_write_class = BannerPublicidadeWriteOnlySerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = [] 
    parser_classes = [MultiPartParser, FormParser]
    image_field = 'logo'
    
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []  # No authentication required
        return super().get_authentication_classes()
    
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    cidade_id_param = openapi.Parameter('cidade_id__in', openapi.IN_QUERY, description="Comma-separated list of Cidade ObjectIDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4")
    estado_id_param = openapi.Parameter('estado_id__in', openapi.IN_QUERY, description="Comma-separated list of Estado ObjectIDs (uses `__in` lookup)", type=openapi.TYPE_STRING, required=False, example="668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4")
    manual_parameters=[page_size_param, fields_param, cidade_id_param, estado_id_param]
    @swagger_auto_schema(operation_description="""
            Banner Publicidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Banner Publicidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner listed',
                    400: 'Error while listing Banner register', }, \
             operation_id='banner-publicidade_list',  operation_summary='List Banner Publicidade', tags=['banner-publicidade'])
    def list(self, request):
        return super().list(request)
    
    
    # lancamento_create
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Comma-separated list of Cidade ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Comma-separated list of Estado ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    imagem_desktop_param = openapi.Parameter('imagem_desktop', openapi.IN_FORM, description="Desktop Image", type=openapi.TYPE_FILE, required=False)
    imagem_mobile_param = openapi.Parameter('imagem_mobile', openapi.IN_FORM, description="Mobile Image", type=openapi.TYPE_FILE, required=False)
    status_param = openapi.Parameter('status', openapi.IN_FORM, description="Banner status", type=openapi.TYPE_STRING, enum=["Ativo", "Inativo"], required=False)
    manual_parameters=[jwt_token_param, cidade_id_param, estado_id_param, imagem_desktop_param, imagem_mobile_param, status_param]
    @swagger_auto_schema(operation_description="""
            Create a new Lancamento object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Banner Publicidade object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner Publicidade created',
                    400: 'Error while creating Banner Publicidade', }, \
             operation_id='banner-publicidade_create',  operation_summary='Create a Banner Publicidade register', tags=['banner-publicidade'])
    def create(self, request):
        try:
            context = {'request': request}
            serializer = self.serializer_write_class(data=request.data, context=context)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(serializer.data['id'])))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item Successfully created!', 'results':filtered_data}, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error creating item => {e}")
            return Response({'message': f'Error creating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
    
    #lancamento_update
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Comma-separated list of Cidade ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Comma-separated list of Estado ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    imagem_desktop_param = openapi.Parameter('imagem_desktop', openapi.IN_FORM, description="Desktop Image", type=openapi.TYPE_FILE, required=False)
    imagem_mobile_param = openapi.Parameter('imagem_mobile', openapi.IN_FORM, description="Mobile Image", type=openapi.TYPE_FILE, required=False)
    status_param = openapi.Parameter('status', openapi.IN_FORM, description="Banner status", type=openapi.TYPE_STRING, enum=["Ativo", "Inativo"], required=False)
    manual_parameters=[jwt_token_param, page_size_param, fields_param, cidade_id_param, estado_id_param, imagem_desktop_param, imagem_mobile_param, status_param]
    @swagger_auto_schema(operation_description="""
            Update a Banner Publicidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the Banner Publicidade object updated as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Banner Publicidade updated',
                    400: 'Error while updating Banner Publicidade', }, \
             operation_id='banner-publicidade_update',  operation_summary='Update a Banner Publicidade register', tags=['banner-publicidade'])        
    def update(self, request, pk=None):
        ### method for updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk)) 
            context = {'request': request}    
            serializer = self.serializer_write_class(instance, context=context, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)
        
        
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    cidade_id_param = openapi.Parameter('cidade_id', openapi.IN_FORM, description="Comma-separated list of Cidade ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    estado_id_param = openapi.Parameter('estado_id', openapi.IN_FORM, description="Comma-separated list of Estado ObjectIDs", type=openapi.TYPE_STRING, required=False, example="[668ee131ef557b3dba0464a3,668ee131ef557b3dba0464a4]")
    imagem_desktop_param = openapi.Parameter('imagem_desktop', openapi.IN_FORM, description="Desktop Image", type=openapi.TYPE_FILE, required=False)
    imagem_mobile_param = openapi.Parameter('imagem_mobile', openapi.IN_FORM, description="Mobile Image", type=openapi.TYPE_FILE, required=False)
    status_param = openapi.Parameter('status', openapi.IN_FORM, description="Banner status", type=openapi.TYPE_STRING, enum=["Ativo", "Inativo"], required=False)
    manual_parameters=[jwt_token_param, page_size_param, fields_param, cidade_id_param, estado_id_param, imagem_desktop_param, imagem_mobile_param, status_param]
    @swagger_auto_schema(operation_description="""
            Partial Update a Banner Publicidade object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the Banner Publicidade object updated as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Banner Publicidade updated',
                    400: 'Error while updating Banner Publicidade', }, \
             operation_id='banner-publicidade_partial_update',  operation_summary='Update a Banner Publicidade register', tags=['banner-publicidade'])        
    def partial_update(self, request, pk=None):
        ### method for partially updating a single item
        try:
            instance = self.queryset.get(id=ObjectId(pk))
            context = {'request': request}
            serializer = self.serializer_write_class(instance, data=request.data, context=context, partial=True)
            if serializer.is_valid():
                serializer.save()
                serializer = self.serializer_class(self.queryset.get(id=ObjectId(instance.id)))
                filtered_data = self.apply_field_filters(serializer.data)
                return Response({'message':'Item successfully updated','results':filtered_data}, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            logger.error(f"Error updating item => {e}")
            return Response({'message': f'Error updating item => {e}'}, status=status.HTTP_400_BAD_REQUEST)



from rest_framework.views import APIView
import uuid
class FileUploadView(APIView):
    parser_classes = (MultiPartParser, FormParser)
    permission_classes = [IsAuthenticated, HasGroupOrPermission]
    authentication_classes = [JWTAuthentication]

    def post(self, request, *args, **kwargs):
        file = request.data.get('file')
        if file:
            folder_name = 'upload_test'
            foreign_id = uuid.uuid4()
            file_name = another_handle_upload_file(file=file, folder_name=folder_name, instance_id=uuid.uuid4(), multiple=True, foreign_id=foreign_id)
            if file_name:    
                return Response({"message": "File uploaded successfully.",
                            "file_name": file_name,
                            "foreign_id": foreign_id,
                            "folder_name": folder_name,
                            "MEDIA_URL": settings.MEDIA_URL,
                             "url": f"{settings.MEDIA_URL}{folder_name}/img/{foreign_id}/{file_name}"}, status=201)
            else:
                return Response({"error": "Error uploading file."}, status=400)
        return Response({"error": "File not provided."}, status=400)
    


# # Upload file handler
# def handle_uploaded_file(file, folder_name, instance_id=None, multiple=False, foreign_id=None):
#     try:
#         logger.info(f"Uploading file: {file.name}")
#         # Ensure the directory exists
#         if multiple==True and foreign_id:
#             directory = f'{folder_name.lower()}/img/{foreign_id}/'
#             logger.info(f"Directory: {directory}")
#         elif instance_id:
#             directory = f'{folder_name.lower()}/img/{instance_id}/'
#             logger.info(f"Directory: {directory}")
#         else:
#             directory = f'{folder_name.lower()}/img/'
#             logger.info(f"Directory: {directory}")
#         os.makedirs(directory, exist_ok=True)
        
#         # Change file name to avoid conflicts
#         file.name = f"{instance_id}{os.path.splitext(file.name)[1]}"
#         logger.info(f"File Name: {file.name}")
#         logger.info(f"File Size: {file.size}")
#         logger.info(f"File Content Type: {file.content_type}")
#         # print(f"File Name: {file.name}")
#         # print(f"File Size: {file.size}")
#         # print(f"File Content Type: {file.content_type}")

#         # Read the file content and reset the file pointer
#         file_content = file.read()
#         file.seek(0)  # Reset file pointer
        
#         path = os.path.join(directory, file.name)
#         logger.info(f"Path: {path}")
#         #print(f"Path: {path}")

#         file_path = default_storage.save(path, ContentFile(file_content))
#         logger.info(f"File saved at: {file_path}")
#         #print(f"File saved at: {file_path}")

#         return file_path
#     except Exception as e:
#         logger.error(f"Error uploading file: {e})")
        
        


### Testing another upload function
from django.core.files.uploadedfile import InMemoryUploadedFile
def another_handle_upload_file(file, folder_name, instance_id=None, multiple=False, foreign_id=None):
    
    # Check if the file is a memory upload file object
    if not isinstance(file, InMemoryUploadedFile):
        logger.error(f"File is not an InMemoryUploadedFile: {file}")
        print(f"File is not an InMemoryUploadedFile: {file}")
        return None

    try:
        # Change file name to avoid conflicts
        file.name = f"{instance_id}{os.path.splitext(file.name)[1]}"
        
        # Generate the save path for the file
        if multiple and foreign_id:
            save_path = os.path.join(settings.MEDIA_ROOT, folder_name, 'img', str(foreign_id), file.name)
        elif instance_id:
            save_path = os.path.join(settings.MEDIA_ROOT, folder_name, 'img', str(instance_id), file.name)
        else:
            save_path = os.path.join(settings.MEDIA_ROOT, folder_name, 'img', file.name)

        # Ensure the directory exists
        os.makedirs(os.path.dirname(save_path), exist_ok=True)

        # Save the file content
        with open(save_path, 'wb') as output_file:
            for chunk in file.chunks():
                output_file.write(chunk)

        #logger.info(f"File saved to {save_path}")
        #print(f"File saved to {save_path}")

        return file.name

    except Exception as e:
        logger.error(f"An error occurred during file handling: {e}")
        print(f"An error occurred during file handling: {e}")
        return None


"""
class QueryParams(models.Model):
	id = models.ObjectIdField(db_column='_id', primary_key=True, editable=False)
	user = models.ArrayReferenceField(to=Usuario, on_delete=models.CASCADE)
	query_params = models.JSONField()
	created_at = models.DateTimeField(auto_now_add=True, editable=False)
	updated_at = models.DateTimeField(auto_now=True, editable=False)
	
	objects = models.DjongoManager()
	
	class Meta:
		verbose_name = 'Query Params'
		verbose_name_plural = 'Query Params'
		app_label = 'panel'
"""

class QueryParamsUserViewSet(CustomViewSet):
    model = QueryParamsUser
    queryset = model.objects.all()
    serializer_class = QueryParamsUserSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
# from django_filters import FilterSet
# class QueryParamsFilter(FilterSet):
#     def __init__(self, *args, **kwargs):
#         super().__init__(*args, **kwargs)
#         if 'query_params' in self.data:
#             for key, value in self.data['query_params'].items():
#                 # Handle keys wrapped in brackets
#                 if key.startswith('[') and key.endswith(']'):
#                     key = key[1:-1]  # Remove brackets
                
#                 # Add a filter dynamically for the nested field
#                 self.filters[f'query_params__{key}'] = filters.CharFilter(
#                     field_name=f'query_params__{key}',
#                     lookup_expr=value if '__' in value else 'exact'
#                 )

#     class Meta:
#         model = QueryParamsGeneral
#         fields = []
        
# from django.db.models import Count
# from django.db.models.functions import Cast
# from django.db.models import CharField 
# class QueryParamsGeneralViewSet(CustomViewSet):
#     model = QueryParamsGeneral
#     queryset = model.objects.all()
#     serializer_class = QueryParamsGeneralSerializer
#     filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
#     search_fields='__all__'
#     ordering_fields = '__all__'
#     exclude_fields = []
    
#     def get_permissions(self):
#         if self.action in ['list', 'retrieve']:
#             return [AllowAny()]
#         return super().get_permissions()
    
#     def get_authentication_classes(self):
#         if self.action in ['list', 'retrieve']:
#             return []
#         return super().get_authentication_classes()

    
    
#     # list containing the distinct query_params and origin, with a count of each, ordered by count
#     @action(detail=False, methods=['get'], url_path='list-distinct', url_name='list-distinct', permission_classes=[AllowAny], authentication_classes=[])
#     def list_distinct(self, request):
#         try:
#             queryset = self.filter_queryset(self.get_queryset())
            
#             # Aggregate and count manually
#             data = {}
#             for obj in queryset:
#                 query_params = json.dumps(obj.query_params, sort_keys=True)  # Normalize keys
#                 key = (query_params, obj.origin)
#                 data[key] = data.get(key, 0) + 1
            
#             # Prepare the response
#             ranking_data = [
#                 {
#                     'query_params': json.loads(k[0]),
#                     'origin': k[1],
#                     'count': v
#                 }
                
#                 for k, v in data.items()
#             ]
            
#             ranking_data = sorted(ranking_data, key=lambda x: x['count'], reverse=True)
            
#             return Response({'results': ranking_data}, status=status.HTTP_200_OK)
#         except Exception as e:
#             logger.error(f"Error listing distinct query params: {e}")
#             return Response({'message': f'Error listing distinct query params => {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)


    
    
    
    # def get_permissions(self):
    #     if self.action in ['list','create','retrieve','update','partial_update','destroy']:
    #         return [AllowAny()]
    #     return super().get_permissions()
    
    # def get_authentication_classes(self):
    #     if self.action in ['list','create','retrieve','update','partial_update','destroy']:
    #         return []
    #     return super().get_authentication_classes()
    
    # jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    # manual_parameters = [jwt_token_param]
    # @swagger_auto_schema(manual_parameters=manual_parameters)
    # def list(self, request):
    #     return super().list(request)
    
    # @
    
    
    
#     db.panel_queryparamsgeneral.aggregate([
#   // Group by `origin` and `query_params`
#   {
#     $group: {
#       _id: {
#         origin: "$origin",
#         query_params: "$query_params"
#       },
#       count: { $sum: 1 }
#     }
#   },
#   // Project the output in the desired format
#   {
#     $project: {
#       _id: 0, // Remove the default _id
#       origin: "$_id.origin", 
#       query_params: "$_id.query_params", 
#       count: 1
#     }
#   },
#   // Optionally, you can sort the results by count (descending)
#   {
#     $sort: { count: -1 }
#   }
# ]);



class QueryParamsGeneralViewSet(CustomViewSet):
    model = QueryParamsGeneral
    queryset = model.objects.all()
    serializer_class = QueryParamsGeneralSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields = '__all__'
    ordering_fields = '__all__'
    exclude_fields = []

    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()

    # @action(detail=False, methods=['get'], url_path='list-distinct', url_name='list-distinct', permission_classes=[AllowAny], authentication_classes=[])
    # def list_distinct(self, request):
        
    #     try:
            
    #         # MongoDB aggregation pipeline
    #         pipeline = [
    #             {
    #                 "$group": {
    #                     "_id": {
    #                         "origin": "$origin",
    #                         "query_params": "$query_params"
    #                     },
    #                     "count": {"$sum": 1}
    #                 }
    #             },
    #             {
    #                 "$project": {
    #                     "_id": 0,
    #                     "origin": "$_id.origin",
    #                     "query_params": "$_id.query_params",
    #                     "count": 1
    #                 }
    #             },
    #             {
    #                 "$sort": {"count": -1}
    #             }
    #         ]

    #         # Execute the aggregation pipeline
    #         results = list(QueryParamsGeneral.objects.mongo_aggregate(pipeline))

    #         return Response({"results": results}, status=status.HTTP_200_OK)

    #     except Exception as e:
    #         logger.error(f"Error listing distinct query params: {e}")
    #         return Response({"message": f"Error listing distinct query params => {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)



    # @action(detail=False, methods=['get'], url_path='list-distinct', url_name='list-distinct', permission_classes=[AllowAny], authentication_classes=[])
    # def list_distinct(self, request):
    #     try:
    #         # Retrieve search parameters from query params
    #         origin_filter = request.query_params.get('origin', None)
    #         query_params_filters = {key: value for key, value in request.query_params.items() if key != 'origin'}
            
    #         # Define fields to exclude from the group statement
    #         excluded_fields = ['page_size', 'ordering', 'page','medias_limit']

    #         # Build the match stage for filtering
    #         match_stage = {}
    #         if origin_filter:
    #             match_stage['origin'] = origin_filter

    #         if query_params_filters:
    #             regex_filters = []
    #             for key, value in query_params_filters.items():
    #                 regex_key = f'query_params.{key}'  # Access nested fields
    #                 regex_filters.append({regex_key: {"$regex": value, "$options": "i"}})  # Case-insensitive regex

    #             if regex_filters:
    #                 match_stage['$and'] = regex_filters

    #         # MongoDB aggregation pipeline
    #         pipeline = []

    #         # Add the match stage if there are filters
    #         if match_stage:
    #             pipeline.append({"$match": match_stage})

    #         # Group by `origin` and `query_params`
    #         pipeline.extend([
    #             {
    #                 "$group": {
    #                     "_id": {
    #                         "origin": "$origin",
    #                         "query_params": "$query_params"
    #                     },
    #                     "count": {"$sum": 1}
    #                 }
    #             },
    #             {
    #                 "$project": {
    #                     "_id": 0,
    #                     "origin": "$_id.origin",
    #                     "query_params": "$_id.query_params",
    #                     "count": 1
    #                 }
    #             },
    #             {
    #                 "$sort": {"count": -1}
    #             }
    #         ])
            
    #         #print(f"Pipeline: {pipeline}")

    #         # Execute the aggregation pipeline
    #         results = list(QueryParamsGeneral.objects.mongo_aggregate(pipeline))

    #         return Response({"results": results}, status=status.HTTP_200_OK)

    #     except Exception as e:
    #         logger.error(f"Error listing distinct query params: {e}")
    #         return Response({"message": f"Error listing distinct query params => {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)
    
    
    @action(detail=False, methods=['get'], url_path='list-distinct', url_name='list-distinct', permission_classes=[AllowAny], authentication_classes=[])
    def list_distinct(self, request):
        try:
            # Retrieve search parameters from query params
            origin_filter = request.query_params.get('origin', None)
            query_params_filters = {key: value for key, value in request.query_params.items() if key != 'origin'}

            # Define fields to exclude from the group statement
            excluded_fields = ['page_size', 'ordering', 'page','medias_limit', 'fields']

            # Build the match stage for filtering
            match_stage = {}
            if origin_filter:
                match_stage['origin'] = origin_filter

            if query_params_filters:
                regex_filters = []
                for key, value in query_params_filters.items():
                    regex_key = f'query_params.{key}'  # Access nested fields
                    regex_filters.append({regex_key: {"$regex": value, "$options": "i"}})  # Case-insensitive regex

                if regex_filters:
                    match_stage['$and'] = regex_filters

            # MongoDB aggregation pipeline
            pipeline = []

            # Add the match stage if there are filters
            if match_stage:
                pipeline.append({"$match": match_stage})

            # Handle cases where query_params is either an array or an object
            pipeline.append({
                "$addFields": {
                    "normalized_query_params": {
                        "$cond": {
                            "if": {"$isArray": "$query_params"},  # Check if query_params is an array
                            "then": {
                                "$map": {
                                    "input": "$query_params",
                                    "as": "item",
                                    "in": {
                                        "$arrayToObject": {
                                            "$filter": {
                                                "input": {"$objectToArray": "$$item"},
                                                "as": "field",
                                                "cond": {"$not": {"$in": ["$$field.k", excluded_fields]}}
                                            }
                                        }
                                    }
                                }
                            },
                            "else": {
                                "$arrayToObject": {
                                    "$filter": {
                                        "input": {"$objectToArray": "$query_params"},
                                        "as": "field",
                                        "cond": {"$not": {"$in": ["$$field.k", excluded_fields]}}
                                    }
                                }
                            }
                        }
                    }
                }
            })

            # Group by `origin` and normalized `query_params`
            pipeline.extend([
                {
                    "$group": {
                        "_id": {
                            "origin": "$origin",
                            "query_params": "$normalized_query_params"
                        },
                        "count": {"$sum": 1}
                    }
                },
                {
                    "$project": {
                        "_id": 0,
                        "origin": "$_id.origin",
                        "query_params": "$_id.query_params",
                        "count": 1
                    }
                },
                {
                    "$sort": {"count": -1}
                }
            ])

            # Execute the aggregation pipeline
            results = list(QueryParamsGeneral.objects.mongo_aggregate(pipeline))

            return Response({"results": results}, status=status.HTTP_200_OK)

        except Exception as e:
            logger.error(f"Error listing distinct query params: {e}")
            return Response({"message": f"Error listing distinct query params => {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)




# class NossaHistoria(models.Model):
# 	"""
# 	NossaHistoria model represents the history of the organization with multilingual support.
# 	Attributes:
# 		id (ObjectIdField): Primary key, non-editable.
# 		ano (PositiveIntegerField): Year of the event.
# 		texto (TextField): Description of the event in Portuguese.
# 		titulo (CharField): Title of the event in Portuguese.
# 		texto_en (TextField): Description of the event in English.
# 		titulo_en (CharField): Title of the event in English.
# 		created_by (ArrayReferenceField): Reference to the user who created the record.
# 		updated_by (ArrayReferenceField): Reference to the user who last updated the record.
# 		created_at (DateTimeField): Timestamp when the record was created, non-editable.
# 		updated_at (DateTimeField): Timestamp when the record was last updated, non-editable.
# 	Meta:
# 		verbose_name (str): Human-readable singular name of the model.
# 		verbose_name_plural (str): Human-readable plural name of the model.
# 		app_label (str): Name of the app the model belongs to.
# 		ordering (list): Default ordering for the model.
# 	"""
    
# 	id = models.ObjectIdField(db_column='_id', primary_key=True, editable=False)
# 	ano = models.PositiveIntegerField()
# 	texto = models.TextField()
# 	titulo = models.CharField(max_length=255)
# 	texto_en = models.TextField()
# 	titulo_en = models.CharField(max_length=255)
# 	created_by = models.ArrayReferenceField(to=Usuario, on_delete=models.CASCADE, related_name='nossa_historia_created', db_column='created_by')
# 	updated_by = models.ArrayReferenceField(to=Usuario, on_delete=models.CASCADE, related_name='nossa_historia_updated', db_column='updated_by')
# 	created_at = models.DateTimeField(auto_now_add=True, editable=False)
# 	updated_at = models.DateTimeField(auto_now=True, editable=False)
	
# 	objects = models.DjongoManager()
	
# 	class Meta:
# 		verbose_name = 'Nossa História'
# 		verbose_name_plural = 'Nossa História'
# 		app_label = 'panel'
# 		ordering = ['ano']

# class NossaHistoriaSerializer(serializers.ModelSerializer):
    
#     created_by = UsuarioSimpleSerializer(many=True, read_only=True)
#     updated_by = UsuarioSimpleSerializer(many=True, read_only=True)
    
#     class Meta:
#         model = NossaHistoria
#         fields = '__all__'
#         extra_kwargs = {
#             'ano': {'required': True},
#             'texto': {'required': True},
#             'titulo': {'required': True},
#             'texto_en': {'required': True},
#             'titulo_en': {'required': True},
#             'created_by': {'required': False},
#             'updated_by': {'required': False},
#             'created_at': {'required': False},
#             'updated_at': {'required': False},
#         }


class NossaHistoriaViewSet(CustomViewSet):
    model=NossaHistoria
    queryset = model.objects.all()
    serializer_class = NossaHistoriaSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters=[page_size_param, fields_param]
    @swagger_auto_schema(operation_description="""
            Nossa Historia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Nossa Historia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Banner listed',
                    400: 'Error while listing Nossa Historia register', }, \
             operation_id='nossa-historia_list',  operation_summary='List Nossa Historia', tags=['nossa-historia'])
    def list(self, request):
        return super().list(request)
    
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Create a new Nossa Historia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Nossa Historia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Nossa Historia created',
                    400: 'Error while creating Nossa Historia', },
                request_body=NossaHistoriaSerializer,\
             operation_id='nossa-historia_create',  operation_summary='Create a Nossa Historia register', tags=['nossa-historia'])
    def create(self, request):
        return super().create(request)
   
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new Nossa Historia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Nossa Historia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Nossa Historia updated',
                    400: 'Error while updating Nossa Historia', },
                request_body=NossaHistoriaSerializer,\
             operation_id='nossa-historia_update',  operation_summary='Update a Nossa Historia register', tags=['nossa-historia'])
    def update(self, request, pk=None):
        return super().update(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new Nossa Historia object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Nossa Historia object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Nossa Historia updated',
                    400: 'Error while updating Nossa Historia', },
                request_body=NossaHistoriaSerializer,\
             operation_id='nossa-historia_update',  operation_summary='Update a Nossa Historia register', tags=['nossa-historia'])
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)
    
    



class PaginaViewSet(CustomViewSet):
    model=Pagina
    queryset = model.objects.all()
    serializer_class = PaginaSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    def get_permissions(self):
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters=[page_size_param, fields_param]
    @swagger_auto_schema(operation_description="""
            Pagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Pagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Pagina listed',
                    400: 'Error while listing Pagina register', }, \
             operation_id='paginas_list',  operation_summary='List Pagina', tags=['paginas'])
    def list(self, request):
        return super().list(request)
    
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Create a new Pagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created Pagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'Pagina created',
                    400: 'Error while creating Pagina', },
                request_body=PaginaSerializer,\
             operation_id='paginas_create',  operation_summary='Create a Pagina register', tags=['paginas'])
    def create(self, request):
        return super().create(request)
   
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new Pagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Pagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Pagina updated',
                    400: 'Error while updating Pagina', },
                request_body=PaginaSerializer,\
             operation_id='paginas_update',  operation_summary='Update a Pagina register', tags=['paginas'])
    def update(self, request, pk=None):
        return super().update(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new Pagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated Pagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'Pagina updated',
                    400: 'Error while updating Pagina', },
                request_body=PaginaSerializer,\
             operation_id='paginas_partial_update',  operation_summary='Update a Pagina register', tags=['paginas'])
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)
    
    


class SEOTagViewSet(CustomViewSet):
    model=SEOTag
    queryset = model.objects.all()
    serializer_class = SEOTagSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters=[page_size_param, fields_param]
    @swagger_auto_schema(operation_description="""
            SEOTag object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created SEOTag object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'SEOTag listed',
                    400: 'Error while listing SEOTag register', }, \
             operation_id='seo-tags_list',  operation_summary='List SEOTag', tags=['seo-tags'])
    def list(self, request):
        return super().list(request)
    
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Create a new SEOTag object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created SEOTag object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'SEOTag created',
                    400: 'Error while creating SEOTag', },
                request_body=SEOTagSerializer,\
             operation_id='seo-tags_create',  operation_summary='Create a SEOTag register', tags=['seo-tags'])
    def create(self, request):
        return super().create(request)
   
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new SEOTag object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated SEOTag object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'SEOTag updated',
                    400: 'Error while updating SEOTag', },
                request_body=SEOTagSerializer,\
             operation_id='seo-tags_update',  operation_summary='Update a SEOTag register', tags=['seo-tags'])
    def update(self, request, pk=None):
        return super().update(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new SEOTag object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated SEOTag object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'SEOTag updated',
                    400: 'Error while updating SEOTag', },
                request_body=SEOTagSerializer,\
             operation_id='seo-tags_partial_update',  operation_summary='Update a SEOTag register', tags=['seo-tags'])
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)
    


class SEOPaginaViewSet(CustomViewSet):
    model=SEOPagina
    queryset = model.objects.all()
    serializer_class = SEOPaginaSerializer
    filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields='__all__'
    ordering_fields = '__all__'
    exclude_fields = []
    
    def get_permissions(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return [AllowAny()]
        return super().get_permissions()

    def get_authentication_classes(self):
        #if self.action in ['list', 'retrieve']:
        if self.action in ['list', 'retrieve']:
            return []
        return super().get_authentication_classes()
    
    page_size_param = openapi.Parameter('page_size', openapi.IN_QUERY, description="Number of items per page", type=openapi.TYPE_INTEGER, required=False, example=10)
    fields_param = openapi.Parameter('fields', openapi.IN_QUERY, description="Comma-separated list of fields to include in the response", type=openapi.TYPE_STRING, required=False, example="id,nome,logo")
    manual_parameters=[page_size_param, fields_param]
    @swagger_auto_schema(operation_description="""
            SEOPagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created SEOPagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'SEOPagina listed',
                    400: 'Error while listing SEOPagina register', }, \
             operation_id='seo-paginas_list',  operation_summary='List SEOPagina', tags=['seo-paginas'])
    def list(self, request):
        return super().list(request)
    
    def retrieve(self, request, pk=None):
        return super().retrieve(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Create a new SEOPagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the created SEOPagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    201: 'SEOPagina created',
                    400: 'Error while creating SEOPagina', },
                request_body=SEOPaginaSerializer,\
             operation_id='seo-paginas_create',  operation_summary='Create a SEOPagina register', tags=['seo-paginas'])
    def create(self, request):
        return super().create(request)
   
    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new SEOPagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated SEOPagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'SEOPagina updated',
                    400: 'Error while updating SEOPagina', },
                request_body=SEOPaginaSerializer,\
             operation_id='seo-paginas_update',  operation_summary='Update a SEOPagina register', tags=['seo-paginas'])
    def update(self, request, pk=None):
        return super().update(request, pk)

    jwt_token_param = openapi.Parameter('Authorization', openapi.IN_HEADER, description="JWT Token", type=openapi.TYPE_STRING, required=True, example='Bearer $access_token')
    manual_parameters=[jwt_token_param]
    @swagger_auto_schema(operation_description="""
            Update a new SEOPagina object.

            Arguments:
            request -- The HTTP request object.

            Returns:
            A Response object containing the updated SEOPagina object as JSON.
            """, manual_parameters=manual_parameters,\
                responses={
                    200: 'SEOPagina updated',
                    400: 'Error while updating SEOPagina', },
                request_body=SEOPaginaSerializer,\
             operation_id='seo-paginas_partial_update',  operation_summary='Update a SEOPagina register', tags=['seo-paginas'])
    def partial_update(self, request, pk=None):
        return super().partial_update(request, pk)
    