from ._base import *


def rename_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # 🔹 Obtener información de la cuenta desde acore_auth
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT id, email, last_ip FROM account WHERE username = %s
        """, [username])
        account_info = cursor.fetchone()

    if not account_info:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

    account_id, email, acore_ip = account_info
    client_ip = request.META.get('REMOTE_ADDR', '')

    # 🔹 Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name FROM characters WHERE account = %s
        """, [account_id])
        characters = [row[0] for row in cursor.fetchall()]

    # 🔹 Obtener el precio del renombrado
    price_obj = RenamePrice.objects.first()
    price = price_obj.price if price_obj else 2.00

    # 🔹 Ejecutar el comando SOAP para verificar el servidor
    command = f".server info"
    response = execute_soap_command(command)

    if request.method == 'POST':
        character_name = request.POST.get('character')

        if response is None:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error de comunicación con el servidor. Intente nuevamente más tarde.</span>'})

        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para renombrar este personaje.</span>'}) 

        # 🔹 Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('rename-success'))
        cancel_url = request.build_absolute_uri(reverse('rename-cancel'))
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=price,
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Renombrar personaje: {character_name}"
        )

        if stripe_response["success"]:
            request.session['rename_character'] = character_name
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })   
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/rename_character.html', {'characters': characters, 'price': price})
@require_paid_stripe()
def rename_success_view(request):
    # Procesar el comando SOAP tras el pago exitoso
    character_name = request.session.get('rename_character')
    if not character_name:
        return redirect('rename-character')

    command = f".char rename {character_name}"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha sido marcado para renombrar."
        request.session.pop('rename_character', None)  # Limpiar la sesión
        return render(request, 'account/rename_success.html', {'message': message})
    else:
        return render(request, 'account/rename_success.html', {'message': f"Error: {response}"})
def rename_cancel_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')
    return render(request, 'account/rename_cancel.html')
