<?php
/**
 * StudyTrack — Advanced Music Page (YouTube powered + manual uploads)
 * ────────────────────────────────────────────────────────────────
 * Music streams through embedded YouTube players, plus users can manually
 * upload their own audio files (MP3 / WAV / OGG / M4A, 5MB max each).
 *   • Curated playlists (Lofi / Focus / Classical)
 *   • Live YouTube search (videos & playlists)
 *   • Favorites (saved to DB per user)
 *   • My Songs — manual per-user uploads, max 5MB/file, stored under uploads/user_songs/{uid}/
 *   • Focus Timer — logs completed sessions into study_sessions/study_streaks
 *
 * Requires: YOUTUBE_API_KEY in includes/config.php
 *           (a plain API key from console.cloud.google.com with "YouTube Data API v3"
 *           enabled — no OAuth/user login needed for search & embeds)
 * Requires: database_youtube_music.sql to be run once (youtube_favorites + user_songs tables)
 * Requires: 'uploads/user_songs/' to be writable by the web server (chmod 755, created automatically)
 * Note: if your php.ini has upload_max_filesize or post_max_size below 5M, uploads
 *       will fail before reaching this script — raise both to at least 6M.
 */

require_once 'includes/config.php';
require_once 'includes/functions.php';
requireLogin();
$uid = $_SESSION['user_id'];

// ── YouTube Data API v3 helper — plain API key, no OAuth needed ──
function youtubeApiGet($endpoint, $params) {
    if (YOUTUBE_API_KEY === '') return null;
    if (!function_exists('curl_init')) return null;

    $params['key'] = YOUTUBE_API_KEY;
    $ch = curl_init('https://www.googleapis.com/youtube/v3/' . $endpoint . '?' . http_build_query($params));
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 8,
    ]);
    $res  = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($code !== 200 || !$res) return null;
    return json_decode($res, true);
}

// ── Manually uploaded songs config (must be defined BEFORE the AJAX block,
//    since the upload_song action below uses these constants) ──
define('MP_MAX_UPLOAD_BYTES', 5 * 1024 * 1024); // hard 5 MB limit
define('MP_UPLOAD_DIR', __DIR__ . '/uploads/user_songs/');
define('MP_ALLOWED_EXT', ['mp3', 'wav', 'ogg', 'm4a']);
define('MP_ALLOWED_MIME', ['audio/mpeg', 'audio/mp3', 'audio/wav', 'audio/x-wav', 'audio/wave', 'audio/ogg', 'audio/mp4', 'audio/x-m4a', 'audio/m4a']);

