from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
import base64
from datetime import datetime
from django.utils.dateparse import parse_datetime

from .models import Refund, Review
from .serializers import RefundCreatePublicSerializer, ReviewSerializerPublic
from .analytics import (
    SalesAnalytics, ProductAnalytics, CustomerAnalytics, 
    ShippingAnalytics, ReviewAnalytics, AnalyticsAggregator,
    get_predefined_date_ranges
)


from django.db import transaction, models
from rest_framework import viewsets, mixins, status
from rest_framework.permissions import AllowAny, IsAdminUser, SAFE_METHODS
from rest_framework.decorators import action
from rest_framework.response import Response
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiExample
from rest_framework import filters, permissions
from django_filters.rest_framework import DjangoFilterBackend

from account.permissions import AdminWriteOnlyOrReadOnly, AdminOnlyForPatchOtherwisePublic

from .models import (
	Order,
	OrderItem,
	Carrier,
	Payment,
	Product,
	DiscountCode,
	Category,
	ProductImage,
	Refund,
	Cart,
	CartItem,
	Wishlist,
)
from .serializers import (
	OrderReadSerializer,
	OrderMiniSerializer,
	OrderCreateSerializer,
	OrderItemReadSerializer,
	
	CarrierReadSerializer,
	PaymentReadSerializer,
	ProductSerializer,
	CategorySerializer,
	ProductImageSerializer,
	DiscountCodeSerializer,
	RefundSerializer,

	CartSerializer,
	CartItemSerializer,
	CartItemCreateSerializer,
	WishlistSerializer,
	WishlistProductActionSerializer,
)

