from apps.product.pos.api.v1.serializers import product_serializers as product_serializers
from apps.pos_device.mixins.pos_device_mixin import POSDeviceMixin
from apps.core.mixins.search_mixin import DynamicSearchMixin
from rest_framework.exceptions import APIException
from apps.product import models as product_models
from apps.pos_device import models as pos_models
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework import viewsets
from rest_framework import status
from django.db import transaction


def trash(queryset, pk):  # noqa
    """ sent object to trash """
    obj = queryset.get(id=pk)
    obj.trash = True
    obj.save()


def delete(queryset, pk):
    """ full delete object """
    obj = queryset.get(id=pk)
    obj.delete()


class ProductViewSet(viewsets.ModelViewSet, DynamicSearchMixin, POSDeviceMixin):
    queryset = product_models.Product.objects.all()  # noqa
    serializer_class = product_serializers.ProductSerializer
    permission_classes = [AllowAny]
    search_fields = ['type', 'name']

    def list(self, request, *args, **kwargs):

        queryset = self.filter_query(self.get_queryset().order_by('-create_date'))  # noqa

        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(serializer.data)

    @action(
        methods=['put'],
        detail=True,
        url_path='trash',
        url_name='trash',
        name='trash',
    )
    @transaction.atomic
    def trash(self, request, pk=None):
        """ Sent product to trash """
        try:
            trash(self.queryset, pk)
        except APIException as e:
            return Response(e, status.HTTP_204_NO_CONTENT) 

    @action(
        methods=['post'],
        detail=True,
        url_name='delete',
        url_path='delete',
        name='delete'
    )
    @transaction.atomic
    def delete(self, request, pk=None):
        """ Full delete of product object """
        try:
            delete(self.queryset, pk)
            return Response(status=status.HTTP_200_OK)
        except APIException as e:
            return Response(e, status=status.HTTP_204_NO_CONTENT)


class POSFreeProductsViewSet(viewsets.ModelViewSet, DynamicSearchMixin, POSDeviceMixin):
    queryset = pos_models.POSFreeProducts.objects.all()
    serializer_class = product_serializers.POSFreeProductSerializer
    permission_classes = [AllowAny]
    search_fields = ['product__name', 'organization__name', 'device__serial']

    def list(self, request, *args, **kwargs):

        device = self.get_pos_device()

        queryset = self.filter_query(
            self.get_queryset().filter(device=device).order_by('-create_date')
        )  # noqa

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

    @transaction.atomic
    def create(self, request, *args, **kwargs):
        """ create my free product from pos & set details """

        organization = self.get_device_organization()
        device = self.get_pos_device()

        request.data.update({'organization': organization.id, 'device': device.id})

        serializer = product_serializers.POSFreeProductSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