// ── AJAX ─────────────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
    $action = $_POST['action'] ?? '';

    // ── Live search (videos + playlists) ──
    if ($action === 'search') {
        $q = trim($_POST['q'] ?? '');
        if ($q === '') jsonResponse(['success' => false, 'message' => 'Type something to search.']);

        if (YOUTUBE_API_KEY === '') jsonResponse(['success' => false, 'message' => "YouTube isn't configured yet. Add YOUTUBE_API_KEY in includes/config.php."]);

        $quota = checkDailyQuota($uid, 'music_search', 'free_music_search_daily_limit', FREE_MUSIC_SEARCH_DAILY_LIMIT_DEFAULT);
        if (!$quota['allowed']) {
            jsonResponse([
                'success'       => false,
                'limit_reached' => true,
                'message'       => "You've used all {$quota['limit']} free searches today. Upgrade to Pro for unlimited music search.",
            ]);
        }

        $data = youtubeApiGet('search', [
            'part' => 'snippet', 'q' => $q, 'type' => 'video,playlist',
            'maxResults' => 12, 'safeSearch' => 'moderate',
            'topicId' => '/m/04rlf', // restricts results to the "Music" topic only (works for both video & playlist types)
        ]);
        if ($data === null) jsonResponse(['success' => false, 'message' => 'YouTube search failed. Try again.']);

        $results = [];
        foreach (($data['items'] ?? []) as $it) {
            $kind = $it['id']['kind'] ?? '';
            $sn   = $it['snippet'] ?? [];
            if ($kind === 'youtube#video') {
                $results[] = [
                    'id'       => $it['id']['videoId'],
                    'type'     => 'video',
                    'name'     => $sn['title'] ?? '',
                    'subtitle' => $sn['channelTitle'] ?? '',
                    'image'    => $sn['thumbnails']['medium']['url'] ?? ($sn['thumbnails']['default']['url'] ?? ''),
                ];
            } elseif ($kind === 'youtube#playlist') {
                $results[] = [
                    'id'       => $it['id']['playlistId'],
                    'type'     => 'playlist',
                    'name'     => $sn['title'] ?? '',
                    'subtitle' => 'Playlist · ' . ($sn['channelTitle'] ?? 'YouTube'),
                    'image'    => $sn['thumbnails']['medium']['url'] ?? ($sn['thumbnails']['default']['url'] ?? ''),
                ];
            }
        }
        logDailyUsage($uid, 'music_search');
        jsonResponse([
            'success'   => true,
            'results'   => $results,
            'quota'     => $quota['is_pro'] ? null : ['used' => $quota['used'] + 1, 'limit' => $quota['limit'], 'remaining' => max(0, $quota['remaining'] - 1)],
        ]);
    }

    // ── Toggle favorite (add / remove) ──
    if ($action === 'toggle_favorite') {
        $sid  = sanitize($_POST['youtube_id'] ?? '');
        $type = in_array($_POST['type'] ?? '', ['video', 'playlist']) ? $_POST['type'] : 'video';
        $name = sanitize($_POST['name'] ?? '');
        $sub  = sanitize($_POST['subtitle'] ?? '');
        $img  = sanitize($_POST['image_url'] ?? '');

        if (!$sid || !$name) jsonResponse(['success' => false, 'message' => 'Missing data.']);

        $chk = $pdo->prepare("SELECT id FROM youtube_favorites WHERE user_id=? AND youtube_id=?");
        $chk->execute([$uid, $sid]);

        if ($row = $chk->fetch()) {
            $pdo->prepare("DELETE FROM youtube_favorites WHERE id=?")->execute([$row['id']]);
            jsonResponse(['success' => true, 'favorited' => false]);
        } else {
            $pdo->prepare("INSERT INTO youtube_favorites (user_id,youtube_id,type,name,subtitle,thumbnail) VALUES (?,?,?,?,?,?)")
                ->execute([$uid, $sid, $type, $name, $sub, $img]);
            jsonResponse(['success' => true, 'favorited' => true]);
        }
    }

    // ── Focus Timer: log a completed session ──
    if ($action === 'log_session') {
        $subId = (int)($_POST['subject_id'] ?? 0);
        $mins  = max(1, min(180, (int)($_POST['minutes'] ?? 0)));

        if ($subId <= 0) jsonResponse(['success' => false, 'message' => 'Please select a subject first.']);

        $chk = $pdo->prepare("SELECT id FROM subjects WHERE id=? AND user_id=?");
        $chk->execute([$subId, $uid]);
        if (!$chk->fetch()) jsonResponse(['success' => false, 'message' => 'Invalid subject.']);

        $date = date('Y-m-d');
        $pdo->prepare("INSERT INTO study_sessions (user_id,subject_id,date,duration_minutes,notes) VALUES (?,?,?,?,?)")
            ->execute([$uid, $subId, $date, $mins, 'Focus Timer session (Music page)']);
        $pdo->prepare("INSERT INTO study_streaks (user_id,date,minutes_studied) VALUES (?,?,?)
                       ON DUPLICATE KEY UPDATE minutes_studied = minutes_studied + ?")
            ->execute([$uid, $date, $mins, $mins]);

        jsonResponse(['success' => true, 'message' => "Session saved — {$mins} min logged!"]);
    }

    // ── Upload a song manually (max 5MB, audio files only) ──
    if ($action === 'upload_song') {
        if (empty($_FILES['song_file']) || !is_array($_FILES['song_file'])) {
            jsonResponse(['success' => false, 'message' => 'Please choose a file to upload.']);
        }
        $file = $_FILES['song_file'];

        // ── Upload-level errors (also catches files rejected by php.ini before reaching us) ──
        if ($file['error'] === UPLOAD_ERR_INI_SIZE || $file['error'] === UPLOAD_ERR_FORM_SIZE) {
            jsonResponse(['success' => false, 'message' => 'File is too large — max 5MB allowed.']);
        }
        if ($file['error'] !== UPLOAD_ERR_OK) {
            jsonResponse(['success' => false, 'message' => 'Upload failed (error code ' . (int)$file['error'] . '). Please try again.']);
        }

        // ── Hard 5MB limit ──
        if ($file['size'] <= 0 || $file['size'] > MP_MAX_UPLOAD_BYTES) {
            jsonResponse(['success' => false, 'message' => 'File is too large — max 5MB allowed.']);
        }

        // ── Extension whitelist ──
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, MP_ALLOWED_EXT, true)) {
            jsonResponse(['success' => false, 'message' => 'Only MP3, WAV, OGG or M4A files are allowed.']);
        }

        // ── Real MIME check (don't trust the extension/client alone) ──
        $mime = '';
        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime  = finfo_file($finfo, $file['tmp_name']) ?: '';
            finfo_close($finfo);
        }
        if ($mime !== '' && !in_array($mime, MP_ALLOWED_MIME, true)) {
            jsonResponse(['success' => false, 'message' => 'That file does not look like a valid audio file.']);
        }

        // ── Row limit so one user can't fill the disk ──
        $cnt = $pdo->prepare("SELECT COUNT(*) FROM user_songs WHERE user_id=?");
        $cnt->execute([$uid]);
        if ((int)$cnt->fetchColumn() >= 100) {
            jsonResponse(['success' => false, 'message' => 'Upload limit reached (100 songs). Delete an old one first.']);
        }

        $title = sanitize($_POST['title'] ?? '');
        if ($title === '') $title = pathinfo($file['name'], PATHINFO_FILENAME);
        $title = mb_substr($title, 0, 150);

        $userDir = MP_UPLOAD_DIR . (int)$uid . '/';
        if (!is_dir($userDir) && !mkdir($userDir, 0755, true) && !is_dir($userDir)) {
            jsonResponse(['success' => false, 'message' => 'Server could not create upload folder.']);
        }
        // Lock the folder down: block script execution of anything inside it.
        $htaccess = MP_UPLOAD_DIR . '.htaccess';
        if (!file_exists($htaccess)) {
            @file_put_contents($htaccess, "php_flag engine off\n<FilesMatch \"\\.(php|phtml|php\\d?|pht|phar)$\">\nRequire all denied\n</FilesMatch>\n");
        }

        $safeName = bin2hex(random_bytes(16)) . '.' . $ext;
        $destPath = $userDir . $safeName;

        if (!move_uploaded_file($file['tmp_name'], $destPath)) {
            jsonResponse(['success' => false, 'message' => 'Could not save the uploaded file. Please try again.']);
        }

        $relPath = 'uploads/user_songs/' . (int)$uid . '/' . $safeName;
        $pdo->prepare("INSERT INTO user_songs (user_id,title,filename,filepath,filesize,created_at) VALUES (?,?,?,?,?,NOW())")
            ->execute([$uid, $title, $safeName, $relPath, $file['size']]);
        $newId = (int)$pdo->lastInsertId();

        jsonResponse(['success' => true, 'message' => 'Song uploaded!', 'song' => [
            'id'       => $newId,
            'title'    => $title,
            'filepath' => $relPath,
            'filesize' => (int)$file['size'],
        ]]);
    }

    // ── Delete a manually uploaded song ──
    if ($action === 'delete_song') {
        $sid = (int)($_POST['song_id'] ?? 0);
        if ($sid <= 0) jsonResponse(['success' => false, 'message' => 'Invalid song.']);

        $stmt = $pdo->prepare("SELECT filepath FROM user_songs WHERE id=? AND user_id=?");
        $stmt->execute([$sid, $uid]);
        $row = $stmt->fetch();
        if (!$row) jsonResponse(['success' => false, 'message' => 'Song not found.']);

        $full = __DIR__ . '/' . $row['filepath'];
        if (is_file($full)) @unlink($full);

        $pdo->prepare("DELETE FROM user_songs WHERE id=? AND user_id=?")->execute([$sid, $uid]);
        jsonResponse(['success' => true]);
    }

    jsonResponse(['success' => false, 'message' => 'Unknown action.']);
}

