import secrets
from decimal import Decimal
from datetime import timedelta
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.db.models import Sum, Count, Q, F, Avg
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.views import View
from django.contrib import messages

from businesses.models import Business
from sales.models import Sale
from orders.models import Order
from products.models import Product
from payments.models import Payment
from core.models import AuditLog


from django.http import JsonResponse
from core.middleware import is_api_or_postman_request


class SuperAdminMixin(LoginRequiredMixin, UserPassesTestMixin):
    """Requires user to be a superuser."""

    def test_func(self):
        return self.request.user.is_superuser

    def handle_no_permission(self):
        if self.request.user.is_authenticated:
            if is_api_or_postman_request(self.request):
                return JsonResponse({
                    'error': 'Forbidden',
                    'detail': 'Superadmin privileges required.'
                }, status=403)
            return render(self.request, '403.html', {'error': 'Superadmin privileges required.'}, status=403)

        if is_api_or_postman_request(self.request):
            return JsonResponse({
                'error': 'Unauthorized',
                'detail': 'Authentication required. Access denied for unauthenticated API request.'
            }, status=401)

        return super().handle_no_permission()


class SuperAdminOverviewView(SuperAdminMixin, View):
    """Super Admin platform overview with global metrics and business filter."""

    def get(self, request):
        business_id = request.GET.get('business_id', '').strip()
        selected_business = None

        all_businesses = Business.objects.all().order_by('name')

        orders_qs = Order.objects.filter(status='paid')
        sales_qs = Sale.objects.all()
        payments_qs = Payment.objects.all()

        if business_id:
            try:
                selected_business = Business.objects.get(id=business_id)
                orders_qs = orders_qs.filter(sale__business=selected_business)
                sales_qs = sales_qs.filter(business=selected_business)
            except Business.DoesNotExist:
                business_id = ''

        total_gross_sales = orders_qs.aggregate(total=Sum('total_amount'))['total'] or Decimal('0.00')

        booking_payments = payments_qs.filter(type='booking_fee', status__in=['verified', 'paid'])
        if selected_business:
            booking_payments = booking_payments.filter(
                Q(metadata__business_id=str(selected_business.id)) |
                Q(metadata__user_id=str(selected_business.user_id))
            )
        booking_fee_earnings = booking_payments.aggregate(total=Sum('amount'))['total'] or Decimal('0.00')

        commission_sales = sales_qs.filter(pricing_model='commission')
        commission_orders_gross = Order.objects.filter(
            sale__in=commission_sales, status='paid'
        ).aggregate(total=Sum('total_amount'))['total'] or Decimal('0.00')

        commission_earnings = (commission_orders_gross * Decimal('0.05')).quantize(Decimal('0.01'))
        total_platform_earnings = booking_fee_earnings + commission_earnings

        total_businesses = Business.objects.count()
        verified_businesses = Business.objects.filter(is_verified=True).count()
        live_sales = sales_qs.filter(status='live').count()
        upcoming_sales = sales_qs.filter(status='upcoming').count()
        total_paid_orders = orders_qs.count()

        recent_businesses = Business.objects.annotate(
            sales_count=Count('sales', distinct=True),
            revenue=Sum('sales__orders__total_amount', filter=Q(sales__orders__status='paid')),
        ).order_by('-created_at')[:5]

        recent_payments = payments_qs.order_by('-created_at')[:8]

        return render(request, 'superadmin/overview.html', {
            'all_businesses': all_businesses,
            'selected_business': selected_business,
            'selected_business_id': business_id,
            'total_gross_sales': total_gross_sales,
            'booking_fee_earnings': booking_fee_earnings,
            'commission_earnings': commission_earnings,
            'total_platform_earnings': total_platform_earnings,
            'total_businesses': total_businesses,
            'verified_businesses': verified_businesses,
            'live_sales': live_sales,
            'upcoming_sales': upcoming_sales,
            'total_paid_orders': total_paid_orders,
            'recent_businesses': recent_businesses,
            'recent_payments': recent_payments,
        })


class SuperAdminBusinessListView(SuperAdminMixin, View):
    """List all registered businesses with verification toggle."""

    def get(self, request):
        businesses = Business.objects.annotate(
            sales_count=Count('sales', distinct=True),
            orders_count=Count('sales__orders', filter=Q(sales__orders__status='paid'), distinct=True),
            revenue=Sum('sales__orders__total_amount', filter=Q(sales__orders__status='paid')),
        ).order_by('-created_at')

        return render(request, 'superadmin/businesses.html', {
            'businesses': businesses,
        })


