from rest_framework import status, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination
from django.db.models import Sum, Count, Avg
from django.db.models.functions import TruncDate
from django.utils import timezone
from datetime import timedelta
from .models import Sale, Customer
from .serializers import (
    SaleSerializer, CustomerSerializer, CustomerDetailSerializer
)


class IsVendor(permissions.BasePermission):
    """Permission class for vendor-only access"""
    def has_permission(self, request, view):
        return (
            request.user.is_authenticated and
            request.user.user_type == 'vendor' and
            hasattr(request.user, 'vendor_profile')
        )


class SalePagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100


class CustomerPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100


# ============== SALES VIEWS ==============

class SaleListCreateView(APIView):
    """List and create sales"""
    permission_classes = [IsVendor]

    def get(self, request):
        vendor = request.user.vendor_profile
        sales = Sale.objects.filter(vendor=vendor).select_related('customer', 'product')

        # Filter by date range
        start_date = request.query_params.get('start_date')
        end_date = request.query_params.get('end_date')
        if start_date:
            sales = sales.filter(created_at__date__gte=start_date)
        if end_date:
            sales = sales.filter(created_at__date__lte=end_date)

        # Filter by payment method
        payment_method = request.query_params.get('payment_method')
        if payment_method:
            sales = sales.filter(payment_method=payment_method)

        # Filter by status
        sale_status = request.query_params.get('status')
        if sale_status:
            sales = sales.filter(status=sale_status)

        # Filter by customer
        customer_id = request.query_params.get('customer_id')
        if customer_id:
            sales = sales.filter(customer_id=customer_id)

        # Search
        search = request.query_params.get('search')
        if search:
            sales = sales.filter(product_name__icontains=search)

        # Pagination
        paginator = SalePagination()
        page = paginator.paginate_queryset(sales, request)

        serializer = SaleSerializer(page, many=True)

        return Response({
            'success': True,
            'data': serializer.data,
            'count': sales.count(),
            'next': paginator.get_next_link(),
            'previous': paginator.get_previous_link()
        }, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = SaleSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            sale = serializer.save()
            return Response({
                'success': True,
                'message': 'Sale recorded successfully',
                'data': SaleSerializer(sale).data
            }, status=status.HTTP_201_CREATED)
        return Response({
            'success': False,
            'message': 'Invalid data',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class SaleDetailView(APIView):
    """Get, update, or delete a sale"""
    permission_classes = [IsVendor]

    def get_sale(self, request, sale_id):
        try:
            return Sale.objects.get(id=sale_id, vendor=request.user.vendor_profile)
        except Sale.DoesNotExist:
            return None

    def get(self, request, sale_id):
        sale = self.get_sale(request, sale_id)
        if not sale:
            return Response({
                'success': False,
                'message': 'Sale not found'
            }, status=status.HTTP_404_NOT_FOUND)

        serializer = SaleSerializer(sale)
        return Response({
            'success': True,
            'data': serializer.data
        }, status=status.HTTP_200_OK)

    def patch(self, request, sale_id):
        sale = self.get_sale(request, sale_id)
        if not sale:
            return Response({
                'success': False,
                'message': 'Sale not found'
            }, status=status.HTTP_404_NOT_FOUND)

        serializer = SaleSerializer(sale, data=request.data, partial=True, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response({
                'success': True,
                'message': 'Sale updated',
                'data': serializer.data
            }, status=status.HTTP_200_OK)
        return Response({
            'success': False,
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, sale_id):
        sale = self.get_sale(request, sale_id)
        if not sale:
            return Response({
                'success': False,
                'message': 'Sale not found'
            }, status=status.HTTP_404_NOT_FOUND)

        sale.delete()
        return Response({
            'success': True,
            'message': 'Sale deleted'
        }, status=status.HTTP_200_OK)


class SaleSummaryView(APIView):
    """Get sales summary and analytics"""
    permission_classes = [IsVendor]

    def get(self, request):
        vendor = request.user.vendor_profile
        period = request.query_params.get('period', 'week')  # day, week, month, year

        # Determine date range
        now = timezone.now()
        if period == 'day':
            start_date = now.replace(hour=0, minute=0, second=0, microsecond=0)
        elif period == 'week':
            start_date = now - timedelta(days=7)
        elif period == 'month':
            start_date = now - timedelta(days=30)
        elif period == 'year':
            start_date = now - timedelta(days=365)
        else:
            start_date = now - timedelta(days=7)

        sales = Sale.objects.filter(
            vendor=vendor,
            status='completed',
            created_at__gte=start_date
        )

        # Calculate totals
        totals = sales.aggregate(
            total_sales=Sum('total_price'),
            total_transactions=Count('id'),
            average_sale=Avg('total_price')
        )

        # Payment breakdown
        payment_breakdown = dict(
            sales.values('payment_method').annotate(
                total=Sum('total_price'),
                count=Count('id')
            ).values_list('payment_method', 'total')
        )

        # Daily sales for chart
        daily_sales = list(
            sales.annotate(date=TruncDate('created_at'))
            .values('date')
            .annotate(total=Sum('total_price'), count=Count('id'))
            .order_by('date')
        )

        return Response({
            'success': True,
            'data': {
                'total_sales': totals['total_sales'] or 0,
                'total_transactions': totals['total_transactions'] or 0,
                'average_sale': round(totals['average_sale'] or 0, 2),
                'payment_breakdown': payment_breakdown,
                'daily_sales': daily_sales,
                'period': period,
            }
        }, status=status.HTTP_200_OK)


# ============== CUSTOMER VIEWS ==============

class CustomerListCreateView(APIView):
    """List and create CRM customers"""
    permission_classes = [IsVendor]

    def get(self, request):
        vendor = request.user.vendor_profile
        customers = Customer.objects.filter(vendor=vendor)

        # Search
        search = request.query_params.get('search')
        if search:
            customers = customers.filter(
                name__icontains=search
            ) | customers.filter(
                phone__icontains=search
            )

        # Sort
        sort_by = request.query_params.get('sort', '-created_at')
        if sort_by in ['name', '-name', 'total_purchases', '-total_purchases', 'purchase_count', '-purchase_count', 'created_at', '-created_at']:
            customers = customers.order_by(sort_by)

        # Pagination
        paginator = CustomerPagination()
        page = paginator.paginate_queryset(customers, request)

        serializer = CustomerSerializer(page, many=True)

        return Response({
            'success': True,
            'data': serializer.data,
            'count': customers.count(),
            'next': paginator.get_next_link(),
            'previous': paginator.get_previous_link()
        }, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = CustomerSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            customer = serializer.save()
            return Response({
                'success': True,
                'message': 'Customer created successfully',
                'data': CustomerSerializer(customer).data
            }, status=status.HTTP_201_CREATED)
        return Response({
            'success': False,
            'message': 'Invalid data',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


class CustomerDetailView(APIView):
    """Get, update, or delete a customer"""
    permission_classes = [IsVendor]

    def get_customer(self, request, customer_id):
        try:
            return Customer.objects.get(id=customer_id, vendor=request.user.vendor_profile)
        except Customer.DoesNotExist:
            return None

    def get(self, request, customer_id):
        customer = self.get_customer(request, customer_id)
        if not customer:
            return Response({
                'success': False,
                'message': 'Customer not found'
            }, status=status.HTTP_404_NOT_FOUND)

        serializer = CustomerDetailSerializer(customer)
        return Response({
            'success': True,
            'data': serializer.data
        }, status=status.HTTP_200_OK)

    def patch(self, request, customer_id):
        customer = self.get_customer(request, customer_id)
        if not customer:
            return Response({
                'success': False,
                'message': 'Customer not found'
            }, status=status.HTTP_404_NOT_FOUND)

        serializer = CustomerSerializer(customer, data=request.data, partial=True, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response({
                'success': True,
                'message': 'Customer updated',
                'data': serializer.data
            }, status=status.HTTP_200_OK)
        return Response({
            'success': False,
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, customer_id):
        customer = self.get_customer(request, customer_id)
        if not customer:
            return Response({
                'success': False,
                'message': 'Customer not found'
            }, status=status.HTTP_404_NOT_FOUND)

        customer.delete()
        return Response({
            'success': True,
            'message': 'Customer deleted'
        }, status=status.HTTP_200_OK)