#FIXME: uravit view na nový order serializer
@extend_schema_view(
	list=extend_schema(tags=["commerce", "public"], summary="List Orders (public - anonymous orders, authenticated - user orders, admin - all orders)"),
	retrieve=extend_schema(tags=["commerce", "public"], summary="Retrieve Order (public - anonymous orders, authenticated - user orders, admin - all orders)"),
	create=extend_schema(tags=["commerce", "public"], summary="Create Order (public)"),
)
class OrderViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
	queryset = Order.objects.select_related("carrier", "payment").prefetch_related(
		"items__product", "discount"
	).order_by("-created_at")
	permission_classes = [permissions.AllowAny]

	def get_permissions(self):
		"""Allow public order access (for anonymous orders) and creation, require auth for user orders"""
		if self.action in ['create', 'list', 'retrieve', 'mini', 'items', 'carrier_detail', 'payment_detail', 'verify_payment', 'download_invoice']:
			return [permissions.AllowAny()]
		return super().get_permissions()

	def get_queryset(self):
		"""Filter orders by user - admins see all, authenticated users see own orders, anonymous users see anonymous orders only"""
		queryset = super().get_queryset()
		
		# Admin users can see all orders
		if self.request.user.is_authenticated and getattr(self.request.user, 'role', None) == 'admin':
			return queryset
		
		# Authenticated users see only their own orders (both user-linked and email-matched anonymous orders)
		if self.request.user.is_authenticated:
			return queryset.filter(
				models.Q(user=self.request.user) | 
				models.Q(user__isnull=True, email=self.request.user.email)
			)
		
		# Anonymous users can only see anonymous orders (no user linked)
		return queryset.filter(user__isnull=True)

	def get_serializer_class(self):
		if self.action == "mini":
			return OrderMiniSerializer
		if self.action in ["list", "retrieve"]:
			return OrderReadSerializer
		if self.action == "create":
			return OrderCreateSerializer
		return OrderReadSerializer

	# Order creation is now handled by CreateModelMixin with proper serializer

	# -- List mini orders -- (public) --
	@action(detail=False, methods=["get"], url_path="detail")
	@extend_schema(
		tags=["commerce", "public"],
		summary="List mini orders (public - anonymous orders, authenticated - user orders)",
		responses={200: OrderMiniSerializer(many=True)},
	)
	def mini(self, request, *args, **kwargs):
		qs = self.get_queryset()  # Already filtered by user/anonymous status
		page = self.paginate_queryset(qs)
		
		if page is not None:
			ser = OrderMiniSerializer(page, many=True)
			return self.get_paginated_response(ser.data)
		
		ser = OrderMiniSerializer(qs, many=True)
		return Response(ser.data)

	# -- Get order items -- (public) --
	@action(detail=True, methods=["get"], url_path="items")
	@extend_schema(
		tags=["commerce", "public"],
		summary="List order items (public - anonymous orders, authenticated - user orders)",
		responses={200: OrderItemReadSerializer(many=True)},
	)
	def items(self, request, pk=None):
		order = self.get_object()  # get_object respects get_queryset filtering
		qs = order.items.select_related("product").all()
		ser = OrderItemReadSerializer(qs, many=True)
		return Response(ser.data)

	# -- Get order carrier -- (public) --
	@action(detail=True, methods=["get"], url_path="carrier")
	@extend_schema(
		tags=["commerce", "public"],
		summary="Get order carrier (public - anonymous orders, authenticated - user orders)",
		responses={200: CarrierReadSerializer},
	)
	def carrier_detail(self, request, pk=None):
		order = self.get_object()  # get_object respects get_queryset filtering
		ser = CarrierReadSerializer(order.carrier)
		return Response(ser.data)

	# -- Get order payment -- (public) --
	@action(detail=True, methods=["get"], url_path="payment")
	@extend_schema(
		tags=["commerce", "public"],
		summary="Get order payment (public - anonymous orders, authenticated - user orders)",
		responses={200: PaymentReadSerializer},
	)
	def payment_detail(self, request, pk=None):
		order = self.get_object()  # get_object respects get_queryset filtering
		ser = PaymentReadSerializer(order.payment)
		return Response(ser.data)

	# -- Mark carrier ready to pickup(store) (admin) --
	@action(
		detail=True,
		methods=["patch"],
		url_path="carrier/ready-to-pickup",
		permission_classes=[IsAdminUser],
	)
	@extend_schema(
		tags=["commerce"],
		summary="Mark carrier ready to pickup (admin)",
		request=None,
		responses={200: CarrierReadSerializer},
	)
	def carrier_ready_to_pickup(self, request, pk=None):
		order = self.get_object()
		if not order.carrier:
			return Response({"detail": "Carrier not set."}, status=400)
		order.carrier.ready_to_pickup()
		order.carrier.refresh_from_db()
		ser = CarrierReadSerializer(order.carrier)
		return Response(ser.data)

	# -- Start ordering shipping (admin) --
	@action(
		detail=True,
		methods=["patch"],
		url_path="carrier/start-ordering-shipping",
		permission_classes=[IsAdminUser],
	)
	@extend_schema(
		tags=["commerce"],
		summary="Start ordering shipping (admin)",
		request=None,
		responses={200: CarrierReadSerializer},
	)
	def carrier_start_ordering_shipping(self, request, pk=None):
		order = self.get_object()
		if not order.carrier:
			return Response({"detail": "Carrier not set."}, status=400)
		order.carrier.start_ordering_shipping()
		order.carrier.refresh_from_db()
		ser = CarrierReadSerializer(order.carrier)
		return Response(ser.data)


	# -- Cancel order (authenticated) --
	@action(detail=True, methods=['post'], permission_classes=[permissions.IsAuthenticated])
	@extend_schema(
		tags=["commerce"],
		summary="Cancel order (authenticated user)",
		responses={200: {"type": "object", "properties": {"status": {"type": "string"}}}},
	)
	def cancel(self, request, pk=None):
		order = self.get_object()  # get_object respects get_queryset filtering
		
		# Can only cancel if not shipped
		if order.carrier and order.carrier.state != Carrier.STATE.PREPARING:
			return Response({'detail': 'Cannot cancel shipped order'}, status=400)
		
		order.status = Order.OrderStatus.CANCELLED
		order.save()
		
		# Restore stock
		for item in order.items.all():
			item.product.stock += item.quantity
			item.product.save()
		
		return Response({'status': 'cancelled'})

	# -- Verify payment (public) --
	@action(detail=True, methods=['post'], url_path='payment/verify')
	@extend_schema(
		tags=["commerce", "public"],
		summary="Verify payment status (public)",
		responses={200: {"type": "object", "properties": {
			"order_id": {"type": "integer"},
			"payment_status": {"type": "string"}
		}}},
	)
	def verify_payment(self, request, pk=None):
		order = self.get_object()
		if order.payment and order.payment.payment_method == Payment.PAYMENT.STRIPE:
			if order.payment.stripe:
				return Response({
					'order_id': order.id,
					'payment_status': order.payment.stripe.status
				})
		return Response({
			'order_id': order.id,
			'payment_status': 'unknown'
		})

	# -- Download invoice (public) --
	@action(detail=True, methods=['get'], url_path='invoice')
	@extend_schema(
		tags=["commerce", "public"],
		summary="Download invoice PDF (public)",
		responses={200: "PDF File"},
	)
	def download_invoice(self, request, pk=None):
		from django.http import FileResponse
		order = self.get_object()
		if not order.invoice or not order.invoice.pdf_file:
			return Response({'detail': 'Invoice not available'}, status=404)
		
		return FileResponse(
			order.invoice.pdf_file.open('rb'),
			content_type='application/pdf',
			as_attachment=True,
			filename=f'invoice_{order.invoice.invoice_number}.pdf'
		)

	# retrieve method removed - get_queryset handles filtering automatically


# ---------- Public/admin viewsets ----------