// ── DATA ─────────────────────────────────────────────────────────
$musicQuota = checkDailyQuota($uid, 'music_search', 'free_music_search_daily_limit', FREE_MUSIC_SEARCH_DAILY_LIMIT_DEFAULT);

$favStmt = $pdo->prepare("SELECT youtube_id,type,name,subtitle,thumbnail FROM youtube_favorites WHERE user_id=? ORDER BY created_at DESC");
$favStmt->execute([$uid]);
$favorites = $favStmt->fetchAll();
$favIds    = array_column($favorites, 'youtube_id');

$subjStmt = $pdo->prepare("SELECT id,name,color FROM subjects WHERE user_id=? ORDER BY name");
$subjStmt->execute([$uid]);
$subjects = $subjStmt->fetchAll();

// ── Manually uploaded songs (per-user files stored on disk) ──
$songsStmt = $pdo->prepare("SELECT id,title,filepath,filesize,created_at FROM user_songs WHERE user_id=? ORDER BY created_at DESC");
$songsStmt->execute([$uid]);
$userSongs = $songsStmt->fetchAll();

$youtubeConfigured = (YOUTUBE_API_KEY !== '');

// Curated categories — real, popular public YouTube videos/playlists.
// Swap the IDs any time: open a video/playlist on youtube.com → copy the "v=" or "list=" value from the URL.
$categories = [
    'lofi' => [
        'label' => '🌙 Lofi',
        'emoji' => '🌙',
        'color' => '#8b5cf6',
        'items' => [
            ['id' => 'PLvGUEIPxRGvWvkelmgyWU6QET6mmGbd8W', 'type' => 'playlist', 'name' => 'Lofi Hip Hop Radio Playlist'],
            ['id' => '5yx6BWlEVcY', 'type' => 'video', 'name' => 'Chillhop Radio — jazzy/lofi beats (live)'],
        ],
    ],
    'focus' => [
        'label' => '🎯 Focus',
        'emoji' => '🎯',
        'color' => '#6366f1',
        'items' => [
            ['id' => 'PLYwFNfjiOd7MpPJl_9VYRDaPBw9cOoGCG', 'type' => 'playlist', 'name' => 'Deep Focus & Concentration Playlist'],
            ['id' => 'oPVte6aMprI', 'type' => 'video', 'name' => 'Deep Focus — Studying & Concentration'],
        ],
    ],
    'classical' => [
        'label' => '🎻 Classical',
        'emoji' => '🎻',
        'color' => '#06b6d4',
        'items' => [
            ['id' => 'PLc87N-d3x2CrSLCAMo8QKtqKcim_Y45-t', 'type' => 'playlist', 'name' => 'Classical Piano Music Playlist'],
            ['id' => 'rDnq1--6knY', 'type' => 'video', 'name' => 'Peaceful Piano — Calm Classical Music'],
        ],
    ],
];
$defaultCat  = 'lofi';
$defaultItem = $categories[$defaultCat]['items'][0];

require_once 'includes/header.php';
renderHeader('Music', 'music');
?>

<style>
.mp-wrap { max-width: 980px; }

/* ── Now Playing hero ── */
.mp-hero {
    background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-secondary) 100%);
    border: 1px solid var(--border); border-radius: 20px;
    padding: 20px; margin-bottom: 18px; position: relative; overflow: hidden;
}
.mp-hero::before {
    content: ''; position: absolute; top: -60px; right: -60px; width: 220px; height: 220px;
    background: radial-gradient(circle, rgba(30,215,96,.10) 0%, transparent 70%);
    border-radius: 50%; pointer-events: none;
}
.mp-hero-lbl {
    font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase;
    letter-spacing: .6px; margin-bottom: 12px; display: flex; align-items: center; gap: 7px;
}
.mp-hero-lbl svg { flex-shrink: 0; }
#mpEmbedBox { border-radius: 14px; overflow: hidden; background: rgba(0,0,0,.2); position: relative; z-index: 1; }
#mpEmbedBox iframe { width: 100%; border: 0; display: block; }
.mp-hero-name { font-size: 14px; font-weight: 700; color: var(--text-primary); margin-top: 12px; position: relative; z-index: 1; }

