from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.http import JsonResponse
from django.contrib.auth.models import User
from django.contrib import messages
from .models import Account, Order, Transaction, Cryptocurrency, SiteSettings, Asset, Position
import random
import decimal
import json
from django.views.decorators.csrf import csrf_exempt
from django.db import transaction

def is_mobile(request):
    user_agent = request.META.get('HTTP_USER_AGENT', '').lower()
    mobile_indicators = ['iphone', 'android', 'phone', 'mobile']
    return any(indicator in user_agent for indicator in mobile_indicators)

def index(request):
    if is_mobile(request):
        return render(request, 'core/mobile/index.html')
    return render(request, 'core/index.html')

def trade(request, trade_type='spot'):
    symbol = request.GET.get('symbol', 'BTCUSDT')
    base_symbol = symbol.replace('USDT', '')
    cryptos = Cryptocurrency.objects.filter(is_active=True)
    account = None
    assets = {}
    base_asset_balance = decimal.Decimal('0')
    
    if request.user.is_authenticated:
        account, _ = Account.objects.get_or_create(user=request.user)
        for asset in account.assets.all():
            assets[asset.currency] = asset
            if asset.currency == base_symbol:
                base_asset_balance = asset.balance
            
    context = {
        'symbol': symbol,
        'base_symbol': base_symbol,
        'trade_type': trade_type.upper(),
        'cryptos': cryptos,
        'account': account,
        'assets': assets,
        'base_asset_balance': base_asset_balance,
    }
    
    template = 'core/mobile/trade.html' if is_mobile(request) else 'core/trade.html'
    return render(request, template, context)

def market_center(request):
    cryptos = Cryptocurrency.objects.filter(is_active=True)
    template = 'core/mobile/market_center.html' if is_mobile(request) else 'core/market_center.html'
    return render(request, template, {'cryptos': cryptos})

def placeholder_view(request, title):
    settings = SiteSettings.objects.first()
    
    if title == '服务条款':
        content = settings.terms_content if settings and settings.terms_content else '暂无服务条款内容。'
    elif title == '隐私政策':
        content = settings.privacy_content if settings and settings.privacy_content else '暂无隐私政策内容。'
    else:
        contents = {
            '帮助中心': '欢迎来到 BitCrypto 帮助中心。在这里您可以找到关于账户设置、资产充提、交易指南等所有问题的答案。我们为您准备了详尽的视频教程和图文说明，帮助您快速上手。',
            '技术支持': 'BitCrypto 技术支持团队 24/7 在线。如果您遇到任何 API 对接、系统报错或连接问题，请随时联系我们的工程师。我们承诺在 15 分钟内给予首次回复。',
            '提交请求': '请在下方表单提交您的需求或反馈。无论是工单申请、投诉建议还是商务合作，我们都会认真对待。您的每一份反馈都是我们前进的动力。',
            '公告中心': '查看 BitCrypto 最新动态。包括新币上线通知、系统维护公告、市场活动资讯等。订阅我们的邮件列表，第一时间获取核心商业情报。',
        }
        content = contents.get(title, f'这是{title}的详细内容。BitCrypto为您提供最优质的服务。')
    
    faqs = [
        {'q': '如何进行身份认证？', 'a': '登录后在个人中心点击身份认证，上传身份证件并完成人脸识别即可。'},
        {'q': '充值多久能到账？', 'a': '区块链网络确认后自动到账，通常 5-30 分钟。'},
        {'q': '手续费是多少？', 'a': '现货交易基础手续费为 0.1%，使用平台币抵扣可享 7.5 折优惠。'},
    ]
    
    return render(request, 'core/article_detail.html', {
        'title': title, 
        'content': content,
        'faqs': faqs if title == '帮助中心' else None
    })

@login_required
def profile(request):
    account, created = Account.objects.get_or_create(user=request.user)
    recent_transactions = Transaction.objects.filter(account=account).order_by('-timestamp')[:10]
    recent_orders = Order.objects.filter(account=account).order_by('-created_at')[:10]
    positions = Position.objects.filter(account=account, is_active=True)
    context = {
        'account': account,
        'recent_transactions': recent_transactions,
        'recent_orders': recent_orders,
        'positions': positions,
    }
    template = 'core/mobile/profile.html' if is_mobile(request) else 'core/profile.html'
    return render(request, template, context)

@login_required
def deposit(request):
    if request.method == 'POST':
        amount = request.POST.get('amount')
        tx_id = request.POST.get('tx_id')
        if amount and tx_id:
            account = request.user.account
            Transaction.objects.create(
                account=account,
                transaction_type='deposit',
                amount=decimal.Decimal(amount),
                status='pending',
                tx_hash=tx_id
            )
            return redirect('core:profile')
    template = 'core/mobile/deposit.html' if is_mobile(request) else 'core/deposit.html'
    return render(request, template)