@extend_schema_view(
	list=extend_schema(tags=["commerce", "public"], summary="List products (public)"),
	retrieve=extend_schema(tags=["commerce", "public"], summary="Retrieve product (public)"),
	create=extend_schema(tags=["commerce"], summary="Create product (auth required)"),
	partial_update=extend_schema(tags=["commerce"], summary="Update product (auth required)"),
	update=extend_schema(tags=["commerce"], summary="Replace product (auth required)"),
	destroy=extend_schema(tags=["commerce"], summary="Delete product (auth required)"),
)
class ProductViewSet(viewsets.ModelViewSet):
	queryset = Product.objects.all()
	serializer_class = ProductSerializer
	permission_classes = [permissions.IsAuthenticatedOrReadOnly]
	filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
	filterset_fields = ['category', 'is_active', 'stock', 'price', 'created_at', 'updated_at', 'limited_to']
	search_fields = ["name", "code", "description"]
	ordering_fields = ["price", "name", "created_at", "updated_at", "stock"]
	ordering = ["price"]

	@action(detail=True, methods=['get'], url_path='availability')
	@extend_schema(
		tags=["commerce", "public"],
		summary="Check product availability (public)",
		responses={200: {"type": "object", "properties": {
			"product_id": {"type": "integer"},
			"available": {"type": "boolean"},
			"stock": {"type": "integer"},
			"is_active": {"type": "boolean"}
		}}},
	)
	def check_availability(self, request, pk=None):
		product = self.get_object()
		return Response({
			'product_id': product.id,
			'available': product.available,
			'stock': product.stock,
			'is_active': product.is_active
		})

	@action(detail=True, methods=['get'], url_path='rating')
	@extend_schema(
		tags=["commerce", "public"],
		summary="Get product rating summary (public)",
		responses={200: {"type": "object", "properties": {
			"product_id": {"type": "integer"},
			"average_rating": {"type": "number"},
			"review_count": {"type": "integer"}
		}}},
	)
	def rating_summary(self, request, pk=None):
		from django.db.models import Avg, Count
		product = self.get_object()
		stats = product.reviews.aggregate(
			average=Avg('rating'),
			count=Count('id')
		)
		return Response({
			'product_id': product.id,
			'average_rating': round(stats['average'], 2) if stats['average'] else 0,
			'review_count': stats['count']
		})


@extend_schema_view(
	list=extend_schema(tags=["commerce", "public"], summary="List categories (public)"),
	retrieve=extend_schema(tags=["commerce", "public"], summary="Retrieve category (public)"),
	create=extend_schema(tags=["commerce"], summary="Create category (auth required)"),
	partial_update=extend_schema(tags=["commerce"], summary="Update category (auth required)"),
	update=extend_schema(tags=["commerce"], summary="Replace category (auth required)"),
	destroy=extend_schema(tags=["commerce"], summary="Delete category (auth required)"),
)
class CategoryViewSet(viewsets.ModelViewSet):
	queryset = Category.objects.all()
	serializer_class = CategorySerializer
	permission_classes = [permissions.IsAuthenticatedOrReadOnly]
	filter_backends = [filters.SearchFilter, filters.OrderingFilter]
	search_fields = ["name", "description"]
	ordering_fields = ["name", "id"]
	ordering = ["name"]


@extend_schema_view(
	list=extend_schema(tags=["commerce", "public"], summary="List product images (public)"),
	retrieve=extend_schema(tags=["commerce", "public"], summary="Retrieve product image (public)"),
	create=extend_schema(tags=["commerce"], summary="Create product image (auth required)"),
	partial_update=extend_schema(tags=["commerce"], summary="Update product image (auth required)"),
	update=extend_schema(tags=["commerce"], summary="Replace product image (auth required)"),
	destroy=extend_schema(tags=["commerce"], summary="Delete product image (auth required)"),
)
class ProductImageViewSet(viewsets.ModelViewSet):
	queryset = ProductImage.objects.all()
	serializer_class = ProductImageSerializer
	permission_classes = [permissions.IsAuthenticatedOrReadOnly]
	filter_backends = [filters.SearchFilter, filters.OrderingFilter]
	search_fields = ["alt_text", "product__name"]
	ordering_fields = ["id", "product__name"]
	ordering = ["-id"]


@extend_schema_view(
	list=extend_schema(tags=["commerce", "public"], summary="List discount codes (public)"),
	retrieve=extend_schema(tags=["commerce", "public"], summary="Retrieve discount code (public)"),
	create=extend_schema(tags=["commerce"], summary="Create discount code (auth required)"),
	partial_update=extend_schema(tags=["commerce"], summary="Update discount code (auth required)"),
	update=extend_schema(tags=["commerce"], summary="Replace discount code (auth required)"),
	destroy=extend_schema(tags=["commerce"], summary="Delete discount code (auth required)"),
)
class DiscountCodeViewSet(viewsets.ModelViewSet):
	queryset = DiscountCode.objects.all()
	serializer_class = DiscountCodeSerializer
	permission_classes = [permissions.IsAuthenticatedOrReadOnly]
	filter_backends = [filters.SearchFilter, filters.OrderingFilter]
	search_fields = ["code", "description"]
	ordering_fields = ["percent", "amount", "valid_from", "valid_to"]
	ordering = ["-valid_from"]