class SuperAdminBusinessDetailView(SuperAdminMixin, View):
    """Deep-dive performance and logs for a single business."""

    def get(self, request, business_id):
        business = get_object_or_404(Business, id=business_id)
        sales = business.sales.annotate(
            order_count=Count('orders', filter=Q(orders__status='paid')),
            revenue=Sum('orders__total_amount', filter=Q(orders__status='paid')),
        ).order_by('-start_at')

        products = business.products.filter(is_active=True)

        orders = Order.objects.filter(
            sale__business=business
        ).select_related('sale').order_by('-created_at')[:20]

        total_revenue = Order.objects.filter(
            sale__business=business, status='paid'
        ).aggregate(total=Sum('total_amount'))['total'] or Decimal('0.00')

        booking_fee_earnings = Payment.objects.filter(
            type='booking_fee', status__in=['verified', 'paid']
        ).filter(
            Q(metadata__business_id=str(business.id)) |
            Q(metadata__user_id=str(business.user_id))
        ).aggregate(total=Sum('amount'))['total'] or Decimal('0.00')

        commission_sales = sales.filter(pricing_model='commission')
        commission_orders_gross = Order.objects.filter(
            sale__in=commission_sales, status='paid'
        ).aggregate(total=Sum('total_amount'))['total'] or Decimal('0.00')
        commission_earnings = (commission_orders_gross * Decimal('0.05')).quantize(Decimal('0.01'))

        platform_earnings = booking_fee_earnings + commission_earnings

        return render(request, 'superadmin/business_detail.html', {
            'business': business,
            'sales': sales,
            'products': products,
            'orders': orders,
            'total_revenue': total_revenue,
            'platform_earnings': platform_earnings,
            'booking_fee_earnings': booking_fee_earnings,
            'commission_earnings': commission_earnings,
        })


class SuperAdminResetSellerPasswordView(SuperAdminMixin, View):
    """Generate temporary password for seller support."""

    def post(self, request, business_id):
        business = get_object_or_404(Business, id=business_id)
        temp_password = f"Flash{secrets.token_hex(3)}!"
        user = business.user
        user.set_password(temp_password)
        user.save()

        AuditLog.objects.create(
            user=request.user,
            action='reset_seller_password',
            target_model='Business',
            target_id=str(business.id),
            details={'business_name': business.name, 'username': user.username}
        )

        messages.success(request, f"Password reset for {business.name}! Temporary Password: {temp_password}")
        return redirect('superadmin:business_detail', business_id=business.id)


class SuperAdminToggleVerifyView(SuperAdminMixin, View):
    """Toggle Trusted Business verification status."""

    def post(self, request, business_id):
        business = get_object_or_404(Business, id=business_id)
        business.is_verified = not business.is_verified
        business.save(update_fields=['is_verified', 'updated_at'])

        AuditLog.objects.create(
            user=request.user,
            action='toggle_business_verification',
            target_model='Business',
            target_id=str(business.id),
            details={'is_verified': business.is_verified, 'business_name': business.name}
        )

        return redirect(request.META.get('HTTP_REFERER', 'superadmin:businesses'))


class SuperAdminSaleListView(SuperAdminMixin, View):
    """Monitor all sales across the platform with override controls."""

    def get(self, request):
        status_filter = request.GET.get('status', 'all')
        sales = Sale.objects.select_related('business').annotate(
            order_count=Count('orders', filter=Q(orders__status='paid')),
            revenue=Sum('orders__total_amount', filter=Q(orders__status='paid')),
        )

        if status_filter != 'all':
            sales = sales.filter(status=status_filter)

        sales = sales.order_by('-start_at')

        return render(request, 'superadmin/sales.html', {
            'sales': sales,
            'status_filter': status_filter,
        })