/* ── Focus timer ── */
.mp-timer {
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 20px;
    padding: 22px; margin-bottom: 18px;
}
.mp-timer-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.mp-timer-icon { width: 34px; height: 34px; border-radius: 10px; background: rgba(99,102,241,.12); display: flex; align-items: center; justify-content: center; font-size: 15px; flex-shrink: 0; }
.mp-timer-title { font-size: 15px; font-weight: 700; color: var(--text-primary); }
.mp-timer-sub { font-size: 12px; color: var(--text-muted); }
.mp-timer-body { display: flex; flex-wrap: wrap; gap: 24px; align-items: center; }
.mp-timer-display { font-family: 'Courier New', monospace; font-size: 44px; font-weight: 800; color: var(--text-primary); min-width: 140px; text-align: center; }
.mp-timer-bar-wrap { width: 100%; height: 6px; background: var(--border); border-radius: 4px; overflow: hidden; margin-top: 8px; }
.mp-timer-bar { height: 100%; width: 0%; background: linear-gradient(90deg, #6366f1, #a855f7); border-radius: 4px; transition: width 1s linear; }
.mp-timer-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.mp-preset-btn {
    padding: 7px 14px; border-radius: 9px; border: 1px solid var(--border); background: var(--bg-secondary);
    color: var(--text-secondary); font-size: 12px; font-weight: 700; cursor: pointer; transition: all .15s;
}
.mp-preset-btn.active, .mp-preset-btn:hover { border-color: var(--accent); color: var(--accent); background: rgba(99,102,241,.08); }
.mp-timer-ctrls { display: flex; gap: 8px; margin-top: 12px; }
.mp-btn {
    padding: 10px 18px; border-radius: 10px; border: none; font-size: 13px; font-weight: 700; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px; transition: all .15s;
}
.mp-btn-primary { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff; }
.mp-btn-primary:hover { opacity: .9; }
.mp-btn-ghost { background: var(--bg-secondary); border: 1px solid var(--border); color: var(--text-secondary); }
.mp-btn-ghost:hover { color: var(--text-primary); }
.mp-timer-subject { flex: 1; min-width: 200px; }
.mp-select {
    width: 100%; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border);
    background: var(--bg-secondary); color: var(--text-primary); font-size: 13px; font-weight: 600;
}
.mp-timer-msg { font-size: 12px; font-weight: 600; padding: 8px 12px; border-radius: 8px; margin-top: 12px; display: none; }
.mp-timer-msg.show { display: block; animation: alertPopIn .28s cubic-bezier(.34,1.3,.64,1); }
@keyframes alertPopIn { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.mp-timer-msg.ok { background: rgba(16,185,129,.1); color: #10b981; border: 1px solid rgba(16,185,129,.25); }
.mp-timer-msg.err { background: rgba(239,68,68,.1); color: #ef4444; border: 1px solid rgba(239,68,68,.25); }

/* ── Tabs ── */
.mp-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.mp-tab {
    padding: 11px 18px; font-size: 13px; font-weight: 700; color: var(--text-muted); cursor: pointer;
    border-bottom: 2px solid transparent; white-space: nowrap; transition: color .15s;
}
.mp-tab.active { color: var(--accent); border-color: var(--accent); }
.mp-tab-panel { display: none; }
.mp-tab-panel.active { display: block; }

/* ── Category pills ── */
.mp-cat-pills { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.mp-cat-pill {
    padding: 8px 16px; border-radius: 99px; border: 1px solid var(--border); background: var(--bg-secondary);
    color: var(--text-secondary); font-size: 12.5px; font-weight: 700; cursor: pointer; transition: all .15s;
}
.mp-cat-pill.active { border-color: var(--accent); color: #fff; background: linear-gradient(135deg, #6366f1, #8b5cf6); }
.mp-cat-panel { display: none; }
.mp-cat-panel.active { display: grid; }

/* ── Grids & cards ── */
.mp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.mp-card {
    background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 14px; padding: 12px;
    cursor: pointer; transition: all .2s; position: relative;
}
.mp-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.mp-card-art {
    width: 100%; aspect-ratio: 1; border-radius: 10px; margin-bottom: 10px; background-size: cover; background-position: center;
    display: flex; align-items: center; justify-content: center; font-size: 34px; color: #fff;
}
.mp-card-name { font-size: 13px; font-weight: 700; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-card-sub { font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.mp-heart {
    position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border-radius: 50%;
    background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center;
    font-size: 13px; cursor: pointer; backdrop-filter: blur(4px); transition: all .15s; color: #fff;
}
.mp-heart.on { color: #ef4444; }
.mp-heart:hover { transform: scale(1.12); }

/* ── Search ── */
.mp-search-row { display: flex; gap: 8px; margin-bottom: 18px; }
.mp-search-input {
    flex: 1; padding: 12px 16px; border-radius: 12px; border: 1px solid var(--border);
    background: var(--bg-secondary); color: var(--text-primary); font-size: 14px;
}
.mp-search-input:focus { outline: none; border-color: var(--accent); }
.mp-empty { text-align: center; padding: 40px 20px; color: var(--text-muted); font-size: 13px; }
.mp-empty a { color: var(--accent); font-weight: 700; text-decoration: none; }
.mp-config-note {
    background: rgba(245,158,11,.08); border: 1px solid rgba(245,158,11,.25); border-radius: 12px;
    padding: 12px 15px; font-size: 12.5px; color: #fbbf24; margin-bottom: 16px; line-height: 1.6;
}

/* ── My Songs / manual upload ── */
.mp-upload-box {
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 18px;
    padding: 20px; margin-bottom: 18px;
}
.mp-upload-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.mp-upload-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.mp-upload-progress { margin-top: 12px; }
.mp-song-list { display: flex; flex-direction: column; gap: 8px; }
.mp-song-row {
    display: flex; align-items: center; gap: 12px; background: var(--bg-secondary);
    border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px;
}
.mp-song-play {
    width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(135deg,#6366f1,#8b5cf6);
    color: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px;
    cursor: pointer; flex-shrink: 0; transition: transform .15s;
}
.mp-song-play:hover { transform: scale(1.08); }
.mp-song-meta { flex: 1; min-width: 0; }
.mp-song-title { font-size: 13px; font-weight: 700; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-song-sub { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.mp-song-row audio { height: 32px; max-width: 220px; flex-shrink: 1; }
.mp-song-del {
    width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border); background: transparent;
    color: var(--text-muted); cursor: pointer; flex-shrink: 0; font-size: 13px; transition: all .15s;
}
.mp-song-del:hover { color: #ef4444; border-color: #ef4444; background: rgba(239,68,68,.08); }
</style>

<div class="mp-wrap">

<!-- NOW PLAYING -->
<div class="mp-hero">
    <div class="mp-hero-lbl">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="#FF0000"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
        Now Playing
    </div>
    <div id="mpEmbedBox">
        <?php if ($defaultItem['type'] === 'video'): ?>
        <iframe id="mpEmbedFrame" src="https://www.youtube.com/embed/<?= htmlspecialchars($defaultItem['id']) ?>?rel=0"
            height="220" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy"></iframe>
        <?php else: ?>
        <iframe id="mpEmbedFrame" src="https://www.youtube.com/embed/videoseries?list=<?= htmlspecialchars($defaultItem['id']) ?>"
            height="352" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy"></iframe>
        <?php endif; ?>
    </div>
    <div class="mp-hero-name" id="mpHeroName"><?= htmlspecialchars($defaultItem['name']) ?></div>
</div>

<?php if (!$youtubeConfigured): ?>
<div class="mp-config-note">
    ⚠️ YouTube API key isn't set yet — Search won't work until an admin adds <b>YOUTUBE_API_KEY</b> in <code>includes/config.php</code> (free key from console.cloud.google.com, enable "YouTube Data API v3"). Curated playlists &amp; embeds below still work fine.
</div>
<?php endif; ?>

<!-- FOCUS TIMER -->
<div class="mp-timer">
    <div class="mp-timer-hd">
        <div class="mp-timer-icon">⏱️</div>
        <div>
            <div class="mp-timer-title">Focus Timer</div>
            <div class="mp-timer-sub">Study with music, then save the session to your log</div>
        </div>
    </div>
    <div class="mp-timer-body">
        <div>
            <div class="mp-timer-display" id="mpTimerDisplay">25:00</div>
            <div class="mp-timer-bar-wrap"><div class="mp-timer-bar" id="mpTimerBar"></div></div>
        </div>
        <div style="flex:1;min-width:220px">
            <div class="mp-timer-presets" id="mpPresets">
                <button class="mp-preset-btn active" data-min="15" onclick="mpSetPreset(15,this)">15 min</button>
                <button class="mp-preset-btn" data-min="25" onclick="mpSetPreset(25,this)">25 min</button>
                <button class="mp-preset-btn" data-min="50" onclick="mpSetPreset(50,this)">50 min</button>
                <input type="number" id="mpCustomMin" min="1" max="180" placeholder="Custom" class="mp-select" style="width:90px;padding:7px 10px;font-size:12px" onchange="mpSetPreset(this.value,null)">
            </div>
            <div class="mp-timer-ctrls">
                <button class="mp-btn mp-btn-primary" id="mpStartBtn" onclick="mpToggleTimer()">▶ Start</button>
                <button class="mp-btn mp-btn-ghost" onclick="mpResetTimer()">↺ Reset</button>
                <button class="mp-btn mp-btn-ghost" onclick="mpLogSession()">💾 Save Session</button>
            </div>
        </div>
        <div class="mp-timer-subject">
            <label style="font-size:11px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px;display:block">Subject</label>
            <?php if (empty($subjects)): ?>
            <div style="font-size:12px;color:var(--text-muted)">No subjects yet — <a href="subjects.php" style="color:var(--accent);font-weight:700;text-decoration:none">add one</a> to save sessions.</div>
            <?php else: ?>
            <select class="mp-select" id="mpSubjectSel">
                <option value="0">— Select subject —</option>
                <?php foreach ($subjects as $s): ?>
                <option value="<?= $s['id'] ?>"><?= htmlspecialchars($s['name']) ?></option>
                <?php endforeach; ?>
            </select>
            <?php endif; ?>
        </div>
    </div>
    <div class="mp-timer-msg" id="mpTimerMsg"></div>
</div>

<!-- TABS -->
<div class="mp-tabs">
    <div class="mp-tab active" data-tab="playlists" onclick="mpSwitchTab('playlists')">🎶 Playlists</div>
    <div class="mp-tab" data-tab="search" onclick="mpSwitchTab('search')">🔍 Search</div>
    <div class="mp-tab" data-tab="favorites" onclick="mpSwitchTab('favorites')">❤️ Favorites (<?= count($favorites) ?>)</div>
    <div class="mp-tab" data-tab="myfiles" onclick="mpSwitchTab('myfiles')" id="mpMySongsTab">📤 My Songs (<?= count($userSongs) ?>)</div>
</div>

<!-- PLAYLISTS PANEL -->
<div class="mp-tab-panel active" id="panel-playlists">
    <div class="mp-cat-pills">
        <?php foreach ($categories as $key => $cat): ?>
        <div class="mp-cat-pill <?= $key === $defaultCat ? 'active' : '' ?>" data-cat="<?= $key ?>" onclick="mpSwitchCat('<?= $key ?>')"><?= $cat['label'] ?></div>
        <?php endforeach; ?>
    </div>
    <?php foreach ($categories as $key => $cat): ?>
    <div class="mp-cat-panel mp-grid <?= $key === $defaultCat ? 'active' : '' ?>" id="cat-<?= $key ?>">
        <?php foreach ($cat['items'] as $item): $isFav = in_array($item['id'], $favIds); ?>
        <div class="mp-card" onclick="mpLoadEmbed('<?= $item['type'] ?>','<?= $item['id'] ?>','<?= htmlspecialchars(addslashes($item['name'])) ?>')">
            <div class="mp-heart <?= $isFav ? 'on' : '' ?>" data-sid="<?= $item['id'] ?>"
                 onclick="event.stopPropagation();mpToggleFav(this,'<?= $item['type'] ?>','<?= $item['id'] ?>','<?= htmlspecialchars(addslashes($item['name'])) ?>','<?= $cat['label'] ?>','')">
                <?= $isFav ? '♥' : '♡' ?>
            </div>
            <div class="mp-card-art" style="background:linear-gradient(135deg,<?= $cat['color'] ?>,#111)"><?= $cat['emoji'] ?></div>
            <div class="mp-card-name"><?= htmlspecialchars($item['name']) ?></div>
            <div class="mp-card-sub"><?= $cat['label'] ?> <?= $item['type'] === 'video' ? 'video' : 'playlist' ?></div>
        </div>
        <?php endforeach; ?>
    </div>
    <?php endforeach; ?>
</div>

<!-- SEARCH PANEL -->
<div class="mp-tab-panel" id="panel-search">
    <div class="mp-search-row">
        <input type="text" class="mp-search-input" id="mpSearchInput" placeholder="Search songs, artists or playlists..." onkeydown="if(event.key==='Enter')mpSearch()">
        <button class="mp-btn mp-btn-primary" onclick="mpSearch()">Search</button>
    </div>
    <?php if (!$musicQuota['is_pro']): ?>
    <div id="mpQuotaBanner" style="font-size:12.5px;color:var(--text-muted);margin:-6px 0 14px;display:flex;align-items:center;gap:8px;flex-wrap:wrap">
        <span id="mpQuotaText">🔍 <?= $musicQuota['used'] ?>/<?= $musicQuota['limit'] ?> free searches used today</span>
        <a href="upgrade.php" style="color:var(--accent);font-weight:600;text-decoration:none">⚡ Upgrade for unlimited</a>
    </div>
    <?php endif; ?>
    <div class="mp-grid" id="mpSearchResults"></div>
    <div class="mp-empty" id="mpSearchEmpty">Search for any song, artist, or playlist on YouTube 🎧</div>
</div>

<!-- FAVORITES PANEL -->
<div class="mp-tab-panel" id="panel-favorites">
    <?php if (empty($favorites)): ?>
    <div class="mp-empty" id="mpFavEmpty">No favorites yet — tap the ♡ on any playlist or search result to save it here.</div>
    <?php endif; ?>
    <div class="mp-grid" id="mpFavGrid">
        <?php foreach ($favorites as $f): ?>
        <div class="mp-card" data-sid="<?= htmlspecialchars($f['youtube_id']) ?>"
             onclick="mpLoadEmbed('<?= $f['type'] ?>','<?= htmlspecialchars($f['youtube_id']) ?>','<?= htmlspecialchars(addslashes($f['name'])) ?>')">
            <div class="mp-heart on" onclick="event.stopPropagation();mpToggleFav(this,'<?= $f['type'] ?>','<?= htmlspecialchars($f['youtube_id']) ?>','<?= htmlspecialchars(addslashes($f['name'])) ?>','<?= htmlspecialchars(addslashes($f['subtitle'])) ?>','<?= htmlspecialchars($f['thumbnail']) ?>',true)">♥</div>
            <div class="mp-card-art" style="<?= $f['thumbnail'] ? "background-image:url('".htmlspecialchars($f['thumbnail'])."')" : "background:linear-gradient(135deg,#6366f1,#111)" ?>"><?= $f['thumbnail'] ? '' : ($f['type']==='video'?'🎬':'📁') ?></div>
            <div class="mp-card-name"><?= htmlspecialchars($f['name']) ?></div>
            <div class="mp-card-sub"><?= htmlspecialchars($f['subtitle']) ?></div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<!-- MY SONGS PANEL (manual uploads) -->
<div class="mp-tab-panel" id="panel-myfiles">
    <div class="mp-upload-box">
        <div class="mp-upload-hd">
            <div class="mp-timer-icon">📤</div>
            <div>
                <div class="mp-timer-title">Upload Your Own Song</div>
                <div class="mp-timer-sub">MP3, WAV, OGG or M4A — max 5MB per file</div>
            </div>
        </div>
        <input type="file" id="mpFileInput" accept=".mp3,.wav,.ogg,.m4a,audio/*" style="display:none" onchange="mpFileSelected(this)">
        <div class="mp-upload-row">
            <button class="mp-btn mp-btn-ghost" onclick="document.getElementById('mpFileInput').click()">📁 Choose File</button>
            <input type="text" id="mpSongTitle" class="mp-select" placeholder="Song title (optional)" style="flex:1;min-width:160px" maxlength="150">
            <button class="mp-btn mp-btn-primary" id="mpUploadBtn" onclick="mpUploadSong()" disabled>⬆ Upload</button>
        </div>
        <div id="mpFileInfo" style="font-size:12px;color:var(--text-muted);margin-top:8px"></div>
        <div class="mp-upload-progress" id="mpUploadProgressWrap" style="display:none">
            <div class="mp-timer-bar-wrap"><div class="mp-timer-bar" id="mpUploadProgress" style="background:linear-gradient(90deg,#10b981,#06b6d4)"></div></div>
        </div>
        <div class="mp-timer-msg" id="mpUploadMsg"></div>
    </div>

    <?php if (empty($userSongs)): ?>
    <div class="mp-empty" id="mpMySongsEmpty">No songs uploaded yet — add your own MP3s above and they'll show up here.</div>
    <?php endif; ?>
    <div class="mp-song-list" id="mpMySongsList">
        <?php foreach ($userSongs as $song): ?>
        <div class="mp-song-row" data-song-id="<?= (int)$song['id'] ?>">
            <div class="mp-song-play" onclick="mpLoadEmbed('local','<?= htmlspecialchars($song['filepath']) ?>','<?= htmlspecialchars(addslashes($song['title'])) ?>')">▶</div>
            <div class="mp-song-meta">
                <div class="mp-song-title"><?= htmlspecialchars($song['title']) ?></div>
                <div class="mp-song-sub"><?= number_format($song['filesize'] / 1024 / 1024, 2) ?> MB · <?= date('M j, Y', strtotime($song['created_at'])) ?></div>
            </div>
            <audio controls preload="none" src="<?= htmlspecialchars($song['filepath']) ?>"></audio>
            <button class="mp-song-del" onclick="mpDeleteSong(<?= (int)$song['id'] ?>, this)" title="Delete">🗑</button>
        </div>
        <?php endforeach; ?>
    </div>
</div>

</div><!-- /.mp-wrap -->

<?php require_once 'includes/footer.php'; renderFooter(); ?>
<script>
// ── State ──
let mpFavSet = new Set(<?= json_encode($favIds) ?>);

// ── Now Playing embed ──
function mpLoadEmbed(type, id, name) {
    const box = document.getElementById('mpEmbedBox');
    document.getElementById('mpHeroName').textContent = name;

    if (type === 'local') {
        // id is the file path of a manually uploaded song
        box.innerHTML = `<audio id="mpEmbedFrame" controls autoplay style="width:100%;display:block;padding:14px" src="${id}"></audio>`;
    } else if (type === 'playlist') {
        box.innerHTML = `<iframe id="mpEmbedFrame" src="https://www.youtube.com/embed/videoseries?list=${id}" height="352" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy"></iframe>`;
    } else {
        // video
        box.innerHTML = `<iframe id="mpEmbedFrame" src="https://www.youtube.com/embed/${id}?rel=0&autoplay=1" height="220" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen loading="lazy"></iframe>`;
    }
    window.scrollTo({ top: 0, behavior: 'smooth' });
}

// ── Tabs ──
function mpSwitchTab(tab) {
    document.querySelectorAll('.mp-tab').forEach(t => t.classList.toggle('active', t.dataset.tab === tab));
    document.querySelectorAll('.mp-tab-panel').forEach(p => p.classList.toggle('active', p.id === 'panel-' + tab));
}

// ── Category pills ──
function mpSwitchCat(cat) {
    document.querySelectorAll('.mp-cat-pill').forEach(p => p.classList.toggle('active', p.dataset.cat === cat));
    document.querySelectorAll('.mp-cat-panel').forEach(p => p.classList.toggle('active', p.id === 'cat-' + cat));
}

// ── Favorite toggle ──
async function mpToggleFav(el, type, id, name, subtitle, image, isFavPanel) {
    const fd = new FormData();
    fd.append('action', 'toggle_favorite');
    fd.append('youtube_id', id);
    fd.append('type', type);
    fd.append('name', name);
    fd.append('subtitle', subtitle || '');
    fd.append('image_url', image || '');

    try {
        const r = await fetch(location.href, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: fd });
        const data = await r.json();
        if (!data.success) { alert(data.message || 'Something went wrong.'); return; }

        if (data.favorited) {
            mpFavSet.add(id);
            el.classList.add('on'); el.textContent = '♥';
        } else {
            mpFavSet.delete(id);
            el.classList.remove('on'); el.textContent = '♡';
            if (isFavPanel) {
                const card = el.closest('.mp-card');
                if (card) card.remove();
                const grid = document.getElementById('mpFavGrid');
                if (grid && !grid.querySelector('.mp-card')) {
                    document.getElementById('mpFavEmpty') || (grid.insertAdjacentHTML('afterend', '<div class="mp-empty" id="mpFavEmpty">No favorites yet — tap the ♡ on any playlist or search result to save it here.</div>'));
                }
            }
        }
        // update favorites tab counter
        const favTab = document.querySelector('.mp-tab[data-tab="favorites"]');
        if (favTab) favTab.textContent = `❤️ Favorites (${mpFavSet.size})`;
    } catch (e) { alert('Network error.'); }
}

// ── Search ──
async function mpSearch() {
    const q = document.getElementById('mpSearchInput').value.trim();
    const results = document.getElementById('mpSearchResults');
    const empty   = document.getElementById('mpSearchEmpty');
    if (!q) return;

    empty.style.display = 'block';
    empty.textContent = 'Searching...';
    results.innerHTML = '';

    const fd = new FormData();
    fd.append('action', 'search');
    fd.append('q', q);

    try {
        const r = await fetch(location.href, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: fd });
        const data = await r.json();
        if (!data.success) {
            if (data.limit_reached) {
                empty.innerHTML = '⚠️ ' + data.message + ' <a href="upgrade.php" style="color:var(--accent);font-weight:600">Upgrade now</a>';
            } else {
                empty.textContent = data.message || 'Search failed.';
            }
            return;
        }
        if (data.quota) {
            const banner = document.getElementById('mpQuotaText');
            if (banner) banner.textContent = '🔍 ' + data.quota.used + '/' + data.quota.limit + ' free searches used today';
        }
        if (!data.results.length) { empty.textContent = 'No results for "' + q + '".'; return; }

        empty.style.display = 'none';
        data.results.forEach(item => {
            const isFav = mpFavSet.has(item.id);
            const div = document.createElement('div');
            div.className = 'mp-card';
            div.onclick = () => mpLoadEmbed(item.type, item.id, item.name);
            div.innerHTML = `
                <div class="mp-heart ${isFav ? 'on' : ''}" data-sid="${item.id}">${isFav ? '♥' : '♡'}</div>
                <div class="mp-card-art" style="${item.image ? `background-image:url('${item.image}')` : `background:linear-gradient(135deg,#6366f1,#111)`}">${item.image ? '' : (item.type === 'video' ? '🎬' : '📁')}</div>
                <div class="mp-card-name">${item.name}</div>
                <div class="mp-card-sub">${item.subtitle}</div>
            `;
            const heart = div.querySelector('.mp-heart');
            heart.onclick = (e) => { e.stopPropagation(); mpToggleFav(heart, item.type, item.id, item.name, item.subtitle, item.image); };
            results.appendChild(div);
        });
    } catch (e) { empty.textContent = 'Network error.'; }
}

// ── Focus Timer ──
let mpTimerTotal   = 15 * 60;
let mpTimerLeft    = mpTimerTotal;
let mpTimerRunning = false;
let mpTimerInt     = null;

function mpFmt(s) {
    const m = Math.floor(s / 60), sec = s % 60;
    return String(m).padStart(2, '0') + ':' + String(sec).padStart(2, '0');
}

function mpUpdateDisplay() {
    document.getElementById('mpTimerDisplay').textContent = mpFmt(mpTimerLeft);
    const pct = 100 - (mpTimerLeft / mpTimerTotal * 100);
    document.getElementById('mpTimerBar').style.width = pct + '%';
}

function mpSetPreset(mins, btn) {
    mins = parseInt(mins);
    if (!mins || mins < 1) return;
    mpTimerTotal = Math.min(180, mins) * 60;
    mpTimerLeft  = mpTimerTotal;
    document.querySelectorAll('.mp-preset-btn').forEach(b => b.classList.remove('active'));
    if (btn) btn.classList.add('active');
    mpUpdateDisplay();
}

function mpToggleTimer() {
    const btn = document.getElementById('mpStartBtn');
    if (mpTimerRunning) {
        clearInterval(mpTimerInt);
        mpTimerRunning = false;
        btn.textContent = '▶ Start';
    } else {
        mpTimerRunning = true;
        btn.textContent = '⏸ Pause';
        mpTimerInt = setInterval(() => {
            mpTimerLeft--;
            mpUpdateDisplay();
            if (mpTimerLeft <= 0) {
                clearInterval(mpTimerInt);
                mpTimerRunning = false;
                btn.textContent = '▶ Start';
                mpShowMsg("Time's up! Tap Save Session to log it.", 'ok');
            }
        }, 1000);
    }
}

function mpResetTimer() {
    clearInterval(mpTimerInt);
    mpTimerRunning = false;
    mpTimerLeft = mpTimerTotal;
    document.getElementById('mpStartBtn').textContent = '▶ Start';
    mpUpdateDisplay();
}

function mpShowMsg(text, type) {
    const el = document.getElementById('mpTimerMsg');
    el.textContent = text;
    el.className = 'mp-timer-msg show ' + type;
    setTimeout(() => el.classList.remove('show'), 5000);
}

async function mpLogSession() {
    const sel = document.getElementById('mpSubjectSel');
    if (!sel) { mpShowMsg('Add a subject first to save sessions.', 'err'); return; }
    const subId = sel.value;
    const elapsedMin = Math.max(1, Math.round((mpTimerTotal - mpTimerLeft) / 60));

    if (subId === '0') { mpShowMsg('Please select a subject first.', 'err'); return; }
    if (elapsedMin < 1) { mpShowMsg('Start the timer first — nothing to save yet.', 'err'); return; }

    const fd = new FormData();
    fd.append('action', 'log_session');
    fd.append('subject_id', subId);
    fd.append('minutes', elapsedMin);

    try {
        const r = await fetch(location.href, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: fd });
        const data = await r.json();
        mpShowMsg(data.message, data.success ? 'ok' : 'err');
        if (data.success) mpResetTimer();
    } catch (e) { mpShowMsg('Network error.', 'err'); }
}

// ── My Songs: manual upload ──
const MP_MAX_UPLOAD_BYTES = 5 * 1024 * 1024; // must match server-side limit
const MP_ALLOWED_EXT_RE   = /\.(mp3|wav|ogg|m4a)$/i;
let mpSelectedFile = null;

function mpFileSelected(input) {
    const file = input.files[0];
    const info = document.getElementById('mpFileInfo');
    const btn  = document.getElementById('mpUploadBtn');

    if (!file) { mpSelectedFile = null; btn.disabled = true; info.textContent = ''; return; }

    if (!MP_ALLOWED_EXT_RE.test(file.name)) {
        info.textContent = '⚠️ Only MP3, WAV, OGG or M4A files are supported.';
        info.style.color = '#ef4444';
        mpSelectedFile = null; btn.disabled = true; input.value = '';
        return;
    }
    if (file.size > MP_MAX_UPLOAD_BYTES) {
        info.textContent = `⚠️ ${(file.size / 1024 / 1024).toFixed(2)} MB — max allowed is 5 MB.`;
        info.style.color = '#ef4444';
        mpSelectedFile = null; btn.disabled = true; input.value = '';
        return;
    }

    mpSelectedFile = file;
    info.textContent = `Selected: ${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)`;
    info.style.color = 'var(--text-muted)';
    btn.disabled = false;

    const titleInput = document.getElementById('mpSongTitle');
    if (!titleInput.value) titleInput.value = file.name.replace(/\.[^.]+$/, '');
}

function mpUploadSong() {
    if (!mpSelectedFile) return;
    const btn      = document.getElementById('mpUploadBtn');
    const msg      = document.getElementById('mpUploadMsg');
    const progWrap = document.getElementById('mpUploadProgressWrap');
    const prog     = document.getElementById('mpUploadProgress');

    btn.disabled = true;
    progWrap.style.display = 'block';
    prog.style.width = '0%';

    const fd = new FormData();
    fd.append('action', 'upload_song');
    fd.append('title', document.getElementById('mpSongTitle').value.trim());
    fd.append('song_file', mpSelectedFile);

    const xhr = new XMLHttpRequest();
    xhr.open('POST', location.href);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xhr.upload.onprogress = (e) => {
        if (e.lengthComputable) prog.style.width = Math.round(e.loaded / e.total * 100) + '%';
    };
    xhr.onload = () => {
        btn.disabled = false;
        progWrap.style.display = 'none';
        let data;
        try { data = JSON.parse(xhr.responseText); } catch (e) {
            mpShowUploadMsg('Server returned an unexpected response.', 'err');
            return;
        }
        mpShowUploadMsg(data.message || (data.success ? 'Uploaded!' : 'Upload failed.'), data.success ? 'ok' : 'err');
        if (data.success) {
            mpAddSongRow(data.song);
            document.getElementById('mpFileInput').value = '';
            document.getElementById('mpSongTitle').value = '';
            document.getElementById('mpFileInfo').textContent = '';
            mpSelectedFile = null;
        }
    };
    xhr.onerror = () => {
        btn.disabled = false;
        progWrap.style.display = 'none';
        mpShowUploadMsg('Network error — please try again.', 'err');
    };
    xhr.send(fd);
}

function mpShowUploadMsg(text, type) {
    const el = document.getElementById('mpUploadMsg');
    el.textContent = text;
    el.className = 'mp-timer-msg show ' + type;
    setTimeout(() => el.classList.remove('show'), 5000);
}

function mpAddSongRow(song) {
    const empty = document.getElementById('mpMySongsEmpty');
    if (empty) empty.remove();

    const list = document.getElementById('mpMySongsList');
    const row = document.createElement('div');
    row.className = 'mp-song-row';
    row.dataset.songId = song.id;
    const mb = (song.filesize / 1024 / 1024).toFixed(2);
    const safeTitle = song.title.replace(/'/g, "\\'");
    row.innerHTML = `
        <div class="mp-song-play" onclick="mpLoadEmbed('local','${song.filepath}','${safeTitle}')">▶</div>
        <div class="mp-song-meta">
            <div class="mp-song-title"></div>
            <div class="mp-song-sub">${mb} MB · just now</div>
        </div>
        <audio controls preload="none" src="${song.filepath}"></audio>
        <button class="mp-song-del" onclick="mpDeleteSong(${song.id}, this)" title="Delete">🗑</button>
    `;
    row.querySelector('.mp-song-title').textContent = song.title; // set via textContent to avoid HTML injection
    list.prepend(row);

    const tab = document.getElementById('mpMySongsTab');
    if (tab) tab.textContent = `📤 My Songs (${list.querySelectorAll('.mp-song-row').length})`;
}

async function mpDeleteSong(id, btn) {
    if (!(await stConfirm('Delete this song? This cannot be undone.'))) return;
    const fd = new FormData();
    fd.append('action', 'delete_song');
    fd.append('song_id', id);

    try {
        const r = await fetch(location.href, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: fd });
        const data = await r.json();
        if (!data.success) { alert(data.message || 'Could not delete song.'); return; }

        const row = btn.closest('.mp-song-row');
        if (row) row.remove();

        const list = document.getElementById('mpMySongsList');
        const remaining = list ? list.querySelectorAll('.mp-song-row').length : 0;
        if (list && remaining === 0 && !document.getElementById('mpMySongsEmpty')) {
            list.insertAdjacentHTML('beforebegin', '<div class="mp-empty" id="mpMySongsEmpty">No songs uploaded yet — add your own MP3s above and they\'ll show up here.</div>');
        }
        const tab = document.getElementById('mpMySongsTab');
        if (tab) tab.textContent = `📤 My Songs (${remaining})`;
    } catch (e) { alert('Network error.'); }
}

mpUpdateDisplay();
</script>