# -- Refund (Admin only) --
@extend_schema_view(
	list=extend_schema(tags=["commerce"], summary="List refunds (admin)"),
	retrieve=extend_schema(tags=["commerce"], summary="Retrieve refund (admin)"),
	create=extend_schema(tags=["commerce"], summary="Create refund (admin)"),
	partial_update=extend_schema(tags=["commerce"], summary="Update refund (admin)"),
	update=extend_schema(tags=["commerce"], summary="Replace refund (admin)"),
	destroy=extend_schema(tags=["commerce"], summary="Delete refund (admin)"),
)
class RefundViewSet(viewsets.ModelViewSet):
	queryset = Refund.objects.select_related("order").all().order_by("-created_at")
	serializer_class = RefundSerializer
	permission_classes = [IsAdminUser]





class RefundPublicView(APIView):
	"""Public endpoint to create and fetch refund objects.

	POST: Create a refund given email and invoice_number or order_id.
		  Returns JSON with refund info, order items, and a base64 PDF payload.
	GET:  Return a refund object by id (query param `id`).
	"""

	permission_classes = [AllowAny]

	def get(self, request):
		rid = request.query_params.get("id")
		if not rid:
			return Response({"detail": "Missing 'id' query parameter."}, status=status.HTTP_400_BAD_REQUEST)
		try:
			refund = Refund.objects.select_related("order").get(id=rid)
		except Refund.DoesNotExist:
			return Response({"detail": "Refund not found."}, status=status.HTTP_404_NOT_FOUND)

		order = refund.order
		items = []
		for it in order.items.select_related('product').all():
			items.append({
				"product_name": getattr(it.product, "name", "Item"),
				"sku": getattr(it.product, "code", None),
				"quantity": it.quantity,
			})

		data = {
			"refund": {
				"id": refund.id,
				"order_id": order.id,
				"reason_choice": refund.reason_choice,
				"reason_text": refund.reason_text,
				"verified": refund.verified,
				"created_at": refund.created_at,
			},
			"order": {
				"id": order.id,
				"email": order.email,
				"created_at": order.created_at,
				"items": items,
			},
		}
		return Response(data)

	def post(self, request):
		serializer = RefundCreatePublicSerializer(data=request.data)
		if not serializer.is_valid():
			return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

		refund = serializer.save()
		order = refund.order

		# Build items list for response
		items = []
		for it in order.items.select_related('product').all():
			items.append({
				"product_name": getattr(it.product, "name", "Item"),
				"sku": getattr(it.product, "code", None),
				"quantity": it.quantity,
			})

		# Generate PDF bytes using model helper
		pdf_bytes = refund.generate_refund_pdf_for_customer()
		pdf_b64 = base64.b64encode(pdf_bytes).decode('ascii')

		resp = {
			"refund": {
				"id": refund.id,
				"order_id": order.id,
				"reason_choice": refund.reason_choice,
				"reason_text": refund.reason_text,
				"verified": refund.verified,
				"created_at": refund.created_at,
			},
			"order": {
				"id": order.id,
				"email": order.email,
				"created_at": order.created_at,
				"items": items,
			},
			"pdf": {
				"filename": f"refund_{refund.id}.pdf",
				"content_type": "application/pdf",
				"base64": pdf_b64,
			},
		}
		return Response(resp, status=status.HTTP_201_CREATED)
	

class ReviewPostPublicView(APIView):
	"""Public endpoint to create a review for a product."""

	permission_classes = [permissions.IsAuthenticated]

	@extend_schema(
		tags=["commerce", "public"],
		summary="Create a product review (public)",
		request=ReviewSerializerPublic,
		responses={201: ReviewSerializerPublic},
	)
	def post(self, request):
		serializer = ReviewSerializerPublic(data=request.data)
		if not serializer.is_valid():
			return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
		
		review = serializer.save()
		out = ReviewSerializerPublic(review)
		return Response(out.data, status=status.HTTP_201_CREATED)


