from management.models.tag import GruppiTag
from management.models.utente import Utente
from management.repositories.gruppo import GruppoRepository
from management.serializers.gruppo_serializer import GruppoSerializer
from management.serializers.tag_serializer import GruppiTagSerializer

from .base import *


class GruppoAPIView(GenericViewSet):
    authentication_classes = [TokenAuthentication]
    _repository = GruppoRepository()

    @requires_auth(permission=[os.getenv('GESTORE'), os.getenv('INCARICATO')])
    def get_items(self, request: Request):
        try:
            args: FilterAndSorting = json.loads(request.body, object_hook=objJsonDecode)   
            filtered_set = self._repository.filtered(args)             
            serializer = GruppoSerializer(filtered_set, many=True)
            data = serializer.data
            return Response(data, status=status.HTTP_200_OK)

        except Exception as e:
            print(e)
            return Response({'detail': 'An error occurred.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    @requires_auth(permission=[os.getenv('GESTORE'), os.getenv('INCARICATO')])
    def get_list(self, request: Request):
        try:
            gruppi = Gruppo.objects.all()
            serializer = GruppoSerializer(gruppi, many=True)
            data = serializer.data

            return Response(data, status=status.HTTP_200_OK)

        except Exception as e:
            print(e)
            return Response({'detail': 'An error occurred.'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @requires_auth(permission=[os.getenv('GESTORE'), os.getenv('INCARICATO')])
    def save_item(self, request: Request):
        try:
            with transaction.atomic():
                dto = request.data.dict() if hasattr(request.data, 'dict') else dict(request.data)    

                tags = dto.pop('tags', [])

                status_result, group = self._repository.save(dto)

                if not status_result:
                    return Response(
                        {'detail': 'An error occurred.'},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR
                    )
                GruppiTag.objects.filter(
                    gruppo_id=group["id"]
                ).delete()

                GruppiTag.objects.bulk_create([
                    GruppiTag(
                        gruppo_id=group["id"],
                        tag_id=tag
                    )
                    for tag in tags
                ])

                return Response(group)

        except Exception as e:
            handle_exception(e)
            raise