false,'error'=>'rasca_id inválido']); exit; } // Premios activos con stock (NULL = ilimitado) $sql = "SELECT id, nombre, probabilidad, stock, activo, imagen_url FROM rasca_premios WHERE rasca_id=? AND activo=1 AND (stock IS NULL OR stock > 0) AND probabilidad > 0"; $st = $conn->prepare($sql); $st->bind_param('i', $rasca_id); $st->execute(); $st->bind_result($id, $nombre, $prob, $stock, $activo, $img); $premios = []; $total = 0.0; while ($st->fetch()) { $prob = (float)$prob; $premios[] = [ 'id' => (int)$id, 'nombre' => $nombre, 'prob' => $prob, 'stock' => is_null($stock) ? null : (int)$stock, 'imagen_url' => $img ?: null ]; $total += max(0.0, $prob); } $st->close(); $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? null; $ua = $_SERVER['HTTP_USER_AGENT'] ?? null; if (!$premios) { // Sin premios disponibles: registra jugada sin premio $conn->prepare("INSERT INTO jugadas_rasca (rasca_id, ip_address, user_agent, porcentaje, premio_id) VALUES (?,?,?,?,NULL)") ->bind_param('issd', $rasca_id, $ip, $ua, $porcentaje) ->execute(); echo json_encode(['ok'=>true,'sin_premio'=>true,'mensaje'=>'No hay premios activos o con stock']); exit; } if ($total <= 0) { echo json_encode(['ok'=>false,'error'=>'Probabilidades inválidas']); exit; } // Selección ponderada $rnd = mt_rand() / mt_getrandmax() * $total; $acc = 0.0; $pick = null; foreach ($premios as $p) { $acc += max(0.0, $p['prob']); if ($rnd <= $acc) { $pick = $p; break; } } if ($pick === null) $pick = $premios[0]; // Transacción: descontar stock (si aplica) y registrar jugada $conn->begin_transaction(); if ($pick['stock'] !== null) { $upd = $conn->prepare("UPDATE rasca_premios SET stock = stock - 1 WHERE id=? AND stock > 0"); $upd->bind_param('i', $pick['id']); $upd->execute(); if ($upd->affected_rows === 0) { $conn->rollback(); // stock se agotó en carrera; registra jugada sin premio $conn->prepare("INSERT INTO jugadas_rasca (rasca_id, ip_address, user_agent, porcentaje, premio_id) VALUES (?,?,?,?,NULL)") ->bind_param('issd', $rasca_id, $ip, $ua, $porcentaje) ->execute(); echo json_encode(['ok'=>true,'sin_premio'=>true,'mensaje'=>'Stock agotado']); exit; } } $ins = $conn->prepare("INSERT INTO jugadas_rasca (rasca_id, ip_address, user_agent, porcentaje, premio_id) VALUES (?,?,?,?,?)"); $ins->bind_param('issdi', $rasca_id, $ip, $ua, $porcentaje, $pick['id']); $ins->execute(); $conn->commit(); echo json_encode([ 'ok' => true, 'premio' => $pick['nombre'], 'premio_id' => $pick['id'], 'imagen_url' => $pick['imagen_url'] ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } catch (Throwable $e) { @mysqli_rollback($conn); echo json_encode(['ok'=>false,'error'=>'No hay articulos en stock.']); //echo json_encode(['ok'=>false,'error'=>'Sorteo falló: '.$e->getMessage()]); }