class SuperAdminSaleActionView(SuperAdminMixin, View):
    """Super admin sale overrides: extend sale (+24h) or force end sale."""

    def post(self, request, sale_id):
        sale = get_object_or_404(Sale, id=sale_id)
        action_type = request.POST.get('action_type')

        if action_type == 'extend':
            sale.end_at = sale.end_at + timedelta(days=1)
            if sale.status == 'ended' and sale.end_at > timezone.now():
                sale.status = 'live'
            sale.save(update_fields=['end_at', 'status'])
            messages.success(request, f"Extended sale '{sale.title}' by +24 hours.")
        elif action_type == 'end':
            sale.status = 'ended'
            sale.save(update_fields=['status'])
            messages.success(request, f"Force ended sale '{sale.title}'.")

        AuditLog.objects.create(
            user=request.user,
            action=f'superadmin_sale_{action_type}',
            target_model='Sale',
            target_id=str(sale.id),
            details={'title': sale.title, 'new_status': sale.status, 'end_at': str(sale.end_at)}
        )

        return redirect(request.META.get('HTTP_REFERER', 'superadmin:sales'))


class SuperAdminOrderListView(SuperAdminMixin, View):
    """Monitor and search customer orders across all sales."""

    def get(self, request):
        status_filter = request.GET.get('status', 'all')
        search_query = request.GET.get('q', '').strip()

        orders = Order.objects.select_related('sale', 'sale__business', 'delivery_option').prefetch_related('items__sale_item__product')

        if status_filter != 'all':
            orders = orders.filter(status=status_filter)

        if search_query:
            orders = orders.filter(
                Q(order_number__icontains=search_query) |
                Q(buyer_name__icontains=search_query) |
                Q(buyer_phone__icontains=search_query) |
                Q(buyer_email__icontains=search_query)
            )

        orders = orders.order_by('-created_at')

        return render(request, 'superadmin/orders.html', {
            'orders': orders,
            'status_filter': status_filter,
            'search_query': search_query,
        })


class SuperAdminPaymentListView(SuperAdminMixin, View):
    """Monitor all Paystack payments."""

    def get(self, request):
        payments = Payment.objects.order_by('-created_at')
        return render(request, 'superadmin/payments.html', {
            'payments': payments,
        })


class SuperAdminAnalyticsView(SuperAdminMixin, View):
    """Platform Analytics & Leaderboards."""

    def get(self, request):
        from django.db.models import ExpressionWrapper, DecimalField

        top_businesses = Business.objects.annotate(
            sales_count=Count('sales', distinct=True),
            total_revenue=Sum('sales__orders__total_amount', filter=Q(sales__orders__status='paid')),
            paid_orders=Count('sales__orders', filter=Q(sales__orders__status='paid'), distinct=True),
        ).order_by('-total_revenue')[:10]

        top_products = Product.objects.filter(is_active=True).annotate(
            units_sold=Sum('sale_items__order_items__quantity', filter=Q(sale_items__order_items__order__status='paid')),
            gross_revenue=Sum(
                ExpressionWrapper(
                    F('sale_items__order_items__unit_price') * F('sale_items__order_items__quantity'),
                    output_field=DecimalField(max_digits=12, decimal_places=2)
                ),
                filter=Q(sale_items__order_items__order__status='paid')
            ),
        ).filter(units_sold__gt=0).order_by('-gross_revenue')[:10]

        return render(request, 'superadmin/analytics.html', {
            'top_businesses': top_businesses,
            'top_products': top_products,
        })


class SuperAdminSettingsView(SuperAdminMixin, View):
    """System Configuration & Fee Defaults."""

    def get(self, request):
        from django.conf import settings
        config = {
            'BOOKING_DAILY_RATE': getattr(settings, 'BOOKING_DAILY_RATE', Decimal('50.00')),
            'BOOKING_COMMISSION_PERCENT': getattr(settings, 'BOOKING_COMMISSION_PERCENT', Decimal('5.00')),
            'BOOKING_COMMISSION_MIN_FEE': getattr(settings, 'BOOKING_COMMISSION_MIN_FEE', Decimal('10.00')),
            'PAYSTACK_SECRET_KEY': getattr(settings, 'PAYSTACK_SECRET_KEY', 'sk_test_***'),
        }
        return render(request, 'superadmin/settings.html', {
            'config': config,
        })


class SuperAdminAuditLogView(SuperAdminMixin, View):
    """Platform audit log."""

    def get(self, request):
        logs = AuditLog.objects.select_related('user').order_by('-created_at')[:100]
        return render(request, 'superadmin/audit_logs.html', {
            'logs': logs,
        })