def restore_character_view(request):
    # Verifica si el usuario está autenticado y obtiene su nombre de usuario
    username = request.session.get('username')
    if not username:
        return redirect('login')  # Redirige si no hay sesión

    # Obtener la ID de cuenta del usuario conectado a partir del sistema de autenticación personalizada
    try:
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute("SELECT id FROM account WHERE username = %s", [username])
            result = cursor.fetchone()

        if not result:
            # Si no se encuentra la cuenta, mostrar un error
            messages.error(request, "No se encontró la cuenta asociada a ese usuario.")
            return redirect('login')  # Redirige al login si no se encuentra la cuenta

        account_id = result[0]  # Obtén el ID de la cuenta
    except Exception as e:
        messages.error(request, f"Ocurrió un error al recuperar la cuenta: {str(e)}")
        return redirect('login')

    # Verificar si se ha seleccionado un personaje para restaurar
    if request.method == 'POST':
        # Obtener el GUID del personaje seleccionado para restaurar
        guid = request.POST.get('guid')

        if not guid:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No se seleccionó un personaje para restaurar.</span>'})

        # Restaurar vía SOAP y responder en JSON (isla React)
        try:
            command = f".char del restore {guid}"  # Comando SOAP para restaurar el personaje
            response = execute_soap_command(command)  # Ejecuta el comando SOAP

            if response == "success":
                return JsonResponse({
                    'success': True,
                    'message': '<span class="ok-form-response">Personaje restaurado exitosamente.</span>',
                    'redirect': reverse('my-account'),
                })
            else:
                return JsonResponse({'success': False, 'message': '<span class="red-form-response">Hubo un error al restaurar el personaje.</span>'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Hubo un error al intentar restaurar el personaje: {str(e)}</span>'})

    # Realizar la consulta para obtener los personajes eliminados de la cuenta
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT guid, level, deleteInfos_Name, deleteInfos_Account, deleteDate 
            FROM characters 
            WHERE deleteInfos_Account = %s AND deleteDate IS NOT NULL
        """, [account_id])  # Filtra por account_id

        # Obtener los resultados de la consulta
        deleted_characters = cursor.fetchall()

    # Si no hay personajes eliminados
    if not deleted_characters:
        return render(request, 'account/restore_character.html', {
            'message': 'No hay personajes eliminados que puedas recuperar.'
        })

    # Crear un listado de personajes eliminados con su nombre y nivel (si lo tienes)
    character_list = []
    for character in deleted_characters:
        guid, level, name, account_id, delete_date = character
        # Agregar la información del personaje al listado
        character_list.append({
            'name': name,
            'guid': guid,
            'level': level,
            'delete_date': delete_date
        })

    # Renderiza la plantilla con los personajes eliminados
    return render(request, 'account/restore_character.html', {
        'character_list': character_list,
        'character_data': [
            {'guid': c['guid'], 'name': c['name'], 'level': c['level']}
            for c in character_list
        ],
    })
def restore_items_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    characters = []
    deleted_items = []
    selected_character = None

    try:
        # Obtener la ID de cuenta del usuario
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute("SELECT id FROM account WHERE username = %s", [username])
            result = cursor.fetchone()
            if result:
                account_id = result[0]
            else:
                messages.error(request, "No se encontró la cuenta asociada.")
                return redirect('login')

        # Obtener los personajes del usuario
        with connections['acore_characters'].cursor() as cursor:
            cursor.execute("SELECT name FROM characters WHERE account = %s", [account_id])
            characters = [row[0] for row in cursor.fetchall()]

    except Exception as e:
        messages.error(request, f"Error al obtener los personajes: {str(e)}")

    # La isla React usa AJAX (X-Requested-With); en ese caso respondemos JSON.
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'

    if request.method == "GET" and "character_name" in request.GET:
        selected_character = request.GET.get("character_name")

        if selected_character:
            try:
                # Ejecutar comando SOAP para obtener ítems eliminados del personaje seleccionado
                command = f".item restore list {selected_character}"
                response = execute_soap_command(command)

                # Procesar la respuesta del servidor
                for line in response.split("\n"):
                    match = re.search(r"Recover id: (\d+) \| Item: (.+) \((\d+)\) \| Count: (\d+)", line)
                    if match:
                        recover_id = match.group(1)
                        item_name = match.group(2)
                        item_id = match.group(3)
                        count = match.group(4)
                        deleted_items.append({
                            "recover_id": recover_id,
                            "item_name": item_name,
                            "item_id": item_id,
                            "count": count
                        })

            except Exception as e:
                if is_ajax:
                    return JsonResponse({'error': f'Error al obtener los ítems eliminados: {str(e)}'})
                messages.error(request, f"Error al obtener los ítems eliminados: {str(e)}")

        if is_ajax:
            return JsonResponse({'items': deleted_items})

    if request.method == "POST":
        recover_id = request.POST.get("recover_id")
        selected_character = request.POST.get("character_name")

        if not recover_id or not selected_character:
            if is_ajax:
                return JsonResponse({'success': False, 'message': '<span class="red-form-response">Selecciona un personaje y un ítem para restaurar.</span>'})
            messages.error(request, "Selecciona un personaje y un ítem para restaurar.")
            return redirect('restore-items')

        try:
            # Ejecutar comando SOAP para restaurar el ítem
            command = f".item restore {recover_id} {selected_character}"
            response = execute_soap_command(command)
            ok = "success" in response.lower()
        except Exception as e:
            if is_ajax:
                return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al restaurar el ítem: {str(e)}</span>'})
            messages.error(request, f"Error al restaurar el ítem: {str(e)}")
            return redirect('restore-items')

        if is_ajax:
            msg = ('<span class="ok-form-response">Ítem restaurado exitosamente.</span>' if ok
                   else '<span class="red-form-response">No se pudo restaurar el ítem.</span>')
            return JsonResponse({'success': ok, 'message': msg})

        messages.success(request, "Ítem restaurado exitosamente.") if ok else messages.error(request, "No se pudo restaurar el ítem.")
        return redirect('restore-items')

    return render(request, 'account/restore_items.html', {
        'characters': characters,
        'deleted_items': deleted_items,
        'selected_character': selected_character,
        'character_names': characters,
    })
def quest_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')
    return render(request, 'account/quest_character.html')
def send_gift_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')
    return render(request, 'account/send_gift.html')    
def customize_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # ?? Obtener información de la cuenta desde acore_auth
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT id, email, last_ip FROM account WHERE username = %s
        """, [username])
        account_info = cursor.fetchone()
        
    if not account_info:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

    account_id, email, acore_ip = account_info
    client_ip = request.META.get('REMOTE_ADDR', '')

    # ?? Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name FROM characters WHERE account = %s
        """, [account_id])
        
        characters = [row[0] for row in cursor.fetchall()]

    # Obtener el precio de la personalización (si se gestiona desde el admin)
    price_obj = CustomizePrice.objects.first()
    price = price_obj.price if price_obj else 1.00

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para personalizar este personaje.</span>'})

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('customize-success'))
        cancel_url = request.build_absolute_uri(reverse('customize-cancel'))
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=price,
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Personalizar personaje: {character_name}"
        )   
        

        if stripe_response["success"]:
            # Guardar temporalmente el nombre del personaje en la sesión
            request.session['customize_character'] = character_name
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/customize_character.html', {'characters': characters, 'price': price})
@require_paid_stripe()
def customize_success_view(request):
    # Procesar el comando SOAP tras el pago exitoso
    character_name = request.session.get('customize_character')
    if not character_name:
        return redirect('customize-character')

    command = f".char customi {character_name}"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha sido marcado para personalización."
        request.session.pop('customize_character', None)  # Limpiar la sesión
        return render(request, 'account/customize_success.html', {'message': message})
    else:
        return render(request, 'account/customize_success.html', {'message': f"Error: {response}"})
def customize_cancel_view(request):
    return render(request, 'account/customize_cancel.html')    
def change_race_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT id, email, last_ip FROM account WHERE username = %s
        """, [username])
        account_info = cursor.fetchone()
        
    if not account_info:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

    account_id, email, acore_ip = account_info
    client_ip = request.META.get('REMOTE_ADDR', '')

    # ?? Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name FROM characters WHERE account = %s
        """, [account_id])
        characters = [row[0] for row in cursor.fetchall()]

    # Obtener el precio del cambio de raza
    price_obj = ChangeRacePrice.objects.first()
    price = price_obj.price if price_obj else 10.00  # Precio predeterminado si no hay registro

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para cambiar la raza de este personaje.</span>'})

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('change-race-success'))
        cancel_url = request.build_absolute_uri(reverse('change-race-cancel'))
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=price,
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Cambio de Raza del personaje: {character_name}"
        )

        if stripe_response["success"]:
            # Guardar el personaje en la sesión para el cambio
            request.session['change_race_character'] = character_name
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/change_race.html', {'characters': characters, 'price': price})
@require_paid_stripe()
def change_race_success_view(request):
    # Procesar el comando SOAP tras el pago exitoso
    character_name = request.session.get('change_race_character')
    if not character_name:
        return redirect('change-race')

    command = f".char changerace {character_name}"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha sido marcado para cambio de raza."
        request.session.pop('change_race_character', None)  # Limpiar la sesión
        return render(request, 'account/change_race_success.html', {'message': message})
    else:
        return render(request, 'account/change_race_success.html', {'message': f"Error: {response}"})
def change_race_cancel_view(request):
    return render(request, 'account/change_race_cancel.html')
def change_faction_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT id, email, last_ip FROM account WHERE username = %s
        """, [username])
        account_info = cursor.fetchone()
            
    if not account_info:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

    account_id, email, acore_ip = account_info
    client_ip = request.META.get('REMOTE_ADDR', '')

    # ?? Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name FROM characters WHERE account = %s
        """, [account_id])    
        characters = [row[0] for row in cursor.fetchall()]

    # Obtener el precio del cambio de facción
    price_obj = ChangeFactionPrice.objects.first()
    price = price_obj.price if price_obj else 10.00

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para cambiar la facción de este personaje.</span>'})

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('change-faction-success'))
        cancel_url =  request.build_absolute_uri(reverse('change-faction-cancel'))
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=price,
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Cambiar Faccion del personaje: {character_name}"
        )   

        if stripe_response["success"]:
            # Guardar el personaje seleccionado en la sesión
            request.session['change_faction_character'] = character_name
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/change_faction.html', {'characters': characters, 'price': price})
@require_paid_stripe()
def change_faction_success_view(request):
    # Procesar el comando SOAP tras el pago exitoso
    character_name = request.session.get('change_faction_character')
    if not character_name:
        return redirect('change-faction-character')

    command = f".char changef {character_name}"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha cambiado de facción con éxito."
        request.session.pop('change_faction_character', None)  # Limpiar la sesión
        return render(request, 'account/change_faction_success.html', {'message': message})
    else:
        return render(request, 'account/change_faction_success.html', {'message': f"Error: {response}"})
def change_faction_cancel_view(request):
    return render(request, 'account/change_faction_cancel.html')
def level_up_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT id, email, last_ip FROM account WHERE username = %s
        """, [username])
        account_info = cursor.fetchone()
        
    if not account_info:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

    account_id, email, acore_ip = account_info
    client_ip = request.META.get('REMOTE_ADDR', '')

    # ?? Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name FROM characters WHERE account = %s
        """, [account_id])
        characters = [row[0] for row in cursor.fetchall()]

    # Obtener el precio de subir a nivel 80
    price_obj = LevelUpPrice.objects.first()
    price = price_obj.price if price_obj else 10.00

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para subir de nivel a este personaje.</span>'})

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('level-up-success'))
        cancel_url = request.build_absolute_uri(reverse('level-up-cancel'))
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=price,
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Subir el Nivel 80 del personaje: {character_name}"
            )

        if stripe_response["success"]:
            # Guardar el personaje en la sesión para usarlo después del pago
            request.session['levelup_character'] = character_name
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/level_up.html', {'characters': characters, 'price': price})
@require_paid_stripe()
def level_up_success_view(request):
    character_name = request.session.get('levelup_character')
    if not character_name:
        return redirect('level-up-character')

    # Ejecutar el comando SOAP
    command = f".char level {character_name} 80"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha sido subido al nivel 80."
    else:
        message = f"Error: {response}"

    # Limpiar la sesión
    request.session.pop('levelup_character', None)

    return render(request, 'account/level_up_success.html', {'message': message})
def level_up_cancel_view(request):
    return render(request, 'account/level_up_cancel.html')
def gold_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes y estado de conexión del usuario
    try:
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute("""
                SELECT id, email, last_ip FROM account WHERE username = %s
            """, [username])
            account_info = cursor.fetchone()

        if not account_info:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error: Cuenta no encontrada.</span>'})

        account_id, email, acore_ip = account_info
        client_ip = request.META.get('REMOTE_ADDR', '')

        # Obtener personajes del usuario desde la base de datos `acore_characters`
        with connections['acore_characters'].cursor() as cursor:
            cursor.execute("""
                SELECT name, online, money FROM characters WHERE account = %s
            """, [account_id])
            characters_data = cursor.fetchall()

        characters = {row[0]: {'online': row[1], 'money': row[2]} for row in characters_data}

    except Exception as e:
        return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al obtener los personajes: {str(e)}</span>'})

    # Obtener precios del oro
    gold_prices = GoldPrice.objects.all().order_by('gold_amount')

    if request.method == 'POST':
        character_name = request.POST.get('character')
        gold_amount = request.POST.get('gold_amount')

        # Validaciones iniciales
        if not character_name or not gold_amount:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Seleccione un personaje y una cantidad de oro.</span>'})

        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para enviar oro a este personaje.</span>'})

        if characters[character_name]['online'] == 1:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje debe estar desconectado para recibir oro.</span>'})

        try:
            gold_amount = int(gold_amount)
        except ValueError:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Cantidad de oro no válida.</span>'})

        gold_price = GoldPrice.objects.filter(gold_amount=gold_amount).first()
        if not gold_price:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Cantidad de oro no válida.</span>'})

        # El precio va en euros (con decimales); el helper lo pasa a céntimos (×100)
        stripe_price = gold_price.price

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('gold-success'))
        cancel_url = request.build_absolute_uri(reverse('gold-cancel'))
        
        # Llamada corregida a create_checkout_session con todos los parámetros requeridos
        stripe_response = create_checkout_session(
            account_id=account_id,
            username=username,
            email=email,
            acore_ip=acore_ip,
            amount=stripe_price,  # El precio calculado
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Aumentar el Oro: {gold_amount} al Personaje: {character_name}"
        )

        if stripe_response["success"]:
            # Guardar en sesión los datos para el callback tras el pago
            request.session['gold_transaction'] = {
                'character_name': character_name,
                'gold_amount': gold_amount
            }
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/gold_character.html', {
        'characters': characters,
        'gold_prices': gold_prices,
        'character_names': list(characters.keys()),
        'gold_options': [{'gold_amount': p.gold_amount, 'price': str(p.price)} for p in gold_prices],
    })
@require_paid_stripe()
def gold_success_view(request):
    # Procesar el pago exitoso
    transaction = request.session.pop('gold_transaction', None)
    if not transaction:
        return redirect('gold-character')

    character_name = transaction['character_name']
    gold_amount = int(transaction['gold_amount'])

    # Calcular el oro en formato del juego
    game_gold_amount = gold_amount * 10000

    # Actualizar la cantidad de oro en la base de datos
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            UPDATE characters
            SET money = money + %s
            WHERE name = %s
        """, [game_gold_amount, character_name])

    return render(request, 'account/gold_success.html', {'character_name': character_name, 'gold_amount': gold_amount})
