import json
from decimal import Decimal
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.contrib.auth import authenticate, login, logout
from django.views.decorators.csrf import csrf_exempt
from django.db import transaction
from .models import CustomUser, Bet, ChatMessage, Withdrawal

# ==========================================
# 1. HTML PAGE RENDERERS
# ==========================================
def home_view(request):
    return render(request, 'predictor/home.html')

def login_page(request):
    if request.user.is_authenticated:
        return redirect('home')
    return render(request, 'predictor/login.html')

def register_page(request):
    if request.user.is_authenticated:
        return redirect('home')
    return render(request, 'predictor/register.html')

def deposit_view(request):
    return render(request, 'predictor/deposit.html') 

def withdraw_view(request):
    if not request.user.is_authenticated:
        return redirect('login_page')
    # Fetch history for Rule 3
    history = Withdrawal.objects.filter(user=request.user).order_by('-created_at')
    return render(request, 'predictor/withdraw.html', {'history': history})

def ai_predictor_view(request):
    return render(request, 'predictor/marketer.html') 


# ==========================================
# 2. AUTHENTICATION APIs
# ==========================================
@csrf_exempt
def register_api(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        phone = request.POST.get('phone')
        password = request.POST.get('password')

        if CustomUser.objects.filter(phone=phone).exists():
            return JsonResponse({'status': 'error', 'message': 'Phone number already registered.'})
        if CustomUser.objects.filter(username=username).exists():
            return JsonResponse({'status': 'error', 'message': 'Username already taken.'})

        try:
            user = CustomUser.objects.create_user(username=username, phone=phone, password=password)
            user.balance = Decimal('500.00')
            user.save()
            return JsonResponse({'status': 'success', 'message': 'Account created successfully!'})
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': 'Registration failed. Check inputs.'})
            
    return JsonResponse({'status': 'error', 'message': 'Invalid request method. Use POST.'})

@csrf_exempt
def login_api(request):
    if request.method == 'POST':
        phone = request.POST.get('phone')
        password = request.POST.get('password')

        user = authenticate(request, username=phone, password=password)
        if user is not None:
            login(request, user) 
            return JsonResponse({
                'status': 'success',
                'message': 'Login successful!',
                'data': {'username': user.username, 'balance': float(user.balance)}
            })
        return JsonResponse({'status': 'error', 'message': 'Invalid phone or password.'})
        
    return JsonResponse({'status': 'error', 'message': 'Invalid request method. Use POST.'})

@csrf_exempt
def logout_api(request):
    logout(request)
    return JsonResponse({'status': 'success', 'message': 'Logged out successfully.'})

def session_check_api(request):
    if request.user.is_authenticated:
        return JsonResponse({
            'status': 'success',
            'data': {'username': request.user.username, 'balance': float(request.user.balance)}
        })
    return JsonResponse({'status': 'error', 'message': 'Not logged in.'})


# ==========================================
# 3. GAMEPLAY & BETTING APIs
# ==========================================
@csrf_exempt
def bet_api(request):
    if not request.user.is_authenticated:
        return JsonResponse({'status': 'error', 'message': 'Please login to play.'})

    action = request.POST.get('action')
    
    try:
        with transaction.atomic():
            user = CustomUser.objects.select_for_update().get(id=request.user.id)

            if action == 'place':
                amount = Decimal(request.POST.get('amount', '0'))
                if amount < 50:
                    return JsonResponse({'status': 'error', 'message': 'Minimum bet is 50 KES'})
                if user.balance < amount:
                    return JsonResponse({'status': 'error', 'message': 'Insufficient balance'})

                user.balance -= amount
                user.save()
                bet = Bet.objects.create(user=user, amount=amount, status='pending')
                return JsonResponse({'status': 'success', 'bet_id': bet.id, 'balance': float(user.balance)})

            elif action == 'cancel':
                bet_id = request.POST.get('bet_id')
                bet = Bet.objects.select_for_update().get(id=bet_id, user=user, status='pending')
                user.balance += bet.amount
                user.save()
                bet.status = 'cancelled'
                bet.save()
                return JsonResponse({'status': 'success', 'balance': float(user.balance)})

            elif action == 'cashout':
                bet_id = request.POST.get('bet_id')
                multiplier = Decimal(request.POST.get('multiplier', '1.00'))
                bet = Bet.objects.select_for_update().get(id=bet_id, user=user, status='pending')
                
                profit = bet.amount * multiplier
                user.balance += profit
                user.save()
                
                bet.status = 'cashed_out'
                bet.multiplier = multiplier
                bet.profit = profit
                bet.save()
                return JsonResponse({'status': 'success', 'profit': float(profit), 'balance': float(user.balance)})

            elif action == 'crash':
                bet_id = request.POST.get('bet_id')
                bet = Bet.objects.select_for_update().get(id=bet_id, user=user, status='pending')
                bet.status = 'lost'
                bet.save()
                return JsonResponse({'status': 'success'})

            elif action == 'my_bets':
                bets = Bet.objects.filter(user=user).order_by('-created_at')[:20]
                data = [{
                    'id': b.id, 'bet_amount': float(b.amount), 
                    'multiplier': float(b.multiplier) if b.multiplier else None, 
                    'profit': float(b.profit), 'status': b.status
                } for b in bets]
                return JsonResponse({'status': 'success', 'data': data})
            elif action == 'live_bets':
            # Fetch the latest 40 bets from all users to simulate the live lobby
                bets = Bet.objects.all().order_by('-created_at')[:40]
                data = [{
                    'name': b.user.username, 
                    'betAmount': float(b.amount), 
                    'targetMultiplier': float(b.multiplier) if b.multiplier else 0, 
                    'profit': float(b.profit), 
                    'hasCashedOut': b.status == 'cashed_out',
                    'crashed': b.status == 'lost',
                    'status': b.status
                } for b in bets]
                return JsonResponse({'status': 'success', 'data': data})

            return JsonResponse({'status': 'error', 'message': 'Invalid action'})

    except Bet.DoesNotExist:
        if action == 'crash':
            return JsonResponse({'status': 'success'}) # Already cashed out, ignore crash
        return JsonResponse({'status': 'error', 'message': 'Bet not found or already processed.'})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': 'Server error processing bet.'})


# ==========================================
# 4. CHAT APIs
# ==========================================
def chat_fetch_api(request):
    messages = ChatMessage.objects.order_by('-created_at')[:50]
    data = [{'username': m.user.username, 'message': m.message} for m in reversed(messages)]
    return JsonResponse({'status': 'success', 'data': data})

@csrf_exempt
def chat_send_api(request):
    if not request.user.is_authenticated:
        return JsonResponse({'status': 'error', 'message': 'Auth required'})
    if request.method == 'POST':
        message = request.POST.get('message', '').strip()
        if message:
            ChatMessage.objects.create(user=request.user, message=message[:200])
            return JsonResponse({'status': 'success'})
    return JsonResponse({'status': 'error', 'message': 'Failed to send'})

# 5. NEW: WITHDRAWAL API
# ADD THIS NEW API FOR WITHDRAWALS
@csrf_exempt
def withdraw_api(request):
    if not request.user.is_authenticated:
        return JsonResponse({'status': 'error', 'message': 'Auth required'})
    
    if request.method == 'POST':
        amount = Decimal(request.POST.get('amount', '0'))
        phone = request.POST.get('phone', '')

        # RULE 4: Minimum 200 KES check on backend
        if amount < 200:
            return JsonResponse({'status': 'error', 'message': 'Minimum withdrawal is 200 KES'})
            
        with transaction.atomic():
            user = CustomUser.objects.select_for_update().get(id=request.user.id)
            
            if user.balance < amount:
                return JsonResponse({'status': 'error', 'message': 'Insufficient balance'})
            
            # Deduct balance
            user.balance -= amount
            user.save()
            
            # Record the request for History
            Withdrawal.objects.create(user=user, amount=amount, phone=phone)
            
            return JsonResponse({'status': 'success', 'balance': float(user.balance)})
            
    return JsonResponse({'status': 'error', 'message': 'Invalid request'})