@login_required
def withdraw(request):
    account = request.user.account
    if request.method == 'POST':
        amount = request.POST.get('amount')
        address = request.POST.get('address')
        if amount and address:
            amount_dec = decimal.Decimal(amount)
            if account.balance >= amount_dec:
                account.balance -= amount_dec
                account.save()
                Transaction.objects.create(
                    account=account,
                    transaction_type='withdraw',
                    amount=amount_dec,
                    status='completed',
                    tx_hash=f"wd_{random.randint(1000, 9999)}"
                )
                return redirect('core:profile')
    template = 'core/mobile/withdraw.html' if is_mobile(request) else 'core/withdraw.html'
    return render(request, template, {'account': account})

@login_required
def verify(request):
    account = request.user.account
    if request.method == 'POST':
        account.kyc_status = 'pending'
        account.save()
        return redirect('core:profile')
    template = 'core/mobile/verify.html' if is_mobile(request) else 'core/verify.html'
    return render(request, template, {'account': account})

def register_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        password_confirm = request.POST.get('password_confirm')
        captcha_input = request.POST.get('captcha_input')
        captcha_expected = request.session.get('captcha_result')

        if password != password_confirm:
            messages.error(request, "两次输入的密码不一致")
        elif str(captcha_input) != str(captcha_expected):
            messages.error(request, "验证码错误")
        elif User.objects.filter(username=username).exists():
            messages.error(request, "用户名已存在")
        else:
            user = User.objects.create_user(username=username, password=password)
            Account.objects.get_or_create(user=user)
            login(request, user)
            return redirect('core:index')
            
    captcha_text, captcha_result = generate_captcha()
    request.session['captcha_result'] = captcha_result
    
    template = 'core/mobile/register.html' if is_mobile(request) else 'core/register.html'
    return render(request, template, {
        'captcha_text': captcha_text
    })

def generate_captcha():
    a = random.randint(1, 10)
    b = random.randint(1, 10)
    op = random.choice(['+', '-', '*'])
    if op == '+': res = a + b
    elif op == '-': res = a - b
    else: res = a * b
    return f"{a} {op} {b} = ?", res

def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            return redirect('core:index')
    else:
        form = AuthenticationForm()
    template = 'core/mobile/login.html' if is_mobile(request) else 'core/login.html'
    return render(request, template, {'form': form})

@login_required
@csrf_exempt
def submit_order(request):
    if request.method != 'POST':
        return JsonResponse({'status': 'error', 'message': 'Invalid request'})
        
    try:
        data = json.loads(request.body)
        symbol = data.get('symbol', 'BTCUSDT')
        side = data.get('side') # BUY or SELL
        trade_type = data.get('trade_type', 'SPOT')
        order_type = data.get('order_type', 'MARKET')
        price_val = data.get('price')
        amount_val = data.get('amount', 0)
        leverage = int(data.get('leverage', 20))
        
        account = request.user.account
        base_symbol = symbol.replace('USDT', '')
        
        # Get price (consider manual override)
        crypto = Cryptocurrency.objects.filter(symbol=base_symbol).first()
        settings = SiteSettings.objects.first()
        
        current_price = crypto.current_price if (crypto and crypto.current_price > 0) else decimal.Decimal('48000')
        if settings and settings.is_pinning_active and crypto and crypto.manual_price:
            current_price = crypto.manual_price
            
        with transaction.atomic():
            if trade_type == 'SPOT':
                if order_type == 'MARKET':
                    # Spot Market Order: Execute Immediately
                    if side == 'BUY':
                        # BUY: amount_val is USDT
                        total_usdt = decimal.Decimal(str(amount_val))
                        if account.balance < total_usdt:
                            return JsonResponse({'status': 'error', 'message': '余额不足'})
                        
                        exec_amount = total_usdt / current_price
                        account.balance -= total_usdt
                        account.save()
                        
                        asset, _ = Asset.objects.get_or_create(account=account, currency=base_symbol)
                        asset.balance += exec_amount
                        asset.save()
                        
                        Order.objects.create(
                            account=account, symbol=symbol, side=side, order_type=order_type,
                            trade_type=trade_type, amount=exec_amount, total_usdt=total_usdt, status='FILLED'
                        )
                    else: # SELL
                        # SELL: amount_val is coin quantity
                        exec_amount = decimal.Decimal(str(amount_val))
                        asset, _ = Asset.objects.get_or_create(account=account, currency=base_symbol)
                        if asset.balance < exec_amount:
                            return JsonResponse({'status': 'error', 'message': f'{base_symbol} 余额不足'})
                        
                        total_usdt = exec_amount * current_price
                        asset.balance -= exec_amount
                        asset.save()
                        
                        account.balance += total_usdt
                        account.save()
                        
                        Order.objects.create(
                            account=account, symbol=symbol, side=side, order_type=order_type,
                            trade_type=trade_type, amount=exec_amount, total_usdt=total_usdt, status='FILLED'
                        )
                else: # LIMIT
                    # Spot Limit Order: Freeze Assets, Pend
                    price = decimal.Decimal(str(price_val))
                    amount = decimal.Decimal(str(amount_val))
                    if side == 'BUY':
                        total_usdt = price * amount
                        if account.balance < total_usdt:
                            return JsonResponse({'status': 'error', 'message': '余额不足'})
                        
                        account.balance -= total_usdt
                        account.frozen_balance += total_usdt
                        account.save()
                        
                        Order.objects.create(
                            account=account, symbol=symbol, side=side, order_type=order_type,
                            trade_type=trade_type, amount=amount, price=price, total_usdt=total_usdt, status='PENDING'
                        )
                    else: # SELL
                        asset, _ = Asset.objects.get_or_create(account=account, currency=base_symbol)
                        if asset.balance < amount:
                            return JsonResponse({'status': 'error', 'message': f'{base_symbol} 余额不足'})
                        
                        asset.balance -= amount
                        asset.frozen += amount
                        asset.save()
                        
                        Order.objects.create(
                            account=account, symbol=symbol, side=side, order_type=order_type,
                            trade_type=trade_type, amount=amount, price=price, status='PENDING'
                        )
            
            else: # CONTRACT
                # Contract: Initial Margin = face_value(100) * lots / leverage
                lots = decimal.Decimal(str(amount_val))
                face_value = decimal.Decimal('100')
                margin_required = (face_value * lots) / decimal.Decimal(str(leverage))
                
                if account.balance < margin_required:
                    return JsonResponse({'status': 'error', 'message': '保证金不足'})
                
                if order_type == 'MARKET':
                    # Contract Market Order: Immediate Open Position
                    account.balance -= margin_required
                    account.save()
                    
                    Position.objects.create(
                        account=account, symbol=symbol, side='LONG' if side == 'BUY' else 'SHORT',
                        leverage=leverage, entry_price=current_price, lots=lots, margin=margin_required
                    )
                    
                    Order.objects.create(
                        account=account, symbol=symbol, side=side, order_type=order_type,
                        trade_type=trade_type, amount=lots, leverage=leverage, status='FILLED'
                    )
                else: # LIMIT
                    # Contract Limit Order: Freeze Margin, Pend
                    price = decimal.Decimal(str(price_val))
                    account.balance -= margin_required
                    account.frozen_balance += margin_required
                    account.save()
                    
                    Order.objects.create(
                        account=account, symbol=symbol, side=side, order_type=order_type,
                        trade_type=trade_type, amount=lots, price=price, leverage=leverage, status='PENDING'
                    )
            
        return JsonResponse({'status': 'success'})
            
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)})

