<?php
header('Content-Type: application/json; charset=utf-8');
ini_set('display_errors', 0);
error_reporting(E_ALL);

require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/includes/db.php';
require_once dirname(__DIR__) . '/includes/auth.php';
require_once dirname(__DIR__) . '/includes/functions.php';
require_once dirname(__DIR__) . '/includes/api.php';

apiRequireMethod('POST');
apiRequireCsrf();

$name = trim((string)($_POST['name'] ?? ''));
$description = trim((string)($_POST['description'] ?? ''));
$rawSongIds = (string)($_POST['song_ids'] ?? '[]');
$decoded = json_decode($rawSongIds, true);

if ($name === '') {
    apiError('플레이리스트 이름을 입력해 주세요.', 'invalid_name', 400);
}

if (!is_array($decoded)) {
    apiError('저장할 대기열 정보가 올바르지 않습니다.', 'invalid_queue', 400);
}

$songIds = [];
$seen = [];
foreach ($decoded as $songId) {
    $id = (int)$songId;
    if ($id <= 0 || isset($seen[$id])) {
        continue;
    }
    $seen[$id] = true;
    $songIds[] = $id;
    if (count($songIds) >= 300) {
        break;
    }
}

if (empty($songIds)) {
    apiError('저장할 곡이 없습니다.', 'empty_queue', 400);
}

try {
    $pdo = getDBConnection();
    $placeholders = [];
    $params = [];
    foreach ($songIds as $idx => $songId) {
        $key = ':song_' . $idx;
        $placeholders[] = $key;
        $params[$key] = $songId;
    }

    $checkSql = "
        SELECT id
        FROM songs
        WHERE id IN (" . implode(',', $placeholders) . ")
          AND COALESCE(is_missing, 0) = 0
          AND COALESCE(is_hidden, 0) = 0
    ";
    $stmt = $pdo->prepare($checkSql);
    $stmt->execute($params);
    $validIds = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
    $validSet = array_fill_keys($validIds, true);
    $orderedIds = array_values(array_filter($songIds, static function ($id) use ($validSet) {
        return isset($validSet[(int)$id]);
    }));

    if (empty($orderedIds)) {
        apiError('저장 가능한 곡이 없습니다.', 'no_valid_songs', 400);
    }

    $safeName = function_exists('mb_substr') ? mb_substr($name, 0, 255, 'UTF-8') : substr($name, 0, 255);
    $safeDescription = $description !== ''
        ? (function_exists('mb_substr') ? mb_substr($description, 0, 1000, 'UTF-8') : substr($description, 0, 1000))
        : null;

    $pdo->beginTransaction();

    $insertPlaylist = $pdo->prepare("
        INSERT INTO playlists (name, description, display_scope)
        VALUES (:name, :description, 'private')
    ");
    $insertPlaylist->execute([
        ':name' => $safeName,
        ':description' => $safeDescription,
    ]);
    $playlistId = (int)$pdo->lastInsertId();

    $insertSong = $pdo->prepare("
        INSERT INTO playlist_songs (playlist_id, song_id, sort_order)
        VALUES (:playlist_id, :song_id, :sort_order)
    ");
    foreach ($orderedIds as $order => $songId) {
        $insertSong->execute([
            ':playlist_id' => $playlistId,
            ':song_id' => (int)$songId,
            ':sort_order' => $order + 1,
        ]);
    }

    $pdo->commit();

    if (function_exists('writeAppLog')) {
        writeAppLog('info', 'queue_playlist_saved', 'Queue saved as playlist', [
            'playlist_id' => $playlistId,
            'song_count' => count($orderedIds),
        ]);
    }

    apiSuccess([
        'playlist_id' => $playlistId,
        'song_count' => count($orderedIds),
        'url' => 'playlist_view.php?id=' . $playlistId,
    ], '대기열을 플레이리스트로 저장했습니다.');
} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    if (function_exists('writeAppLog')) {
        writeAppLog('error', 'queue_playlist_save_error', 'Queue playlist save failed', [
            'song_count' => count($songIds),
            'error' => $e->getMessage(),
        ]);
    }
    apiError('대기열을 플레이리스트로 저장하지 못했습니다.', 'server_error', 500);
}
