query("SELECT *, UNIX_TIMESTAMP(created_at) as started_at FROM song_requests WHERE status = 'played' ORDER BY created_at DESC LIMIT 1"); $lastPlayed = $stmt->fetch(); $isLocalActive = false; if ($lastPlayed) { $duration = (int)($lastPlayed['duration'] ?? 240); $endTime = $lastPlayed['started_at'] + $duration; if (time() < $endTime) { $isLocalActive = true; } } // 2. If no local song is active, check if RadioKing is playing something we should wait for $shouldWait = $isLocalActive; if (!$isLocalActive) { // Optional: Check RadioKing current track end_at try { $radioKingUrl = 'https://www.radioking.com/widgets/api/v1/radio/828046/track/current'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $radioKingUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 3); $resp = curl_exec($ch); curl_close($ch); if ($resp) { $data = json_decode($resp, true); if (isset($data['end_at'])) { $endAt = strtotime($data['end_at']); // If the RadioKing song ends in more than 5 seconds, we wait if ($endAt > (time() + 5)) { $shouldWait = true; } } } } catch (Exception $e) { // Ignore RadioKing errors and proceed } } if (!$shouldWait) { // 3. Take the oldest pending request and "execute" it $stmt = $db->query("SELECT * FROM song_requests WHERE status = 'pending' ORDER BY is_priority DESC, created_at ASC LIMIT 1"); $next = $stmt->fetch(); if ($next) { // Find YouTube info before playing if missing $youtubeUrl = $next['youtube_url']; $duration = $next['duration'] ?? 240; if (!$youtubeUrl) { try { require_once __DIR__ . '/../ai/LocalAIApi.php'; $artist = $next['artist']; $song = $next['song']; $aiResp = LocalAIApi::createResponse([ 'input' => [ ['role' => 'system', 'content' => 'Eres un asistente de radio. Tu tarea es encontrar el ID de YouTube oficial y la duración aproximada en segundos para una canción. Responde ÚNICAMENTE con un JSON: {"id": "...", "duration": ...}. Si no estás seguro, usa id null y duration 240.'], ['role' => 'user', 'content' => "Encuentra el ID de YouTube y duración para: $artist - $song"] ] ]); if (!empty($aiResp['success'])) { $jsonText = LocalAIApi::extractText($aiResp); $data = json_decode($jsonText, true); if ($data && isset($data['id']) && $data['id'] !== null) { $youtubeUrl = "https://www.youtube.com/watch?v={$data['id']}"; $duration = (int)($data['duration'] ?? 240); } } } catch (Exception $e) {} } $stmt = $db->prepare("UPDATE song_requests SET status = 'played', youtube_url = ?, duration = ?, created_at = NOW() WHERE id = ?"); $stmt->execute([$youtubeUrl, $duration, $next['id']]); // Log automation $db->prepare("INSERT INTO automation_logs (message) VALUES (?)")->execute(["Auto-DJ ejecutó: {$next['artist']} - {$next['song']}"]); // Announce in chat $chatMsg = "🤖 [AUTO-DJ] Es el turno de: **{$next['artist']} - {$next['song']}** (Pedido por: **{$next['requester']}**) 🎧🔥"; $db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]); echo json_encode(['success' => true, 'action' => 'executed', 'song' => $next['song']]); exit; } } echo json_encode(['success' => true, 'action' => 'none']); } catch (Exception $e) { echo json_encode(['success' => false, 'error' => $e->getMessage()]); }