# readonly public reviews, admin can patch
class ReviewPublicViewSet(viewsets.ModelViewSet):
	queryset = Review.objects.all()
	serializer_class = ReviewSerializerPublic
	permission_classes = [AdminOnlyForPatchOtherwisePublic]
	filter_backends = [filters.SearchFilter, filters.OrderingFilter]
	search_fields = ["product__name", "user__username", "comment"]
	ordering_fields = ["rating", "created_at"]
	ordering = ["-created_at"]

	def get_queryset(self):
		"""Filter reviews - admins see all, users see all reviews but can only modify their own"""
		queryset = super().get_queryset()
		
		# Admin users can see and modify all reviews
		if self.request.user.is_authenticated and getattr(self.request.user, 'role', None) == 'admin':
			return queryset
		
		# For modification actions, users can only modify their own reviews
		if self.action in ['update', 'partial_update', 'destroy']:
			if self.request.user.is_authenticated:
				return queryset.filter(user=self.request.user)
			return queryset.none()
		
		# For viewing, everyone can see all reviews (they're public)
		return queryset

	@action(detail=False, methods=['get'], url_path='product/(?P<product_id>[^/.]+)')
	@extend_schema(
		tags=["commerce", "public"],
		summary="Get reviews for specific product (public)",
		responses={200: ReviewSerializerPublic(many=True)},
	)
	def by_product(self, request, product_id=None):
		reviews = self.get_queryset().filter(product_id=product_id)
		page = self.paginate_queryset(reviews)
		if page:
			serializer = self.get_serializer(page, many=True)
			return self.get_paginated_response(serializer.data)
		serializer = self.get_serializer(reviews, many=True)
		return Response(serializer.data)


# ---------- CART MANAGEMENT ----------

@extend_schema_view(
	list=extend_schema(tags=["commerce", "cart"], summary="Get current cart (public)"),
	retrieve=extend_schema(tags=["commerce", "cart"], summary="Get cart by ID (public)"),
)
class CartViewSet(viewsets.GenericViewSet):
	"""
	Shopping cart management for authenticated and anonymous users.
	Anonymous users use session_key, authenticated users use their user account.
	"""
	queryset = Cart.objects.prefetch_related('items__product')
	serializer_class = CartSerializer
	permission_classes = [AllowAny]

	def get_queryset(self):
		"""Filter carts by user/session - users only see their own cart"""
		queryset = super().get_queryset()
		
		# Admin users can see all carts
		if self.request.user.is_authenticated and getattr(self.request.user, 'role', None) == 'admin':
			return queryset
		
		# Authenticated users see only their cart
		if self.request.user.is_authenticated:
			return queryset.filter(user=self.request.user)
		
		# Anonymous users see only their session cart
		session_key = self.request.session.session_key
		if session_key:
			return queryset.filter(session_key=session_key, user__isnull=True)
		return queryset.none()

	def get_or_create_cart(self, request):
		"""Get or create cart for current user/session"""
		if request.user.is_authenticated:
			cart, _ = Cart.objects.get_or_create(user=request.user)
		else:
			# Use session for anonymous users
			session_key = request.session.session_key
			if not session_key:
				request.session.create()
				session_key = request.session.session_key
			cart, _ = Cart.objects.get_or_create(session_key=session_key)
		return cart

	@action(detail=False, methods=['get'], url_path='current')
	@extend_schema(
		tags=["commerce", "cart"],
		summary="Get current user's cart",
		responses={200: CartSerializer},
	)
	def current(self, request):
		"""Get the current user's cart"""
		cart = self.get_or_create_cart(request)
		serializer = CartSerializer(cart)
		return Response(serializer.data)

	@action(detail=False, methods=['post'], url_path='add')
	@extend_schema(
		tags=["commerce", "cart"],
		summary="Add item to cart",
		request=CartItemCreateSerializer,
		responses={200: CartSerializer},
	)
	def add_item(self, request):
		"""Add a product to the cart or update quantity if already exists"""
		serializer = CartItemCreateSerializer(data=request.data)
		serializer.is_valid(raise_exception=True)

		cart = self.get_or_create_cart(request)
		product_id = serializer.validated_data['product_id']
		quantity = serializer.validated_data['quantity']

		product = Product.objects.get(pk=product_id)

		# Check if item already in cart
		cart_item, created = CartItem.objects.get_or_create(
			cart=cart,
			product=product,
			defaults={'quantity': quantity}
		)

		if not created:
			# Update quantity if item already exists
			cart_item.quantity += quantity
			cart_item.save()

		cart.refresh_from_db()
		return Response(CartSerializer(cart).data)

	@action(detail=False, methods=['patch'], url_path='items/(?P<item_id>[^/.]+)')
	@extend_schema(
		tags=["commerce", "cart"],
		summary="Update cart item quantity",
		request={"type": "object", "properties": {"quantity": {"type": "integer"}}},
		responses={200: CartSerializer},
	)
	def update_item(self, request, item_id=None):
		"""Update quantity of a cart item"""
		cart = self.get_or_create_cart(request)
		
		try:
			cart_item = CartItem.objects.get(pk=item_id, cart=cart)
		except CartItem.DoesNotExist:
			return Response({'detail': 'Cart item not found'}, status=404)

		quantity = request.data.get('quantity')
		if quantity is None:
			return Response({'detail': 'Quantity is required'}, status=400)

		try:
			quantity = int(quantity)
			if quantity < 1:
				return Response({'detail': 'Quantity must be at least 1'}, status=400)
		except ValueError:
			return Response({'detail': 'Invalid quantity'}, status=400)

		cart_item.quantity = quantity
		cart_item.save()

		cart.refresh_from_db()
		return Response(CartSerializer(cart).data)

	@action(detail=False, methods=['delete'], url_path='items/(?P<item_id>[^/.]+)')
	@extend_schema(
		tags=["commerce", "cart"],
		summary="Remove item from cart",
		responses={200: CartSerializer},
	)
	def remove_item(self, request, item_id=None):
		"""Remove an item from the cart"""
		cart = self.get_or_create_cart(request)
		
		try:
			cart_item = CartItem.objects.get(pk=item_id, cart=cart)
			cart_item.delete()
		except CartItem.DoesNotExist:
			return Response({'detail': 'Cart item not found'}, status=404)

		cart.refresh_from_db()
		return Response(CartSerializer(cart).data)

	@action(detail=False, methods=['post'], url_path='clear')
	@extend_schema(
		tags=["commerce", "cart"],
		summary="Clear all items from cart",
		responses={200: CartSerializer},
	)
	def clear(self, request):
		"""Remove all items from the cart"""
		cart = self.get_or_create_cart(request)
		cart.items.all().delete()
		cart.refresh_from_db()
		return Response(CartSerializer(cart).data)


