from ._base import *


def store_novawow_cancel_view(request):
    return render(request, 'store/store_novawow_cancel.html')  
def store_novawow_view(request):
    username = request.session.get('username')
    if not username:
        return redirect('login')

    category_name = request.GET.get("category")

    # 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 = (
                SELECT id 
                FROM acore_auth.account 
                WHERE username = %s
            )
        """, [username])
        characters = [row[0] for row in cursor.fetchall()]

    # Obtener categorías e ítems
    categories = Category.objects.prefetch_related("items").all()
    store_data = {category.name: list(category.items.values()) for category in categories}

    # Si se está solicitando una categoría específica, devolver solo los ítems de esa categoría
    if category_name:
        try:
            category = Category.objects.get(name=category_name)
        except Category.DoesNotExist:
            return JsonResponse({'success': False, 'message': 'Categoría no encontrada'}, status=404)
        return JsonResponse({'success': True, 'items': list(category.items.values())})

    # Obtener carrito desde la sesión
    carrito = request.session.get('carrito', [])

    # Calcular el precio total con 2 decimales
    total_price = sum(Decimal(item['precio']) for item in carrito)
    total_price_with_iva = (total_price * Decimal('1.21')).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

    if request.method == 'POST':
        # Obtener datos del body
        data = json.loads(request.body)
        character_name = data.get('character')
        carrito_cliente = data.get('carrito') or []

        if not character_name:
            return JsonResponse({'success': False, 'message': 'Por favor, selecciona un personaje.'})

        # Verificar si el personaje pertenece al usuario
        if character_name not in characters:
            return JsonResponse({'success': False, 'message': 'No tienes permiso para este personaje.'})

        if not carrito_cliente:
            return JsonResponse({'success': False, 'message': 'El carrito está vacío.'})

        # VALIDAR ÍTEMS Y PRECIOS CONTRA LA BASE DE DATOS (nunca confiar en el
        # precio ni en los ítems que manda el cliente).
        try:
            ids_solicitados = [int(item['id']) for item in carrito_cliente]
        except (KeyError, TypeError, ValueError):
            return JsonResponse({'success': False, 'message': 'Carrito no válido.'})

        items_db = {i.item_id: i for i in Item.objects.filter(item_id__in=ids_solicitados)}

        carrito = []          # carrito saneado que se guardará en sesión
        total_price = Decimal('0.00')
        for item in carrito_cliente:
            item_id = int(item['id'])
            db_item = items_db.get(item_id)
            if not db_item:
                return JsonResponse({'success': False, 'message': f'Ítem no disponible en la tienda (ID {item_id}).'})
            try:
                cantidad = max(1, int(item.get('cantidad', 1)))
            except (TypeError, ValueError):
                cantidad = 1
            total_price += db_item.price * cantidad
            carrito.append({'id': item_id, 'nombre': db_item.name, 'cantidad': cantidad})

        total_price_with_iva = (total_price * Decimal('1.21')).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

        # Guardar en sesión el carrito YA VALIDADO (para la entrega tras el pago)
        request.session['carrito'] = carrito
        request.session.modified = True

        # Descripción del producto a partir de los datos validados
        product_description = ", ".join([f"{it['nombre']} x{it['cantidad']}" for it in carrito])

        # Obtener detalles del usuario
        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': 'Cuenta no encontrada.'})

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

        # Crear sesión de pago con Stripe
        success_url = request.build_absolute_uri(reverse('store-novawow/success'))
        cancel_url = request.build_absolute_uri(reverse('store-novawow/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=total_price_with_iva,  # El precio con IVA
            character_name=character_name,
            success_url=success_url,
            cancel_url=cancel_url,
            product_name=f"Compra de ítems para el personaje: {character_name} : {product_description}"
        )

        if stripe_response["success"]:
            request.session['store_novawow'] = 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'Error al iniciar el pago: {stripe_response["error"]}'})    

    return render(request, 'store/store_novawow.html', {
        'characters': characters,
        'store_data': store_data,
        'categories': categories,
        'total_price': total_price_with_iva
    })
@require_paid_stripe(redirect_to='store-novawow')
def store_novawow_success_view(request):
    # Procesar el comando SOAP tras el pago exitoso
    character_name = request.session.get('store_novawow')
    carrito = request.session.get('carrito', [])

    if not character_name or not carrito:
        return redirect('store-novawow')

    # Contar correctamente los ítems por ID
    item_counts = Counter(item["id"] for item in carrito)

    # Generar la lista de ítems en formato "ID:Cantidad"
    items_str = " ".join(f"{item_id}:{count}" for item_id, count in item_counts.items())

    # Construir el comando SOAP
    command = f".send items {character_name} 'Gracias por donar a Nova WoW' 'Aquí tienes tu donación' {items_str}"

    # Ejecutar el comando SOAP
    response = execute_soap_command(command)

    # Limpiar la sesión después del envío
    request.session.pop('store_novawow', None)
    request.session.pop('carrito', None)

    if response is None or response.strip() == "":
        message = f"Los ítems han sido añadidos al personaje {character_name} correctamente."
        return render(request, 'store/store_novawow_success.html', {'message': message})
    else:
        return render(request, 'store/store_novawow_success.html', {'message': f"Error: {response}"})
def store_novawow_buscar_categoria_view(request, categoria):
    try:
        # Buscar la categoría desde el parámetro de la URL
        category = Category.objects.get(name=categoria)
        items = category.items.all().values("id", "name", "price", "image_url")
        return JsonResponse({"success": True, "items": list(items)})
    except Category.DoesNotExist:
        return JsonResponse({"success": False, "message": "Categoría no encontrada"}, status=404)
