from django.shortcuts import render
from rest_framework.response import Response
# from .custom_pagination import CustomPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework import viewsets
from .models import *
from .serializers import *
from rest_framework.exceptions import ValidationError
from rest_framework.pagination import PageNumberPagination
from Help_Support.decorators import cache_response
from product.models import *
from Help_Support.models import *
from django.db.models import Count
from login_signup.custom_authentication import CustomJWTAuthentication
class PlanViewSet(viewsets.ModelViewSet):
    queryset = Plan.objects.all()
    serializer_class = PlanSerializer
    # pagination_class = CustomPagination

class SubscribeViewSet(viewsets.ModelViewSet):
   
    # queryset = subscribe.objects.all()
    def get_queryset(self):
        # Use select_related for foreign key relationships
        return subscribe.objects.select_related('plan','user').order_by('-id')
    def get_serializer_class(self):
        if self.action == 'list' or self.action == 'retrieve':
            return SubscribeSerializer
        elif self.action == 'create':
            return SubscribeCreateSerializer
        return SubscribeUpdateSerializer 
    # pagination_class = CustomPagination
    @cache_response()
    def list(self, request):
        queryset = subscribe.objects.all().order_by('id')
        # Use the custom queryset method to get subscriptions
        user_id = request.query_params.get('user_id')
        if user_id:
            # Filter subscriptions by the provided user_id
            queryset =queryset.filter(user_id=user_id)
        for sub in queryset:
            sub.is_expired = sub.check_expiration()
            sub.save()

        # 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)

class DashboardViewSet(viewsets.ViewSet):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]
    def list(self, request):
        statuses = [
            ('registered', 'Registered'),
            ('otp verified', 'Otp Verified'),
            ('document uploaded', 'Document Uploaded'),
            ('rejected', 'Rejected'),
            ('inactive', 'Inactive'),
            ('approved', 'Approved'),
            ('reuploaded document', 'Reuploaded Document')
        ]
        # General statistics
        total_products = Product.objects.count()
        total_vendors = User.objects.filter(is_vendor=True).count()  
        total_buyers = User.objects.filter(is_buyer=True).count()
        total_active_products = Product.objects.filter(status='active').count()
        total_inactive_products = Product.objects.filter(status='inactive').count()
        total_available_products = Product.objects.filter(availability_status='available').count()
        total_out_of_stock_products = Product.objects.filter(availability_status='out of stock').count()
        total_categories = Category.objects.count()
        total_reports = Report.objects.count()                    
        total_offers=OfferModel.objects.count()
        vendor_user_count_by_status = {}
        plans = Plan.objects.all()
        plan_user_count = {}
        for plan in plans:
            user_count = subscribe.objects.filter(plan=plan,is_expired=False,user__is_vendor=True).count()
            plan_user_count[plan.name] = user_count
        for status_key, status_value in statuses:
            user_count = User.objects.filter(status=status_key, is_vendor=True).count()
            vendor_user_count_by_status[status_value] = user_count
        products_with_offer_counts = Product.objects.annotate(
            offer_count=Count('offer')  # 'offer' is the related name for OfferModel
        ).filter(offer_count__gt=0)
        top_products = products_with_offer_counts.order_by('-offer_count')[:5]
        # Prepare the response data
        product_counts = {
            product.id: {
                'name': product.title,  # Assuming 'title' is a field in your Product model
                'offer_count': product.offer_count
            }
            for product in top_products
        }
        categories_with_product_counts = Category.objects.annotate(
            product_count=Count('category_product')  # 'products' is the related name for Product
        ).filter(product_count__gt=0)
        # Prepare the response data
        category_counts = {
            category.id: {
                'name': category.category_name,  # Assuming 'name' is a field in your Category model
                'product_count': category.product_count
            }
            for category in categories_with_product_counts
        }
        now = timezone.now()

        # Calculate date ranges
        last_month_start = now - timedelta(days=30)
        last_week_start = now - timedelta(days=7)
        last_year_start = now - timedelta(days=365)

        # Get counts for each time period based on created_at
        user_count_last_month = User.objects.filter(created_at__gte=last_month_start).count()
        user_count_last_week = User.objects.filter(created_at__gte=last_week_start).count()
        user_count_last_year = User.objects.filter(created_at__gte=last_year_start).count()

        # Prepare the response data
        counts = {
            'last_month': user_count_last_month,
            'last_week': user_count_last_week,
            'last_year': user_count_last_year
        }

        stats = {
            "total":{
            "total_products": total_products,
            "total_vendors": total_vendors,
            "total_buyers": total_buyers,
            "total_active_products": total_active_products,
            "total_inactive_products": total_inactive_products,
            "total_available_products": total_available_products,
            "total_out_of_stock_products": total_out_of_stock_products,
            "total_categories": total_categories,
            "total_reports": total_reports, 
            "total_offers": total_offers,
            },
            "total_vendor_status":vendor_user_count_by_status,
            "suscription":plan_user_count,
            "offers":product_counts,
            "category":category_counts,
            "useranalytics":counts,
            
        }

        return Response(DashboardStatsSerializer(stats).data)
    
class UserDashboardViewSet(viewsets.ViewSet):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]
    def list(self, request):
        # Get the authenticated user
        user = request.user
        # User-specific statistics
        products = Product.objects.filter(user__email=user)
        total_products = products.count()
        total_offers = OfferModel.objects.filter(product__in=products).count() 
        total_categories = products.values('category').distinct().count()
        active_products_count = products.filter(status='active').count()
        inactive_products_count = products.filter(status='inactive').count()
        available_products_count = products.filter(availability_status='available').count()
        out_of_stock_products_count = products.filter(availability_status='out of stock').count()
        total_reports = Report.objects.filter(product__in=products).count()
        product_stats = products.annotate(
            offer_count=Count('offer'),  
            report_count=Count('report') 
        )

        # Prepare the data for response
        stats = []
        for product in product_stats:
            stats.append({
                'product_id': product.id,
                'product_name': product.title,  # Assuming the product has a `title` field
                'offer_count': product.offer_count,
                'report_count': product.report_count
            })
        user_stats = {
            "total":{
            "total_products": total_products,
            "total_offers": total_offers,
            "total_categories": total_categories,
            "active_products_count": active_products_count,
            "inactive_products_count": inactive_products_count,
            "available_products_count": available_products_count,
            "out_of_stock_products_count": out_of_stock_products_count,
            "total_reports": total_reports,
            
            },
            'products': stats,
            
        }

        return Response(UserDashboardStatsSerializer(user_stats).data)