# ---------- WISHLIST MANAGEMENT ----------

@extend_schema_view(
	list=extend_schema(tags=["commerce", "wishlist"], summary="Get current user's wishlist (authenticated)"),
	retrieve=extend_schema(tags=["commerce", "wishlist"], summary="Get wishlist by ID (authenticated)"),
)
class WishlistViewSet(viewsets.GenericViewSet):
	"""
	User wishlist management - users can only access their own wishlist
	"""
	queryset = Wishlist.objects.prefetch_related('products')
	serializer_class = WishlistSerializer
	permission_classes = [permissions.IsAuthenticated]

	def get_queryset(self):
		"""Filter to current user's wishlist only"""
		return self.queryset.filter(user=self.request.user)

	def get_or_create_wishlist(self):
		"""Get or create wishlist for current user"""
		wishlist, _ = Wishlist.objects.get_or_create(user=self.request.user)
		return wishlist

	@action(detail=False, methods=['get'], url_path='current')
	@extend_schema(
		tags=["commerce", "wishlist"],
		summary="Get current user's wishlist",
		responses={200: WishlistSerializer},
	)
	def current(self, request):
		"""Get the current user's wishlist"""
		wishlist = self.get_or_create_wishlist()
		serializer = WishlistSerializer(wishlist)
		return Response(serializer.data)

	@action(detail=False, methods=['post'], url_path='add')
	@extend_schema(
		tags=["commerce", "wishlist"],
		summary="Add product to wishlist",
		request=WishlistProductActionSerializer,
		responses={200: WishlistSerializer},
	)
	def add_product(self, request):
		"""Add a product to the user's wishlist"""
		serializer = WishlistProductActionSerializer(data=request.data)
		serializer.is_valid(raise_exception=True)

		wishlist = self.get_or_create_wishlist()
		product_id = serializer.validated_data['product_id']
		product = Product.objects.get(pk=product_id)

		wishlist.add_product(product)
		wishlist.refresh_from_db()
		return Response(WishlistSerializer(wishlist).data)

	@action(detail=False, methods=['post'], url_path='remove')
	@extend_schema(
		tags=["commerce", "wishlist"],
		summary="Remove product from wishlist",
		request=WishlistProductActionSerializer,
		responses={200: WishlistSerializer},
	)
	def remove_product(self, request):
		"""Remove a product from the user's wishlist"""
		serializer = WishlistProductActionSerializer(data=request.data)
		serializer.is_valid(raise_exception=True)

		wishlist = self.get_or_create_wishlist()
		product_id = serializer.validated_data['product_id']
		
		try:
			product = Product.objects.get(pk=product_id)
			wishlist.remove_product(product)
		except Product.DoesNotExist:
			return Response({'detail': 'Product not found'}, status=404)

		wishlist.refresh_from_db()
		return Response(WishlistSerializer(wishlist).data)

	@action(detail=False, methods=['post'], url_path='clear')
	@extend_schema(
		tags=["commerce", "wishlist"],
		summary="Clear all products from wishlist",
		responses={200: WishlistSerializer},
	)
	def clear(self, request):
		"""Remove all products from the user's wishlist"""
		wishlist = self.get_or_create_wishlist()
		wishlist.products.clear()
		wishlist.refresh_from_db()
		return Response(WishlistSerializer(wishlist).data)

	@action(detail=False, methods=['get'], url_path='check/(?P<product_id>[^/.]+)')
	@extend_schema(
		tags=["commerce", "wishlist"],
		summary="Check if product is in wishlist",
		responses={200: {"type": "object", "properties": {"in_wishlist": {"type": "boolean"}}}},
	)
	def check_product(self, request, product_id=None):
		"""Check if a product is in user's wishlist"""
		wishlist = self.get_or_create_wishlist()
		try:
			product = Product.objects.get(pk=product_id)
			in_wishlist = wishlist.has_product(product)
			return Response({'in_wishlist': in_wishlist})
		except Product.DoesNotExist:
			return Response({'detail': 'Product not found'}, status=404)


