from django.core.cache import cache
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from core.Permission import ReadOnly
from product.models import Category, Product, ProductTree
from product.serializers import CategorySerializer, ProductSerializer, ProductTreeSerializer

CACHE_TTL = 60 * 5  # 5 dakika


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 12
    page_size_query_param = 'page_size'
    max_page_size = 100


class CategoryListView(generics.ListAPIView):
    permission_classes = [ReadOnly]
    serializer_class = CategorySerializer
    queryset = Category.objects.order_by('order').filter(is_active=True, parent__isnull=True).all()

    def get(self, request, *args, **kwargs):
        cache_key = 'product:categories:list'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        cache.set(cache_key, serializer.data, timeout=CACHE_TTL)
        return Response(serializer.data)


class CategoryRetrieveAPIView(generics.RetrieveAPIView):
    permission_classes = [ReadOnly]
    queryset = Category.objects.order_by('order').filter(is_active=True).all()
    serializer_class = CategorySerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        slug = self.kwargs.get('slug')
        cache_key = f'product:category:{slug}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        instance = self.get_object()
        serializer = self.get_serializer(instance)
        cache.set(cache_key, serializer.data, timeout=CACHE_TTL)
        return Response(serializer.data)


class ProductListAPIView(generics.ListAPIView):
    permission_classes = [ReadOnly]
    serializer_class = ProductSerializer
    queryset = Product.objects.filter(is_active=True).all()
    pagination_class = StandardResultsSetPagination

    def get(self, request, *args, **kwargs):
        # Sayfa numarasını al
        page = request.query_params.get('page', 1)
        cache_key = f'product:products:list:page:{page}'
        
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        queryset = self.get_queryset()
        
        # Sayfalama işlemini uygula
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # Sayfalanmış yanıtı al (count, next, previous, results yapısı)
            response = self.get_paginated_response(serializer.data)
            # Yanıtın verisini (data) cache'e kaydet
            cache.set(cache_key, response.data, timeout=CACHE_TTL)
            return response

        # Sayfalama yoksa normal döndür
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class FeaturedProductListAPIView(generics.ListAPIView):
    permission_classes = [ReadOnly]
    serializer_class = ProductSerializer
    queryset = Product.objects.filter(is_active=True, is_front=True).all()

    def get(self, request, *args, **kwargs):
        cache_key = 'product:products:featured'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        cache.set(cache_key, serializer.data, timeout=CACHE_TTL)
        return Response(serializer.data)


class ProductListTreeAPIView(generics.ListAPIView):
    permission_classes = [ReadOnly]
    serializer_class = ProductTreeSerializer
    queryset = ProductTree.objects.filter(is_active=True).all()[:3]

    def get(self, request, *args, **kwargs):
        cache_key = 'product:product_trees:list'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        cache.set(cache_key, serializer.data, timeout=CACHE_TTL)
        return Response(serializer.data)


class ProductRetrieveAPIView(generics.RetrieveAPIView):
    permission_classes = [ReadOnly]
    queryset = Product.objects.filter(is_active=True).all()
    serializer_class = ProductSerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        slug = self.kwargs.get('slug')
        cache_key = f'product:product:{slug}'
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data)

        instance = self.get_object()
        serializer = self.get_serializer(instance)
        cache.set(cache_key, serializer.data, timeout=CACHE_TTL)
        return Response(serializer.data)