@login_required
@csrf_exempt
def close_position(request, position_id):
    if request.method != 'POST':
        return JsonResponse({'status': 'error', 'message': 'Invalid request'})
        
    position = get_object_or_404(Position, id=position_id, account=request.user.account, is_active=True)
    
    base_symbol = position.symbol.replace('USDT', '')
    crypto = Cryptocurrency.objects.filter(symbol=base_symbol).first()
    settings = SiteSettings.objects.first()
    current_price = crypto.current_price if (crypto and crypto.current_price > 0) else decimal.Decimal('48000')
    if settings and settings.is_pinning_active and crypto and crypto.manual_price:
        current_price = crypto.manual_price
    
    account = request.user.account
    face_value = decimal.Decimal('100')
    
    # Win/Loss Control Logic
    # 100 = Must Win, -100 = Must Loss
    forced_upl = None
    if account.win_loss_control != 0:
        # Force a small profit or loss
        total_value = position.lots * face_value
        if account.win_loss_control > 0: # Force Profit
            forced_upl = total_value * decimal.Decimal('0.05') # 5% profit
        else: # Force Loss
            forced_upl = -total_value * decimal.Decimal('0.05') # 5% loss
    
    # Calculate Unrealized P&L
    if position.side == 'LONG':
        upl = (current_price - position.entry_price) / position.entry_price * (position.lots * face_value)
    else:
        upl = (position.entry_price - current_price) / position.entry_price * (position.lots * face_value)
    
    # If control is active, override upl
    if forced_upl is not None:
        upl = forced_upl

    with transaction.atomic():
        # Settlement: Margin + P&L - Fee (0.05%)
        fee = (position.lots * face_value) * decimal.Decimal('0.0005')
        account.balance += (position.margin + upl - fee)
        account.save()
        
        position.is_active = False
        position.save()
        
        # Log closing order
        Order.objects.create(
            account=account, symbol=position.symbol, side='SELL' if position.side == 'LONG' else 'BUY',
            order_type='MARKET', trade_type='CONTRACT', amount=position.lots, status='FILLED'
        )
        
    return JsonResponse({'status': 'success'})

def market_data(request):
    settings = SiteSettings.objects.first()
    cryptos = Cryptocurrency.objects.filter(is_active=True)
    data = []
    for c in cryptos:
        price = float(c.current_price)
        if settings and settings.is_pinning_active and c.manual_price:
            price = float(c.manual_price)
        
        symbol_display = c.symbol if 'USDT' in c.symbol else f"{c.symbol}USDT"
            
        data.append({
            'symbol': symbol_display,
            'price': price,
            'change': float(c.change_24h)
        })
    return JsonResponse(data, safe=False)