@extend_schema_view(
	list=extend_schema(tags=["commerce", "admin"], summary="List all wishlists (admin)"),
	retrieve=extend_schema(tags=["commerce", "admin"], summary="Get wishlist by ID (admin)"),
	update=extend_schema(tags=["commerce", "admin"], summary="Update wishlist (admin)"),
	partial_update=extend_schema(tags=["commerce", "admin"], summary="Partially update wishlist (admin)"),
	destroy=extend_schema(tags=["commerce", "admin"], summary="Delete wishlist (admin)"),
)
class AdminWishlistViewSet(viewsets.ModelViewSet):
	"""
	Admin-only wishlist management - can view and modify any user's wishlist
	"""
	queryset = Wishlist.objects.prefetch_related('products').select_related('user')
	serializer_class = WishlistSerializer
	permission_classes = [AdminOnlyForPatchOtherwisePublic]
	filter_backends = [filters.SearchFilter, filters.OrderingFilter]
	search_fields = ["user__email", "user__first_name", "user__last_name"]
	ordering_fields = ["created_at", "updated_at"]
	ordering = ["-updated_at"]


# ---------- ANALYTICS SYSTEM ----------

class AnalyticsView(APIView):
	"""
	Comprehensive analytics and reporting API for business intelligence.
	Supports configurable date ranges and various analytics modules.
	
	GET /analytics/ - Complete dashboard overview
	GET /analytics/?type=sales - Sales analytics
	GET /analytics/?type=products - Product analytics  
	GET /analytics/?type=customers - Customer analytics
	GET /analytics/?type=shipping - Shipping analytics
	GET /analytics/?type=reviews - Review analytics
	GET /analytics/?type=inventory - Inventory analytics
	GET /analytics/?type=ranges - Available date ranges
	POST /analytics/ - Generate custom analytics reports
	"""
	permission_classes = [permissions.IsAdminUser]

	def _parse_date_params(self, request):
		"""Parse date parameters from request"""
		start_date = request.query_params.get('start_date')
		end_date = request.query_params.get('end_date')
		period = request.query_params.get('period', 'last_30_days')
		
		if start_date:
			start_date = parse_datetime(start_date)
		if end_date:
			end_date = parse_datetime(end_date)
			
		# If no dates provided, use predefined period
		if not start_date or not end_date:
			predefined_ranges = get_predefined_date_ranges()
			if period in predefined_ranges:
				date_range = predefined_ranges[period]
				start_date = start_date or date_range['start']
				end_date = end_date or date_range['end']
				
		return start_date, end_date, period

	@extend_schema(
		tags=["commerce", "analytics"],
		summary="Get analytics data",
		description="Get various analytics based on type parameter",
		parameters=[
			{"name": "type", "in": "query", "schema": {"type": "string", "enum": ["dashboard", "sales", "products", "customers", "shipping", "reviews", "inventory", "ranges"]}, "description": "Type of analytics to retrieve"},
			{"name": "start_date", "in": "query", "schema": {"type": "string", "format": "date-time"}},
			{"name": "end_date", "in": "query", "schema": {"type": "string", "format": "date-time"}},
			{"name": "period", "in": "query", "schema": {"type": "string", "enum": ["today", "yesterday", "last_7_days", "last_30_days", "last_90_days", "this_month", "last_month", "this_year", "last_year"]}},
			{"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100}, "description": "Limit for product analytics"}
		]
	)
	def get(self, request):
		"""Get analytics data based on type parameter"""
		analytics_type = request.query_params.get('type', 'dashboard')
		start_date, end_date, period = self._parse_date_params(request)
		
		if analytics_type == 'dashboard':
			return self._get_dashboard_analytics(start_date, end_date, period)
		elif analytics_type == 'sales':
			return self._get_sales_analytics(start_date, end_date, period)
		elif analytics_type == 'products':
			return self._get_product_analytics(request, start_date, end_date)
		elif analytics_type == 'customers':
			return self._get_customer_analytics(start_date, end_date)
		elif analytics_type == 'shipping':
			return self._get_shipping_analytics(start_date, end_date)
		elif analytics_type == 'reviews':
			return self._get_review_analytics(start_date, end_date)
		elif analytics_type == 'inventory':
			return self._get_inventory_analytics()
		elif analytics_type == 'ranges':
			return self._get_date_ranges()
		else:
			return Response({'error': 'Invalid analytics type'}, status=400)

	def _get_dashboard_analytics(self, start_date, end_date, period):
		"""Get complete analytics dashboard overview"""
		dashboard_data = AnalyticsAggregator.dashboard_overview(start_date, end_date)
		dashboard_data['query_params'] = {
			'start_date': start_date.isoformat() if start_date else None,
			'end_date': end_date.isoformat() if end_date else None,
			'period': period
		}
		return Response(dashboard_data)

	def _get_sales_analytics(self, start_date, end_date, period):
		"""Get detailed sales and revenue analytics"""
		sales_data = SalesAnalytics.revenue_overview(start_date, end_date, period)
		payment_data = SalesAnalytics.payment_methods_breakdown(start_date, end_date)
		
		# Calculate percentages for payment methods
		total_revenue = sum(item['revenue'] for item in payment_data)
		for item in payment_data:
			item['percentage'] = round(
				(item['revenue'] / total_revenue * 100) if total_revenue > 0 else 0, 2
			)
		
		return Response({
			'sales': sales_data,
			'payment_methods': payment_data
		})

	def _get_product_analytics(self, request, start_date, end_date):
		"""Get product performance analytics"""
		limit = int(request.query_params.get('limit', 20))
		
		top_products = ProductAnalytics.top_selling_products(start_date, end_date, limit)
		category_performance = ProductAnalytics.category_performance(start_date, end_date)
		
		return Response({
			'top_products': top_products,
			'category_performance': category_performance
		})

	def _get_customer_analytics(self, start_date, end_date):
		"""Get customer behavior analytics"""
		customer_overview = CustomerAnalytics.customer_overview(start_date, end_date)
		cart_analysis = CustomerAnalytics.cart_abandonment_analysis()
		
		return Response({
			'customer_overview': customer_overview,
			'cart_abandonment': cart_analysis
		})

	def _get_shipping_analytics(self, start_date, end_date):
		"""Get shipping methods and Deutsche Post analytics"""
		shipping_methods = ShippingAnalytics.shipping_methods_breakdown(start_date, end_date)
		deutsche_post_data = ShippingAnalytics.deutsche_post_analytics()
		
		return Response({
			'shipping_methods': shipping_methods,
			'deutsche_post': deutsche_post_data
		})

	def _get_review_analytics(self, start_date, end_date):
		"""Get review and rating analytics"""
		review_data = ReviewAnalytics.review_overview(start_date, end_date)
		return Response(review_data)

	def _get_inventory_analytics(self):
		"""Get comprehensive inventory analytics"""
		inventory_data = ProductAnalytics.inventory_analysis()
		return Response(inventory_data)

	def _get_date_ranges(self):
		"""Get available predefined date ranges"""
		ranges = get_predefined_date_ranges()
		return Response({
			'available_ranges': list(ranges.keys()),
			'ranges': {
				key: {
					'start': value['start'].isoformat(),
					'end': value['end'].isoformat(),
					'display_name': key.replace('_', ' ').title()
				}
				for key, value in ranges.items()
			}
		})

	@extend_schema(
		tags=["commerce", "analytics"],
		summary="Generate custom analytics report",
		description="Generate custom analytics based on specified modules and parameters",
	)
	def post(self, request):
		"""Generate custom analytics report based on specified modules"""
		modules = request.data.get('modules', ['sales', 'products'])
		start_date = request.data.get('start_date')
		end_date = request.data.get('end_date')
		period = request.data.get('period', 'daily')
		options = request.data.get('options', {})

		if start_date:
			start_date = parse_datetime(start_date)
		if end_date:
			end_date = parse_datetime(end_date)

		# If no dates provided, default to last 30 days
		if not start_date or not end_date:
			predefined_ranges = get_predefined_date_ranges()
			date_range = predefined_ranges.get('last_30_days')
			start_date = start_date or date_range['start']
			end_date = end_date or date_range['end']

		report_data = {}
		
		if 'sales' in modules:
			report_data['sales'] = {
				'revenue': SalesAnalytics.revenue_overview(start_date, end_date, period),
				'payment_methods': SalesAnalytics.payment_methods_breakdown(start_date, end_date)
			}
		
		if 'products' in modules:
			limit = options.get('product_limit', 20)
			report_data['products'] = {
				'top_selling': ProductAnalytics.top_selling_products(start_date, end_date, limit),
				'categories': ProductAnalytics.category_performance(start_date, end_date)
			}
		
		if 'customers' in modules:
			report_data['customers'] = CustomerAnalytics.customer_overview(start_date, end_date)
		
		if 'shipping' in modules:
			report_data['shipping'] = {
				'methods': ShippingAnalytics.shipping_methods_breakdown(start_date, end_date),
				'deutsche_post': ShippingAnalytics.deutsche_post_analytics()
			}
		
		if 'reviews' in modules:
			report_data['reviews'] = ReviewAnalytics.review_overview(start_date, end_date)

		return Response({
			'report': report_data,
			'parameters': {
				'modules': modules,
				'start_date': start_date.isoformat(),
				'end_date': end_date.isoformat(),
				'period': period,
				'generated_at': datetime.now().isoformat()
			}
		})

	