import json
from datetime import timedelta
import uuid
from django.urls import reverse
from django.utils import timezone
from django.contrib import messages
from django.db.models import Avg, Count, Q, Exists, OuterRef, Value, Sum
from django.contrib.auth import get_user_model
from django.contrib.admin.views.decorators import staff_member_required
from django.http import HttpResponse, JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect, render

# Import your models and helpers
from .models import (
    WalletTransaction, WithdrawalRequest, create_notification,
    # ... other models you already have
)
from .payment_providers import CryptoProvider

# Email Helper
from django.core.mail import send_mail
from django.conf import settings

def send_transaction_email(user, subject, message):
    """Send email notification to user"""
    try:
        send_mail(
            subject=subject,
            message=message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[user.email],
            fail_silently=True,
        )
    except:
        pass  # Don't break flow if email fails


# ===================== CRYPTO ADMIN VIEWS =====================

@staff_member_required
def admin_crypto_approval(request):
    """Admin panel to review and approve crypto deposits & withdrawals"""
    pending_deposits = WalletTransaction.objects.filter(
        status=WalletTransaction.Status.PENDING,
        transaction_type=WalletTransaction.Type.DEPOSIT
    ).select_related('user').order_by('-created_at')

    pending_withdrawals = WithdrawalRequest.objects.filter(
        status=WithdrawalRequest.Status.PENDING
    ).select_related('user').order_by('-created_at')

    context = {
        'pending_deposits': pending_deposits,
        'pending_withdrawals': pending_withdrawals,
        'pending_deposits_count': pending_deposits.count(),
        'pending_withdrawals_count': pending_withdrawals.count(),
    }
    return render(request, 'investments/admin_crypto_approval.html', context)


@staff_member_required
@require_POST
def approve_crypto_deposit(request, tx_id):
    """Approve crypto deposit"""
    transaction = get_object_or_404(
        WalletTransaction, 
        pk=tx_id, 
        status=WalletTransaction.Status.PENDING
    )
    
    tx_hash = request.POST.get('tx_hash')
    if tx_hash:
        transaction.metadata = {**transaction.metadata, 'tx_hash': tx_hash}
    
    CryptoProvider.verify_deposit(transaction, tx_hash)
    
    # Send email notification
    send_transaction_email(
        transaction.user,
        "✅ Your Deposit Has Been Approved",
        f"Your {transaction.provider.upper()} deposit of ${transaction.amount / 100:.2f} has been successfully credited to your wallet."
    )
    
    messages.success(request, f"Deposit #{tx_id} approved and wallet credited.")
    return redirect('core:admin_crypto_approval')


@staff_member_required
@require_POST
def reject_crypto_deposit(request, tx_id):
    """Reject crypto deposit"""
    transaction = get_object_or_404(
        WalletTransaction, 
        pk=tx_id, 
        status=WalletTransaction.Status.PENDING
    )
    
    transaction.status = WalletTransaction.Status.FAILED
    transaction.save()
    
    send_transaction_email(
        transaction.user,
        "❌ Deposit Rejected",
        "Your deposit request was reviewed and not approved. Please contact support with your transaction hash if you believe this is an error."
    )
    
    create_notification(
        user=transaction.user,
        verb="Your deposit was rejected. Please contact support."
    )
    
    messages.warning(request, f"Deposit #{tx_id} rejected.")
    return redirect('core:admin_crypto_approval')


@staff_member_required
@require_POST
def approve_withdrawal(request, withdrawal_id):
    """Approve withdrawal request"""
    withdrawal = get_object_or_404(
        WithdrawalRequest, 
        pk=withdrawal_id, 
        status=WithdrawalRequest.Status.PENDING
    )
    
    withdrawal.status = WithdrawalRequest.Status.APPROVED
    withdrawal.processed_at = timezone.now()
    withdrawal.save()
    
    send_transaction_email(
        withdrawal.user,
        "✅ Withdrawal Approved",
        f"Your withdrawal request of ${withdrawal.amount / 100:.2f} has been approved and is being processed."
    )
    
    create_notification(
        user=withdrawal.user,
        verb=f"Your withdrawal of ${withdrawal.amount / 100:.2f} has been approved."
    )
    
    messages.success(request, f"Withdrawal #{withdrawal_id} approved.")
    return redirect('core:admin_crypto_approval')


@staff_member_required
@require_POST
def reject_withdrawal(request, withdrawal_id):
    """Reject withdrawal request"""
    withdrawal = get_object_or_404(
        WithdrawalRequest, 
        pk=withdrawal_id, 
        status=WithdrawalRequest.Status.PENDING
    )
    
    withdrawal.status = WithdrawalRequest.Status.REJECTED
    withdrawal.processed_at = timezone.now()
    withdrawal.save()
    
    send_transaction_email(
        withdrawal.user,
        "❌ Withdrawal Rejected",
        "Your withdrawal request was reviewed and rejected. Please contact support for more details."
    )
    
    create_notification(
        user=withdrawal.user,
        verb="Your withdrawal request was rejected. Please contact support."
    )
    
    messages.warning(request, f"Withdrawal #{withdrawal_id} rejected.")
    return redirect('core:admin_crypto_approval')