def gold_cancel_view(request):
    return render(request, 'account/gold_cancel.html')
def transfer_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener el precio de transferencia
    price_obj = TransferPrice.objects.first()
    price = price_obj.price if price_obj else 10.00

    # Obtener el ID de usuario desde acore_auth.account
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("SELECT id, email, last_ip FROM account WHERE username = %s", [username])
        user_data = cursor.fetchone()
    if not user_data:
        return JsonResponse({'success': False, 'message': '<span class="red-form-response">Cuenta no encontrada. Por favor, inicie sesión nuevamente.</span>'})

    user_id, email, acore_ip = user_data  # ID de la cuenta, email y la última IP

    # Obtener personajes de la cuenta de origen
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name, class, online
            FROM characters
            WHERE account = %s
        """, [user_id])
        characters = cursor.fetchall()

    if request.method == 'POST':
        character_name = request.POST.get('character')
        destination_account = request.POST.get('destination_account')
        token = request.POST.get('security_token')

        # Validaciones
        if not all([character_name, destination_account, token]):
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, complete todos los campos.</span>'})

        character = next((char for char in characters if char[0] == character_name), None)
        if not character:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para transferir este personaje.</span>'})

        # Verificar si el personaje está desconectado
        if character[2] == 1:  # Si está conectado
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje debe estar desconectado para ser transferido.</span>'})

        # Verificar el token de seguridad
        security_token = SecurityToken.objects.filter(user_id=user_id, token=token).first()
        if not security_token:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Token de seguridad incorrecto.</span>'})

        # Verificar si el token ha expirado
        if security_token.expires_at < timezone.now():
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El token ha expirado. Solicite uno nuevo.</span>'})

        # Verificar si la cuenta de destino existe
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute("SELECT id FROM account WHERE username = %s", [destination_account])
            destination_account_data = cursor.fetchone()

        if not destination_account_data:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">La cuenta de destino no existe.</span>'})

        # Verificar restricciones en la cuenta de destino
        destination_account_id = destination_account_data[0]
        with connections['acore_characters'].cursor() as cursor:
            cursor.execute("""
                SELECT account, name, class, level, online
                FROM characters
                WHERE account = %s
            """, [destination_account_id])
            destination_characters = cursor.fetchall()

        if not any(char[3] >= 55 and char[2] != 6 for char in destination_characters):
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">La cuenta destino debe tener al menos un personaje de nivel 55 o superior que no sea Caballero de la Muerte.</span>'})

        if any(char[2] == 6 for char in destination_characters):
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">La cuenta destino no puede tener un Caballero de la Muerte.</span>'})

        # Verificar que ninguna cuenta esté online
        for char in destination_characters:
            if char[4] == 1:
                return JsonResponse({'success': False, 'message': '<span class="red-form-response">Todos los personajes de la cuenta destino deben estar desconectados.</span>'})
        for char in characters:
            if char[2] == 1:
                return JsonResponse({'success': False, 'message': '<span class="red-form-response">Todos los personajes de la cuenta origen deben estar desconectados.</span>'})

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('transfer-success'))
        cancel_url = request.build_absolute_uri(reverse('transfer-cancel'))
        
        # Llamada corregida a create_checkout_session con todos los parámetros requeridos
        stripe_response = create_checkout_session(
            username=username,
            email=email,
            acore_ip=acore_ip,
            account_id=user_id,  # Pasar el account_id
            amount=price,  # El precio de la transferencia
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Transferir el personaje: {character_name} a la cuenta de destino: {destination_account}"
        )

        if stripe_response["success"]:
            # Guardar los datos de la transferencia en la sesión para usarlos después del pago
            request.session['transfer_data'] = {
                'character_name': character_name,
                'destination_account': destination_account
            }
            return JsonResponse({
                'success': True,
                'session_id': stripe_response["session_id"],
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY
            })
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error al iniciar el pago: {stripe_response["error"]}</span>'})

    return render(request, 'account/transfer_character.html', {
        'characters': characters,
        'price': price,
        'character_names': [c[0] for c in characters],
    })
@require_paid_stripe()
def transfer_success_view(request):
    transfer_data = request.session.get('transfer_data')
    if not transfer_data:
        return redirect('transfer-character')

    character_name = transfer_data['character_name']
    destination_account = transfer_data['destination_account']

    # Ejecutar comando SOAP
    command = f".char changeaccount {destination_account} {character_name}"
    response = execute_soap_command(command)

    if response is None or response.strip() == "":
        message = f"El personaje {character_name} ha sido transferido a la cuenta {destination_account}."
        request.session.pop('transfer_data', None)  # Limpiar sesión
        return render(request, 'account/transfer_success.html', {'message': message})
    else:
        return render(request, 'account/transfer_success.html', {'message': f"Error: {response}"})
def transfer_cancel_view(request):
    return render(request, 'account/transfer_cancel.html')  
def revive_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name, online
            FROM characters
            WHERE account = (
                SELECT id 
                FROM acore_auth.account 
                WHERE username = %s
            )
        """, [username])
        characters_data = cursor.fetchall()
        characters = {row[0]: row[1] for row in characters_data}  # Diccionario con nombre y estado de conexión

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para revivir este personaje.</span>'})

        # Verificar si el personaje está desconectado
        if characters[character_name] == 1:  # Si está conectado
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje debe estar desconectado para ser revivido.</span>'})

        # Verificar el historial de uso del comando `revive`
        last_revive = ReviveHistory.objects.filter(character_name=character_name).order_by('-used_at').first()
        if last_revive and last_revive.used_at > now() - timedelta(hours=12):
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje solo puede revivirse una vez cada 12 horas.</span>'})

        # Ejecutar el comando SOAP
        command = f".revive {character_name}"
        response = execute_soap_command(command)

        # None = fallo de comunicación con el servidor
        if response is None:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error de comunicación con el servidor. Intente nuevamente más tarde.</span>'})

        # Respuesta vacía = éxito (el comando .revive no devuelve texto si va bien)
        if response.strip() == "":
            ReviveHistory.objects.create(character_name=character_name, used_at=now())
            return JsonResponse({'success': True, 'message': f'<span class="ok-form-response">El personaje {character_name} ha sido revivido con éxito.</span>'})

        # Respuesta no vacía = el servidor devolvió un mensaje/error
        return JsonResponse({'success': False, 'message': f'<span class="red-form-response">{response}</span>'})

    return render(request, 'account/revive_character.html', {'characters': characters.keys()})
