from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import viewsets, mixins, status
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated

from recipe.serializers import TagSerializer, IngredientSerializer, RecipeSerializer, RecipeDetailSerializer, RecipeImageSerializer
from core.models import Tag, Ingredients, recipe


# Create your views here.


class BaseViewsSetAttrs(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin):
	"""Base viewset class"""
	authentication_classes = (TokenAuthentication,)
	permission_classes = (IsAuthenticated,)


	def get_queryset(self):
		"""Returns objects to current authenticated user only"""
		assigned_only = self.request.query_params.get('assigned_only')
		queryset = self.queryset
		if assigned_only:
			queryset = queryset.filter(recipe__isnull=False)

		return queryset.filter(user=self.request.user).order_by('-name')


	def perform_create(self, serializer):
		"""Creates and saves it to the authenticated user"""
		serializer.save(user=self.request.user)



class TagViewSet(BaseViewsSetAttrs):
	"""Handles the queryset and serializer"""
	queryset = Tag.objects.all()
	serializer_class = TagSerializer



class IngredientViewSet(BaseViewsSetAttrs):
	"""Handles the queryset and serializer"""
	queryset = Ingredients.objects.all()
	serializer_class = IngredientSerializer



class RecipeViewSet(viewsets.ModelViewSet):
	"""Handles the queryset and serializer"""
	authentication_classes = (TokenAuthentication,)
	permission_classes = (IsAuthenticated,)
	serializer_class = RecipeSerializer
	queryset = recipe.objects.all()


	def _params_to_int(self, qs):
		"""converts list of string IDs into list of integers"""
		return [int(str_id) for str_id in qs.split(',')]

	def get_queryset(self):
		"""Returns recipe objects to current authenticated user only"""
		tags = self.request.query_params.get('tags')
		ingredients = self.request.query_params.get('ingredients')
		queryset = self.queryset
		if tags:
			tag_ids = self._params_to_int(tags)
			queryset = queryset.filter(tags__id__in=tag_ids)
		if ingredients:
			ingredient_ids = self._params_to_int(ingredients)
			queryset = queryset.filter(ingredients__id__in=ingredient_ids)

		return queryset.filter(user=self.request.user).order_by('-id')


	def get_serializer_class(self):
		"""Returns appropriate serializer class"""
		if self.action == 'retrieve':
			return RecipeDetailSerializer
		elif self.action == 'upload_image':
			return RecipeImageSerializer

		return self.serializer_class


	def perform_create(self, serializer):
		"""Creates recipe and saves it to the authenticated user"""
		serializer.save(user=self.request.user)


	@action(methods=['POST'], detail=True, url_path='upload-image')
	def upload_image(self, request, pk=None):
		"""Uploads image using valid serializer"""
		recipe = self.get_object()
		serializer = self.get_serializer(
			recipe,
			data=request.data
			)
		if serializer.is_valid():
			serializer.save()

			return Response(
				serializer.data,
				status=status.HTTP_200_OK
				)

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