def unstuck_character_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    # Obtener personajes del usuario desde la base de datos `acore_characters`
    with connections['acore_characters'].cursor() as cursor:
        cursor.execute("""
            SELECT name, online
            FROM characters
            WHERE account = (
                SELECT id 
                FROM acore_auth.account 
                WHERE username = %s
            )
        """, [username])
        characters_data = cursor.fetchall()
        characters = {row[0]: row[1] for row in characters_data}  # Diccionario con nombre y estado de conexión

    if request.method == 'POST':
        character_name = request.POST.get('character')

        # Validar si el personaje fue seleccionado
        if not character_name:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, seleccione un personaje.</span>'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">No tienes permiso para desbloquear este personaje.</span>'})

        # Verificar si el personaje está desconectado
        if characters[character_name] == 1:  # Si está conectado
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje debe estar desconectado para ser desbloqueado.</span>'})

        # Verificar el historial de uso del comando
        last_unstuck = UnstuckHistory.objects.filter(character_name=character_name).order_by('-used_at').first()
        if last_unstuck and last_unstuck.used_at > now() - timedelta(hours=12):
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">El personaje solo puede desbloquearse una vez cada 12 horas.</span>'})

        # Ejecutar el comando SOAP
        command = f".unstuck {character_name} startzone"
        response = execute_soap_command(command)

        if response is None:
            return JsonResponse({'success': False, 'message': '<span class="red-form-response">Error de comunicación con el servidor. Intente nuevamente más tarde.</span>'})

        # Analizar la respuesta
        if f"You are summoning {character_name} (offline)" in response:
            # Registrar el uso del comando
            UnstuckHistory.objects.create(character_name=character_name, used_at=now())
            return JsonResponse({'success': True, 'message': f'<span class="ok-form-response">El personaje {character_name} ha sido desbloqueado con éxito.</span>'})
        else:
            return JsonResponse({'success': False, 'message': f'<span class="red-form-response">Error: {response}</span>'})

    return render(request, 'account/unstuck_character.html', {'characters': characters.keys()})
