T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/public_html/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/library.php
<?php
// Define development mode (set to true for debugging, false for production)
define('DEVELOPMENT_MODE', false);

// Disable error reporting in production for security
error_reporting(0);
ini_set('display_errors', 0);

session_start();

// Include translation system
require_once __DIR__ . '/includes/translations.php';

// Include audio token system for signed URLs
require_once __DIR__ . '/utils/audio_token.php';

// Include security functions for session management
require_once __DIR__ . '/includes/security.php';

// Add security headers
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');

// ALWAYS check if user is logged in - no exceptions
if (!isset($_SESSION['user_id'])) {
    header('Location: /auth/login.php');
    exit;
}

// Note: secureSession() is automatically called when includes/security.php is included above
// This updates last_activity and checks for timeout

// Debug: Log that we're past the session check (only in development)
if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
    error_log("Library.php: Session check passed, user_id: " . ($_SESSION['user_id'] ?? 'not set'));
}

// Handle track edit form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_track') {
    // SECURITY: CSRF Protection
    $csrf_token = $_POST['csrf_token'] ?? '';
    if (!validateCSRFToken($csrf_token)) {
        error_log("SECURITY: CSRF token validation failed in library.php from IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        $_SESSION['error_message'] = 'Security validation failed. Please refresh the page and try again.';
        header('Location: /library.php');
        exit;
    }
    
    // Include database configuration
    require_once 'config/database.php';
    
    try {
        // Get database connection
        $pdo = getDBConnection();
        if (!$pdo) {
            throw new Exception('Database connection failed');
        }
        
        // SECURITY: Validate and sanitize track_id
        $track_id_raw = $_POST['track_id'] ?? null;
        if (!$track_id_raw || !is_numeric($track_id_raw) || (int)$track_id_raw <= 0) {
            error_log("SECURITY: Invalid track_id attempt in library.php: " . htmlspecialchars($track_id_raw ?? '', ENT_QUOTES, 'UTF-8'));
            throw new Exception('Invalid track ID');
        }
        $track_id = (int)$track_id_raw;
        
        // SECURITY: Validate and sanitize title
        $title = trim($_POST['title'] ?? '');
        if (empty($title)) {
            throw new Exception('Title is required');
        }
        
        // SECURITY: Limit title length to prevent DoS
        $title = substr($title, 0, 200);
        
        // Apply title case capitalization (e.g., "dreaming of u" → "Dreaming Of U")
        $title = mb_convert_case($title, MB_CASE_TITLE, 'UTF-8');
        
        // SECURITY: Validate and sanitize description
        $description = trim($_POST['description'] ?? '');
        // SECURITY: Limit description length to prevent DoS
        $description = substr($description, 0, 5000);
        $price = floatval($_POST['price'] ?? 0);
        $is_public = isset($_POST['is_public']) ? 1 : 0;
        
        // Validate price is one of the allowed tiers: Free, $0.99, $1.99, $2.99
        $allowed_prices = [0.00, 0.99, 1.99, 2.99];
        $original_price = $price;
        
        // Round price to 2 decimal places first
        $price = round($price, 2);
        
        // Check if price matches exactly (with tolerance for floating point)
        $matched_price = null;
            foreach ($allowed_prices as $ap) {
            if (abs($price - $ap) < 0.005) { // 0.005 tolerance for rounding
                $matched_price = $ap;
                    break;
            }
        }
        
        // Use matched price or default to free if not matching
        $price = $matched_price !== null ? $matched_price : 0.00;
        
        // Validate that the track belongs to the current user
        $stmt = $pdo->prepare("SELECT user_id, is_public, published_at FROM music_tracks WHERE id = ?");
        $stmt->execute([$track_id]);
        $track = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$track || $track['user_id'] != $_SESSION['user_id']) {
            $_SESSION['error_message'] = 'You can only edit your own tracks.';
            header('Location: /library.php');
            exit;
        }
        
        // Determine if we need to set published_at (first time going public)
        $set_published_at = false;
        if ($is_public == 1 && $track['is_public'] == 0 && empty($track['published_at'])) {
            $set_published_at = true;
        }
        
        // Update the track
        // Note: The database column is 'prompt', not 'description'
        if ($set_published_at) {
            // First time publishing - set permanent published_at timestamp
            $stmt = $pdo->prepare("
                UPDATE music_tracks 
                SET title = ?, prompt = ?, price = ?, is_public = ?, published_at = NOW(), updated_at = NOW()
                WHERE id = ? AND user_id = ?
            ");
        } else {
            // Not first publish - don't touch published_at
            $stmt = $pdo->prepare("
                UPDATE music_tracks 
                SET title = ?, prompt = ?, price = ?, is_public = ?, updated_at = NOW()
                WHERE id = ? AND user_id = ?
            ");
        }
        
        $result = $stmt->execute([$title, $description, $price, $is_public, $track_id, $_SESSION['user_id']]);
        
        if ($result) {
            $_SESSION['success_message'] = 'Track updated successfully!';
        } else {
            $_SESSION['error_message'] = 'Failed to update track. Please try again.';
        }
        
    } catch (Exception $e) {
        // Always log errors for debugging
        error_log("Error updating track: " . $e->getMessage());
        error_log("Error trace: " . $e->getTraceAsString());
        $_SESSION['error_message'] = 'An error occurred while updating the track: ' . htmlspecialchars($e->getMessage());
    } catch (Error $e) {
        // Catch fatal errors too
        error_log("Fatal error updating track: " . $e->getMessage());
        error_log("Error trace: " . $e->getTraceAsString());
        $_SESSION['error_message'] = 'A fatal error occurred while updating the track.';
    }
    
    header('Location: /library.php');
    exit;
}

// Helper functions for formatting
function formatBytes($bytes, $precision = 2) {
    if ($bytes == 0) return '0 B';
    $units = ['B', 'KB', 'MB', 'GB'];
    $base = log($bytes, 1024);
    $unit = $units[floor($base)];
    return round(pow(1024, $base - floor($base)), $precision) . ' ' . $unit;
}

function formatTime($seconds) {
    if ($seconds < 60) {
        return round($seconds, 1) . 's';
    } elseif ($seconds < 3600) {
        $minutes = floor($seconds / 60);
        $remainingSeconds = $seconds % 60;
        return $minutes . 'm ' . round($remainingSeconds) . 's';
    } else {
        $hours = floor($seconds / 3600);
        $minutes = floor(($seconds % 3600) / 60);
        return $hours . 'h ' . $minutes . 'm';
    }
}

// Include database configuration
require_once 'config/database.php';

// Debug: Test database connection (only in development)
if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
    error_log("Library.php: Database config loaded");
}

// Get user info with error handling
$user_id = $_SESSION['user_id'] ?? null; // Define user_id for JavaScript checks
$session_id = session_id(); // Define session_id for signed URLs
try {
    $user = getUserById($_SESSION['user_id']);
    $user_name = $user['name'] ?? 'User';
    // Get credits from database, not session (session can be outdated)
    $credits = $user['credits'] ?? 0;
    // Update session with current credits for consistency
    $_SESSION['credits'] = $credits;
} catch (Exception $e) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Error getting user info: " . $e->getMessage());
    }
    $user_name = 'User';
    $credits = $_SESSION['credits'] ?? 5;
}

// Get subscription info if user has subscription
$subscription_info = null;
$subscription_usage = null;
try {
    require_once __DIR__ . '/utils/subscription_helpers.php';
    $subscription_info = getSubscriptionInfo($_SESSION['user_id']);
    if ($subscription_info) {
        $subscription_usage = getMonthlyTrackUsage($_SESSION['user_id'], $subscription_info['plan_name'] ?? null);
    }
    
    // FIX: Use getEffectivePlan() to get the correct plan (checks subscription first, then users.plan)
    $plan = getEffectivePlan($_SESSION['user_id']);
    $_SESSION['plan'] = $plan;
} catch (Exception $e) {
    error_log("Error getting subscription info in library.php: " . $e->getMessage());
    $subscription_info = null;
    $subscription_usage = null;
    // Fallback to users.plan if getEffectivePlan fails
    $plan = $user['plan'] ?? 'free';
    $_SESSION['plan'] = $plan;
}

// Get user stats
$pdo = getDBConnection();
if (!$pdo) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Database connection failed in library.php");
    }
    die("Unable to connect to the database. Please try again later.");
}

$stmt = $pdo->prepare("
    SELECT 
        COUNT(*) as total_tracks,
        COUNT(CASE WHEN status = 'complete' THEN 1 END) as completed_tracks,
        COUNT(CASE WHEN status = 'processing' THEN 1 END) as processing_tracks,
        COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_tracks,
        AVG(CASE WHEN status = 'complete' THEN duration END) as avg_duration,
        SUM(CASE WHEN status = 'complete' THEN duration END) as total_duration
    FROM music_tracks 
    WHERE user_id = ? AND user_id IS NOT NULL
");
try {
    $stmt->execute([$_SESSION['user_id']]);
    $user_stats = $stmt->fetch();
    
    // Debug: Log the actual count for troubleshooting
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Library stats for user_id " . $_SESSION['user_id'] . ": total_tracks = " . ($user_stats['total_tracks'] ?? 0));
    }
} catch (Exception $e) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Error getting user stats: " . $e->getMessage());
    }
    $user_stats = [
        'total_tracks' => 0,
        'completed_tracks' => 0,
        'processing_tracks' => 0,
        'failed_tracks' => 0,
        'avg_duration' => 0,
        'total_duration' => 0
    ];
}

// Get credit transaction history (last 10)
$credit_history = [];
try {
    $stmt = $pdo->prepare("
        SELECT * FROM credit_transactions 
        WHERE user_id = ? 
        ORDER BY created_at DESC 
        LIMIT 10
    ");
    $stmt->execute([$_SESSION['user_id']]);
    $credit_history = $stmt->fetchAll();
} catch (Exception $e) {
    // Credit history table might not exist yet
}

// Calculate user level based on activity
$user_level = 1;
$xp = ($user_stats['completed_tracks'] ?? 0) * 10 + ($user_stats['total_duration'] ?? 0);
if ($xp >= 1000) $user_level = 5;
elseif ($xp >= 500) $user_level = 4;
elseif ($xp >= 200) $user_level = 3;
elseif ($xp >= 50) $user_level = 2;

// Get recent activity (last 10 tracks)
$recent_activity = [];
try {
    $stmt = $pdo->prepare("
        SELECT title, created_at, status
        FROM music_tracks 
        WHERE user_id = ?
        ORDER BY created_at DESC
        LIMIT 10
    ");
    $stmt->execute([$_SESSION['user_id']]);
    $recent_activity = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
    // Error getting recent activity
}

// Get user's music tracks with enhanced data and variations
// SECURITY: Validate and sanitize GET parameters
$status_filter_raw = $_GET['status'] ?? 'all';
$sort_filter_raw = $_GET['sort'] ?? 'latest';
$time_filter_raw = $_GET['time'] ?? 'all';
$genre_filter_raw = $_GET['genre'] ?? '';
$search_query_raw = trim($_GET['search'] ?? '');

// SECURITY: Validate status filter against allowed values
$allowed_statuses = ['all', 'complete', 'processing', 'failed', 'pending'];
$status_filter = in_array($status_filter_raw, $allowed_statuses) ? $status_filter_raw : 'all';

// SECURITY: Validate sort filter against allowed values
$allowed_sorts = ['latest', 'oldest', 'popular', 'most-played'];
$sort_filter = in_array($sort_filter_raw, $allowed_sorts) ? $sort_filter_raw : 'latest';

// SECURITY: Validate time filter against allowed values
$allowed_times = ['all', 'today', 'week', 'month'];
$time_filter = in_array($time_filter_raw, $allowed_times) ? $time_filter_raw : 'all';

// SECURITY: Sanitize genre filter (alphanumeric, spaces, hyphens only)
$genre_filter = preg_replace('/[^a-zA-Z0-9\s\-]/', '', $genre_filter_raw);
$genre_filter = substr($genre_filter, 0, 50); // Limit length

// SECURITY: Sanitize search query (remove dangerous characters, limit length)
$search_query = preg_replace('/[<>"\']/', '', $search_query_raw);
$search_query = substr($search_query, 0, 100); // Limit length

// Build WHERE clause for status filtering
$where_clause = "WHERE mt.user_id = ?";
$params = [$_SESSION['user_id']];

if ($status_filter !== 'all') {
    $where_clause .= " AND mt.status = ?";
    $params[] = $status_filter;
}

// Add search filter
if (!empty($search_query)) {
    $where_clause .= " AND (mt.title LIKE ? OR mt.prompt LIKE ?)";
    $search_param = '%' . $search_query . '%';
    $params[] = $search_param;
    $params[] = $search_param;
}

// Build time filter condition and add to WHERE clause
switch ($time_filter) {
    case 'today':
        $where_clause .= " AND mt.created_at >= CURDATE()";
        break;
    case 'week':
        $where_clause .= " AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)";
        break;
    case 'month':
        $where_clause .= " AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)";
        break;
    case 'all':
    default:
        // No time filter
        break;
}

// Build genre filter condition and add to WHERE clause
if (!empty($genre_filter) && $genre_filter !== 'all') {
    // Try to match genre from metadata JSON field
    $where_clause .= " AND (JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre')) = ? OR mt.genre = ?)";
    $params[] = $genre_filter;
    $params[] = $genre_filter;
}

// Build ORDER BY clause and additional JOINs for sorting
$order_clause = "ORDER BY ";
$additional_joins = "";

switch ($sort_filter) {
    case 'oldest':
        $order_clause .= "mt.created_at ASC";
        break;
    case 'popular':
        $additional_joins = "LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) likes ON mt.id = likes.track_id";
        $order_clause = "ORDER BY COALESCE(likes.like_count, 0) DESC, mt.created_at DESC";
        break;
    case 'most-played':
        $additional_joins = "LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) plays ON mt.id = plays.track_id";
        $order_clause = "ORDER BY COALESCE(plays.play_count, 0) DESC, mt.created_at DESC";
        break;
    case 'latest':
    default:
        $order_clause .= "mt.created_at DESC";
        break;
}

// Get tracks
try {
    // Check if audio_variations table exists
    $checkTable = $pdo->query("SHOW TABLES LIKE 'audio_variations'");
    if ($checkTable->rowCount() > 0) {
        $stmt = $pdo->prepare("
            SELECT 
                mt.*,
                COALESCE(vars.variation_count, 0) as variation_count,
                CASE 
                    WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR) THEN '🔥 Hot'
                    WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN '⭐ New'
                    ELSE ''
                END as badge
            FROM music_tracks mt
            LEFT JOIN (
                SELECT track_id, COUNT(*) as variation_count 
                FROM audio_variations 
                GROUP BY track_id
            ) vars ON mt.id = vars.track_id
            $additional_joins
            $where_clause
            $order_clause
        ");
    } else {
        // Fallback query without audio_variations table
        $stmt = $pdo->prepare("
            SELECT 
                mt.*,
                0 as variation_count,
                CASE 
                    WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR) THEN '🔥 Hot'
                    WHEN mt.created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN '⭐ New'
                    ELSE ''
                END as badge
            FROM music_tracks mt
            $additional_joins
            $where_clause
            $order_clause
        ");
    }
} catch (Exception $e) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Error preparing tracks query: " . $e->getMessage());
    }
    // Fallback to simple query
    $stmt = $pdo->prepare("
        SELECT 
            mt.*,
            0 as variation_count,
            '' as badge
        FROM music_tracks mt
        $where_clause
        ORDER BY mt.created_at DESC
    ");
}
try {
    $stmt->execute($params);
    $user_tracks = $stmt->fetchAll();
} catch (Exception $e) {
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
        error_log("Error getting user tracks: " . $e->getMessage());
    }
    $user_tracks = [];
}

// OPTIMIZED: Batch load variations for user_tracks instead of N+1 queries
$tracks_with_variations = [];
if (!empty($user_tracks)) {
    // Check if audio_variations table exists
    $checkTable = $pdo->query("SHOW TABLES LIKE 'audio_variations'");
    $has_variations_table = $checkTable->rowCount() > 0;
    
    $variations_by_track = [];
    if ($has_variations_table) {
        // Get all track IDs that have variations
        $track_ids_with_variations = [];
        foreach ($user_tracks as $idx => $track) {
            if (($track['variation_count'] ?? 0) > 0) {
                $track_ids_with_variations[] = $track['id'];
            }
        }
        
        if (!empty($track_ids_with_variations)) {
            $placeholders = implode(',', array_fill(0, count($track_ids_with_variations), '?'));
            $variations_stmt = $pdo->prepare("
                SELECT 
                    track_id,
                    variation_index,
                    audio_url,
                    duration,
                    title,
                    tags,
                    image_url,
                    source_audio_url,
                    metadata,
                    created_at
                FROM audio_variations 
                WHERE track_id IN ($placeholders)
                ORDER BY track_id, variation_index ASC
            ");
            $variations_stmt->execute($track_ids_with_variations);
            $all_variations = $variations_stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Group variations by track_id
            foreach ($all_variations as $variation) {
                $variations_by_track[$variation['track_id']][] = $variation;
            }
        }
    }
    
    $user_id = $_SESSION['user_id'] ?? null;
    $session_id = session_id();
    
    foreach ($user_tracks as $track) {
        $track['variations'] = [];
        
        if (($track['variation_count'] ?? 0) > 0 && isset($variations_by_track[$track['id']])) {
            $raw_variations = $variations_by_track[$track['id']];
            
            // Convert audio URLs to signed proxy URLs for security
            foreach ($raw_variations as &$variation) {
                    if (isset($variation['variation_index'])) {
                        // Replace raw audio_url with signed proxy URL
                        $variation['audio_url'] = getSignedAudioUrl($track['id'], $variation['variation_index'], null, $user_id, $session_id);
                    }
                    
                    // Ensure duration is properly set - check metadata if duration is null/0
                    if (empty($variation['duration']) || $variation['duration'] == 0) {
                        if (!empty($variation['metadata'])) {
                            $meta = is_string($variation['metadata']) ? json_decode($variation['metadata'], true) : $variation['metadata'];
                            if (isset($meta['duration']) && $meta['duration'] !== null && $meta['duration'] !== '' && $meta['duration'] > 0) {
                                $variation['duration'] = (float)$meta['duration'];
                            }
                        }
                        // Fallback: use main track duration if variation duration is still missing
                        if (empty($variation['duration']) || $variation['duration'] == 0) {
                            $variation['duration'] = (float)($track['duration'] ?? 0);
                        }
                    } else {
                        // Ensure duration is a number (could be stored as string)
                        $variation['duration'] = (float)$variation['duration'];
                    }
                    
                    // Remove source URLs for security
                    unset($variation['source_audio_url']);
                }
                unset($variation); // Break reference
                
            $track['variations'] = $raw_variations;
        }
        
        $tracks_with_variations[] = $track;
    }
}

// CRITICAL FIX: Check if "failed" tracks are actually still processing
// If a track has a valid task_id and was created recently, it might still be processing
foreach ($tracks_with_variations as &$track) {
    // If status is 'failed' but has valid task_id and is recent, treat as potentially processing
    if ($track['status'] === 'failed') {
        $task_id = $track['task_id'] ?? $track['api_task_id'] ?? null;
        $created_at = strtotime($track['created_at']);
        $hours_old = (time() - $created_at) / 3600;
        
        // If track has valid task_id and is less than 2 hours old, it might still be processing
        if ($task_id && 
            $task_id !== 'unknown' && 
            !str_starts_with($task_id, 'temp_') && 
            !str_starts_with($task_id, 'retry_') &&
            $hours_old < 2) {
            // Override status to 'processing' to prevent showing Retry/Delete buttons
            $track['status'] = 'processing';
            $track['_was_failed_but_checking'] = true; // Flag for display
        }
    }
    
    // If status is NULL or empty, treat as processing
    if (empty($track['status']) || $track['status'] === null) {
        $track['status'] = 'processing';
    }
}
unset($track);

// Also protect recent_tracks if they exist
if (isset($recent_tracks) && !empty($recent_tracks)) {
    foreach ($recent_tracks as &$track) {
        if ($track['status'] === 'failed') {
            $task_id = $track['task_id'] ?? $track['api_task_id'] ?? null;
            $created_at = strtotime($track['created_at']);
            $hours_old = (time() - $created_at) / 3600;
            
            if ($task_id && 
                $task_id !== 'unknown' && 
                !str_starts_with($task_id, 'temp_') && 
                !str_starts_with($task_id, 'retry_') &&
                $hours_old < 2) {
                $track['status'] = 'processing';
                $track['_was_failed_but_checking'] = true;
            }
        }
        
        if (empty($track['status']) || $track['status'] === null) {
            $track['status'] = 'processing';
        }
    }
    unset($track);
}

// Set page variables for header
$current_page = 'library';
$page_title = t('library.page_title');
$page_description = t('library.page_description');

include 'includes/header.php';

// Enhanced sort order function with proper handling
function getSortOrder($sort_filter) {
    // Debug logging
            if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
            error_log("🎵 Library: Sorting by '$sort_filter'");
        }
    
    switch ($sort_filter) {
        case 'latest':
            return "mt.created_at DESC";
        case 'oldest':
            return "mt.created_at ASC";
        case 'popular':
            // OPTIMIZED: Use JOIN alias instead of subquery
            return "COALESCE(like_stats.like_count, 0) DESC, mt.created_at DESC";
        case 'most-played':
            // OPTIMIZED: Use JOIN alias instead of subquery
            return "COALESCE(play_stats.play_count, 0) DESC, mt.created_at DESC";
        case 'most-viewed':
            // OPTIMIZED: Use JOIN alias instead of subquery
            return "COALESCE(view_stats.view_count, 0) DESC, mt.created_at DESC";
        case 'most-commented':
            // OPTIMIZED: Use JOIN alias instead of subquery
            return "COALESCE(comment_stats.comment_count, 0) DESC, mt.created_at DESC";
        case 'most-shared':
            // OPTIMIZED: Use JOIN alias instead of subquery
            return "COALESCE(share_stats.share_count, 0) DESC, mt.created_at DESC";
        case 'title':
            return "mt.title ASC";
        case 'artist':
            return "u.name ASC, mt.created_at DESC";
        case 'duration':
            return "mt.duration DESC, mt.created_at DESC";
        default:
            if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
            error_log("🎵 Library: Unknown sort filter '$sort_filter', using default");
        }
            return "mt.created_at DESC";
    }
}

// Pagination setup
$per_page = 50; // Optimized: Load 50 tracks per page instead of 1000
$current_page = max(1, intval($_GET['page'] ?? 1));
$offset = ($current_page - 1) * $per_page;

// Get total count for pagination
try {
    $count_query = "
        SELECT COUNT(*) as total
        FROM music_tracks mt
        " . $where_clause . "
        AND (
            (mt.status = 'complete' AND mt.audio_url IS NOT NULL AND mt.audio_url != '')
            OR 
            (mt.status = 'processing' AND mt.task_id IS NOT NULL)
            OR
            (mt.status = 'failed')
        )
    ";
    $count_stmt = $pdo->prepare($count_query);
    $count_stmt->execute($params);
    $total_tracks = (int)$count_stmt->fetch(PDO::FETCH_ASSOC)['total'];
    $total_pages = ceil($total_tracks / $per_page);
} catch (Exception $e) {
    $total_tracks = 0;
    $total_pages = 1;
}

// Get user's tracks with social data and artist info (safe query)
try {
    // Build the query using the WHERE clause that filters by user_id
    // Check if audio_variations table exists for variation count
    $checkTable = $pdo->query("SHOW TABLES LIKE 'audio_variations'");
    $has_variations_table = $checkTable->rowCount() > 0;
    
    $variation_count_select = $has_variations_table 
        ? "COALESCE(variation_stats.variation_count, 0) as variation_count"
        : "0 as variation_count";
    
    $variation_join = $has_variations_table 
        ? "LEFT JOIN (SELECT track_id, COUNT(*) as variation_count FROM audio_variations GROUP BY track_id) variation_stats ON mt.id = variation_stats.track_id\n        "
        : "";
    
    // OPTIMIZED: Using JOINs instead of correlated subqueries for better performance
    $query = "
        SELECT 
            mt.id,
            mt.title,
            mt.prompt,
            mt.audio_url,
            mt.duration,
            mt.created_at,
            mt.user_id,
            mt.price,
            mt.metadata,
            mt.status,
            mt.task_id,
            COALESCE(u.name, 'Unknown Artist') as artist_name,
            u.profile_image,
            COALESCE(u.plan, 'free') as plan,
            $variation_count_select,
            COALESCE(like_stats.like_count, 0) as like_count,
            COALESCE(comment_stats.comment_count, 0) as comment_count,
            COALESCE(share_stats.share_count, 0) as share_count,
            COALESCE(play_stats.play_count, 0) as play_count,
            COALESCE(view_stats.view_count, 0) as view_count,
            COALESCE((SELECT COUNT(*) FROM user_follows WHERE follower_id = ? AND following_id = mt.user_id), 0) as is_following,
            CASE WHEN user_like_stats.track_id IS NOT NULL THEN 1 ELSE 0 END as user_liked,
            COALESCE(artist_stats.total_tracks, 0) as artist_total_tracks
        FROM music_tracks mt
        LEFT JOIN users u ON mt.user_id = u.id
        LEFT JOIN (SELECT track_id, COUNT(*) as like_count FROM track_likes GROUP BY track_id) like_stats ON mt.id = like_stats.track_id
        LEFT JOIN (SELECT track_id, COUNT(*) as comment_count FROM track_comments GROUP BY track_id) comment_stats ON mt.id = comment_stats.track_id
        LEFT JOIN (SELECT track_id, COUNT(*) as share_count FROM track_shares GROUP BY track_id) share_stats ON mt.id = share_stats.track_id
        LEFT JOIN (SELECT track_id, COUNT(*) as play_count FROM track_plays GROUP BY track_id) play_stats ON mt.id = play_stats.track_id
        LEFT JOIN (SELECT track_id, COUNT(*) as view_count FROM track_views GROUP BY track_id) view_stats ON mt.id = view_stats.track_id
        LEFT JOIN (SELECT user_id, COUNT(*) as total_tracks FROM music_tracks WHERE status = 'complete' GROUP BY user_id) artist_stats ON mt.user_id = artist_stats.user_id
        LEFT JOIN (SELECT track_id FROM track_likes WHERE user_id = ?) user_like_stats ON mt.id = user_like_stats.track_id
        " . $variation_join . "
        " . $where_clause . "
        AND (
            (mt.status = 'complete' AND mt.audio_url IS NOT NULL AND mt.audio_url != '')
            OR 
            (mt.status = 'processing' AND mt.task_id IS NOT NULL)
            OR
            (mt.status = 'failed')
        )
        ORDER BY " . getSortOrder($sort_filter) . "
        LIMIT ? OFFSET ?
    ";
    
    $stmt = $pdo->prepare($query);
    
    // Add user_id parameters for is_following and user_liked checks
    // $params already contains the user_id from $where_clause, so we add it twice more for the subqueries
    // Use $_SESSION['user_id'] directly to ensure we have the correct user ID for like checking
    $check_user_id = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0;
    
    // Debug: Log the user_id being used for like checking
    if (empty($recent_tracks) || (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE)) {
        error_log("Library query - Session user_id: " . ($_SESSION['user_id'] ?? 'NULL') . ", check_user_id: " . $check_user_id . ", params count: " . count($params));
    }
    
    $execute_params = array_merge($params, [$check_user_id, $check_user_id, $per_page, $offset]);
    
    $stmt->execute($execute_params);
    $recent_tracks = $stmt->fetchAll();
    
    // Ensure user_liked is an integer (PDO might return it as string)
    // OPTIMIZED: Removed redundant like check - main query already includes this via CASE WHEN
    foreach ($recent_tracks as &$track) {
        $track['user_liked'] = (int)($track['user_liked'] ?? 0);
    }
    unset($track); // Break reference
    
    // OPTIMIZED: Batch load variations instead of N+1 queries
    $checkTable = $pdo->query("SHOW TABLES LIKE 'audio_variations'");
    $has_variations_table = $checkTable->rowCount() > 0;
    
    if ($has_variations_table && !empty($recent_tracks)) {
        // Get all track IDs
        $track_ids = array_column($recent_tracks, 'id');
        $placeholders = implode(',', array_fill(0, count($track_ids), '?'));
        
        // Batch load all variations in one query
        $variations_stmt = $pdo->prepare("
            SELECT 
                track_id,
                variation_index,
                audio_url,
                duration,
                title,
                tags,
                image_url,
                source_audio_url,
                metadata,
                created_at
            FROM audio_variations 
            WHERE track_id IN ($placeholders)
            ORDER BY track_id, variation_index ASC
        ");
        $variations_stmt->execute($track_ids);
        $all_variations = $variations_stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Group variations by track_id
        $variations_by_track = [];
        foreach ($all_variations as $variation) {
            $variations_by_track[$variation['track_id']][] = $variation;
        }
        
        // Also get task_ids for tracks that might share variations
        $task_ids = array_filter(array_column($recent_tracks, 'task_id'));
        $main_tracks_by_task = [];
        if (!empty($task_ids)) {
            $task_placeholders = implode(',', array_fill(0, count($task_ids), '?'));
            $main_track_stmt = $pdo->prepare("
                SELECT task_id, id 
                FROM music_tracks 
                WHERE task_id IN ($task_placeholders) AND status = 'complete' 
                ORDER BY created_at ASC, id ASC
            ");
            $main_track_stmt->execute($task_ids);
            $main_tracks = $main_track_stmt->fetchAll(PDO::FETCH_ASSOC);
            foreach ($main_tracks as $mt) {
                if (!isset($main_tracks_by_task[$mt['task_id']])) {
                    $main_tracks_by_task[$mt['task_id']] = $mt['id'];
                }
            }
        }
        
        // Assign variations to tracks
        $user_id = $_SESSION['user_id'] ?? null;
        $session_id = session_id();
        
        foreach ($recent_tracks as &$track) {
            $track['variations'] = [];
            
            // First, try to get variations for this track
            $raw_variations = $variations_by_track[$track['id']] ?? [];
            
            // Convert audio URLs to signed proxy URLs
            foreach ($raw_variations as &$variation) {
                if (isset($variation['variation_index'])) {
                    $variation['audio_url'] = getSignedAudioUrl($track['id'], $variation['variation_index'], null, $user_id, $session_id);
                }
                
                // Ensure duration is properly set - check metadata if duration is null/0
                if (empty($variation['duration']) || $variation['duration'] == 0) {
                    if (!empty($variation['metadata'])) {
                        $meta = is_string($variation['metadata']) ? json_decode($variation['metadata'], true) : $variation['metadata'];
                        if (isset($meta['duration']) && $meta['duration'] !== null && $meta['duration'] !== '' && $meta['duration'] > 0) {
                            $variation['duration'] = (float)$meta['duration'];
                        }
                    }
                    // Fallback: use main track duration if variation duration is still missing
                    if (empty($variation['duration']) || $variation['duration'] == 0) {
                        $variation['duration'] = (float)($track['duration'] ?? 0);
                    }
                } else {
                    $variation['duration'] = (float)$variation['duration'];
                }
                
                unset($variation['source_audio_url']);
            }
            unset($variation);
            
            $track['variations'] = $raw_variations;
            
            // If no variations found for this track, but it has a task_id,
            // check if there's a main track (first track with same task_id) that has variations
            if (empty($track['variations']) && !empty($track['task_id']) && isset($main_tracks_by_task[$track['task_id']])) {
                $main_track_id = $main_tracks_by_task[$track['task_id']];
                
                // If main track exists and is different, get its variations from batch
                if ($main_track_id != $track['id']) {
                    $raw_variations = $variations_by_track[$main_track_id] ?? [];
                    
                    // Convert audio URLs to signed proxy URLs
                    foreach ($raw_variations as &$variation) {
                        if (isset($variation['variation_index'])) {
                            $variation['audio_url'] = getSignedAudioUrl($track['id'], $variation['variation_index'], null, $user_id, $session_id);
                        }
                        
                        // Ensure duration is properly set - check metadata if duration is null/0
                        if (empty($variation['duration']) || $variation['duration'] == 0) {
                            if (!empty($variation['metadata'])) {
                                $meta = is_string($variation['metadata']) ? json_decode($variation['metadata'], true) : $variation['metadata'];
                                if (isset($meta['duration']) && $meta['duration'] !== null && $meta['duration'] !== '' && $meta['duration'] > 0) {
                                    $variation['duration'] = (float)$meta['duration'];
                                }
                            }
                            // Fallback: use main track duration if variation duration is still missing
                            if (empty($variation['duration']) || $variation['duration'] == 0) {
                                $variation['duration'] = (float)($track['duration'] ?? 0);
                            }
                        } else {
                            $variation['duration'] = (float)$variation['duration'];
                        }
                        
                        unset($variation['source_audio_url']);
                    }
                    unset($variation);
                    
                    $track['variations'] = $raw_variations;
                }
            }
            
            // Update variation_count based on actual variations found
            $track['variation_count'] = count($track['variations']);
        }
        unset($track); // Break reference
    } else {
        // No variations table, set variation_count to 0
        foreach ($recent_tracks as &$track) {
            $track['variations'] = [];
            $track['variation_count'] = $track['variation_count'] ?? 0;
        }
        unset($track);
    }
    
    // Debug: Log first track's user_liked value if in development mode
    if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE && !empty($recent_tracks)) {
        error_log("Library: First track user_liked=" . $recent_tracks[0]['user_liked'] . ", track_id=" . $recent_tracks[0]['id'] . ", session_user_id=" . ($_SESSION['user_id'] ?? 'NULL') . ", check_user_id=" . $check_user_id);
        if (!empty($recent_tracks[0]['variations'])) {
            error_log("Library: First track has " . count($recent_tracks[0]['variations']) . " variations, variation_count=" . ($recent_tracks[0]['variation_count'] ?? 0));
        }
    }
    
} catch (Exception $e) {
    // Fallback to basic query if social features fail
    $checkTable = $pdo->query("SHOW TABLES LIKE 'audio_variations'");
    $has_variations_table = $checkTable->rowCount() > 0;
    
    $variation_count_select = $has_variations_table 
        ? "COALESCE((SELECT COUNT(*) FROM audio_variations WHERE track_id = mt.id), 0) as variation_count"
        : "0 as variation_count";
    
    $stmt = $pdo->prepare("
        SELECT 
            mt.id,
            mt.title,
            mt.prompt,
            mt.audio_url,
            mt.duration,
            mt.created_at,
            mt.user_id,
            mt.price,
            mt.metadata,
            mt.status,
            mt.task_id,
            COALESCE(u.name, 'Unknown Artist') as artist_name,
            u.profile_image,
            COALESCE(u.plan, 'free') as plan,
            $variation_count_select,
            0 as like_count,
            0 as comment_count,
            0 as share_count,
            0 as play_count,
            0 as view_count,
            0 as is_following,
            0 as user_liked,
            1 as artist_total_tracks
        FROM music_tracks mt
        LEFT JOIN users u ON mt.user_id = u.id
        WHERE mt.status = 'complete'
        AND mt.audio_url IS NOT NULL 
        AND mt.audio_url != ''
        ORDER BY mt.created_at DESC
        LIMIT ? OFFSET ?
    ");
    $stmt->execute([$per_page, $offset]);
    $recent_tracks = $stmt->fetchAll();
    
    // Load variations for fallback tracks too
    if ($has_variations_table) {
        foreach ($recent_tracks as &$track) {
            $track['variations'] = [];
            
            // Get variations for this track
            $stmt = $pdo->prepare("
                SELECT 
                    variation_index,
                    audio_url,
                    duration,
                    title,
                    tags,
                    image_url,
                    source_audio_url,
                    metadata,
                    created_at
                FROM audio_variations 
                WHERE track_id = ? 
                ORDER BY variation_index ASC
            ");
            $stmt->execute([$track['id']]);
            $raw_variations = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Convert audio URLs to signed proxy URLs
            foreach ($raw_variations as &$variation) {
                if (isset($variation['variation_index'])) {
                    $variation['audio_url'] = getSignedAudioUrl($track['id'], $variation['variation_index'], null, $user_id, $session_id);
                }
                
                // Ensure duration is properly set - check metadata if duration is null/0
                if (empty($variation['duration']) || $variation['duration'] == 0) {
                    if (!empty($variation['metadata'])) {
                        $meta = is_string($variation['metadata']) ? json_decode($variation['metadata'], true) : $variation['metadata'];
                        if (isset($meta['duration']) && $meta['duration'] !== null && $meta['duration'] !== '' && $meta['duration'] > 0) {
                            $variation['duration'] = (float)$meta['duration'];
                        }
                    }
                    // Fallback: use main track duration if variation duration is still missing
                    if (empty($variation['duration']) || $variation['duration'] == 0) {
                        $variation['duration'] = (float)($track['duration'] ?? 0);
                    }
                } else {
                    $variation['duration'] = (float)$variation['duration'];
                }
                
                unset($variation['source_audio_url']);
            }
            unset($variation);
            
            $track['variations'] = $raw_variations;
            
            // If no variations and has task_id, check main track
            if (empty($track['variations']) && !empty($track['task_id'])) {
                $main_track_stmt = $pdo->prepare("
                    SELECT id 
                    FROM music_tracks 
                    WHERE task_id = ? AND status = 'complete' 
                    ORDER BY created_at ASC, id ASC 
                    LIMIT 1
                ");
                $main_track_stmt->execute([$track['task_id']]);
                $main_track = $main_track_stmt->fetch(PDO::FETCH_ASSOC);
                
                if ($main_track && $main_track['id'] != $track['id']) {
                    $stmt->execute([$main_track['id']]);
                    $raw_variations = $stmt->fetchAll();
                    
                    // Convert audio URLs to signed proxy URLs
                    foreach ($raw_variations as &$variation) {
                        if (isset($variation['variation_index'])) {
                            $variation['audio_url'] = getSignedAudioUrl($track['id'], $variation['variation_index'], null, $user_id, $session_id);
                        }
                        
                        // Ensure duration is properly set - check metadata if duration is null/0
                        if (empty($variation['duration']) || $variation['duration'] == 0) {
                            if (!empty($variation['metadata'])) {
                                $meta = is_string($variation['metadata']) ? json_decode($variation['metadata'], true) : $variation['metadata'];
                                if (isset($meta['duration']) && $meta['duration'] !== null && $meta['duration'] !== '' && $meta['duration'] > 0) {
                                    $variation['duration'] = (float)$meta['duration'];
                                }
                            }
                            // Fallback: use main track duration if variation duration is still missing
                            if (empty($variation['duration']) || $variation['duration'] == 0) {
                                $variation['duration'] = (float)($track['duration'] ?? 0);
                            }
                        } else {
                            $variation['duration'] = (float)$variation['duration'];
                        }
                        
                        unset($variation['source_audio_url']);
                    }
                    unset($variation);
                    
                    $track['variations'] = $raw_variations;
                }
            }
            
            $track['variation_count'] = count($track['variations']);
        }
        unset($track);
    } else {
        foreach ($recent_tracks as &$track) {
            $track['variations'] = [];
            $track['variation_count'] = 0;
        }
        unset($track);
    }
}

// Get all available genres from user's tracks
$genres_query = $pdo->prepare("
    SELECT DISTINCT COALESCE(
        JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.genre')),
        mt.genre,
        'Electronic'
    ) as genre
    FROM music_tracks mt
    WHERE mt.user_id = ?
    AND (
        JSON_EXTRACT(metadata, '$.genre') IS NOT NULL 
        OR mt.genre IS NOT NULL
    )
    AND COALESCE(
        JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.genre')),
        mt.genre,
        ''
    ) != ''
    ORDER BY genre ASC
");
$genres_query->execute([$_SESSION['user_id']]);
$available_genres = $genres_query->fetchAll(PDO::FETCH_COLUMN);

// Add popular genres if missing from database
$popular_genres = ['Electronic', 'House', 'Techno', 'Pop', 'Hip Hop', 'Rock', 'Jazz', 'Classical', 'Ambient', 'Trance', 'Dubstep', 'R&B', 'Reggae', 'Country', 'Folk', 'Blues', 'Funk', 'Disco', 'Drum & Bass', 'Progressive', 'Chillout', 'Lofi'];
foreach ($popular_genres as $genre) {
    if (!in_array($genre, $available_genres)) {
        $available_genres[] = $genre;
    }
}
$available_genres = array_unique($available_genres);
sort($available_genres);

// Get total count for pagination
$count_stmt = $pdo->prepare("
    SELECT COUNT(*) as total
    FROM music_tracks mt
    WHERE mt.status = 'complete'
    AND mt.audio_url IS NOT NULL 
    AND mt.audio_url != ''
");
$count_stmt->execute();
$total_tracks = $count_stmt->fetch()['total'];
$total_pages = ceil($total_tracks / $per_page);

// Get community stats
$community_stats = [
    'total_tracks' => $total_tracks,
    'total_artists' => count(array_unique(array_column($recent_tracks, 'artist_name'))),
    'total_likes' => 0,
    'total_comments' => 0,
    'total_shares' => 0
];
?>

<div class="main-content">
    <style>
/* ============================================
   NEXT-GEN LIBRARY - OPTIMIZED & MODERN DESIGN
   Performance-first, beautiful, cutting-edge
   ============================================ */

/* CSS Variables for easy theming */
:root {
    --primary: #667eea;
    --secondary: #764ba2;
    --accent: #f59e0b;
    --success: #48bb78;
    --danger: #ef4444;
    --bg-dark: #0a0a0a;
    --bg-medium: #1a1a1a;
    --bg-light: #2d2d2d;
    --text-primary: #ffffff;
    --text-secondary: #a0aec0;
    --border: rgba(255, 255, 255, 0.1);
    --glass: rgba(255, 255, 255, 0.05);
    --shadow: rgba(102, 126, 234, 0.1);
}

/* Reset & Base */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

    body {
    padding-bottom: 120px;
    background: var(--bg-dark);
    color: var(--text-primary);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', 'Roboto', sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    line-height: 1.6;
}

/* Performance: GPU acceleration for animations */
.hero, .library-content, .track-card, .stat-card {
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
}

/* ============================================
   HERO SECTION - Modern & Bold
   ============================================ */
    .hero {
    padding: 10rem 0 8rem;
    text-align: center;
    background: linear-gradient(135deg, var(--bg-dark) 0%, var(--bg-medium) 50%, var(--bg-dark) 100%);
        position: relative;
        overflow: hidden;
    margin-bottom: 0;
}

.hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background: 
        radial-gradient(circle at 20% 50%, rgba(102, 126, 234, 0.1) 0%, transparent 50%),
        radial-gradient(circle at 80% 80%, rgba(118, 75, 162, 0.1) 0%, transparent 50%),
        url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(102,126,234,0.08)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
    opacity: 1;
    pointer-events: none;
    }
    
    .hero .container {
    max-width: 90rem;
    margin: 0 auto;
    padding: 0 2rem;
    position: relative;
    z-index: 2;
    }
    
    .hero-content {
    max-width: 90rem;
    margin: 0 auto;
    position: relative;
    z-index: 2;
    }
    
    .hero-badge {
    display: inline-block;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.15), rgba(118, 75, 162, 0.15));
    color: var(--primary);
    padding: 1rem 2rem;
    border-radius: 50px;
    font-size: 1.2rem;
        font-weight: 600;
        margin-bottom: 2rem;
    backdrop-filter: blur(20px);
    border: 1px solid rgba(102, 126, 234, 0.2);
    box-shadow: 0 8px 32px rgba(102, 126, 234, 0.1);
    animation: fadeInUp 0.6s ease-out;
    }
    
    .hero-title {
    font-size: clamp(3rem, 8vw, 6rem);
    font-weight: 900;
    line-height: 1.1;
    margin-bottom: 2rem;
    background: linear-gradient(135deg, #ffffff 0%, var(--primary) 50%, var(--secondary) 100%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
    animation: fadeInUp 0.8s ease-out 0.2s both;
    letter-spacing: -0.02em;
    }
    
    .hero-subtitle {
    font-size: clamp(1.4rem, 3vw, 2rem);
    font-weight: 400;
    margin-bottom: 0;
    opacity: 0.85;
    max-width: 70rem;
    margin-left: auto;
    margin-right: auto;
    color: var(--text-secondary);
    animation: fadeInUp 1s ease-out 0.4s both;
}

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
            opacity: 1;
        transform: translateY(0);
    }
}

/* ============================================
   LIBRARY CONTENT - Organic Flow
   ============================================ */
.library-content,
.community-content {
    background: linear-gradient(135deg, var(--bg-medium) 0%, var(--bg-light) 100%);
    padding: 6rem 0;
    border-radius: 50px 50px 0 0;
    margin-top: -3rem;
        position: relative;
    z-index: 10;
    min-height: 60vh;
}

.library-container,
.community-container {
    max-width: 140rem;
    margin: 0 auto;
    padding: 0 2rem;
}

/* ============================================
   STATS CARDS - Modern Grid
   ============================================ */
.stats-grid,
.community-stats {
        display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 2rem;
    margin-bottom: 4rem;
}

.stat-card {
    background: var(--glass);
    padding: 2.5rem;
    border-radius: 24px;
    backdrop-filter: blur(20px);
    border: 1px solid var(--border);
        text-align: center;
    transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        position: relative;
    overflow: hidden;
}

.stat-card::before {
    content: '';
        position: absolute;
    top: 0;
        left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--primary), var(--secondary));
    transform: scaleX(0);
    transition: transform 0.4s ease;
}

.stat-card:hover::before {
    transform: scaleX(1);
}

.stat-card:hover {
    transform: translateY(-8px);
    border-color: rgba(102, 126, 234, 0.4);
    box-shadow: 0 20px 60px var(--shadow);
}

.stat-number {
    font-size: clamp(2.5rem, 5vw, 4.8rem);
    font-weight: 900;
    color: var(--primary);
    margin-bottom: 0.5rem;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.stat-label {
    color: var(--text-secondary);
    font-size: 1.2rem;
    font-weight: 500;
}

/* ============================================
   FILTERS - Clean & Modern
   ============================================ */
.filters-section,
    .unified-filters {
    background: var(--glass);
    padding: 2rem;
    border-radius: 20px;
        backdrop-filter: blur(20px);
    border: 1px solid var(--border);
    margin-bottom: 4rem;
    }
    
    .filter-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
        gap: 1.5rem;
    align-items: end;
    }
    
    .filter-group {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }
    
    .filter-label {
        font-size: 0.9rem;
    color: var(--text-secondary);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.5px;
    }
    
    .filter-select {
        background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    border-radius: 12px;
    color: var(--text-primary);
    padding: 1rem 1.2rem;
        font-size: 1rem;
        transition: all 0.3s ease;
        cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
    background-position: right 1rem center;
    background-repeat: no-repeat;
    background-size: 1.5rem;
    padding-right: 3.5rem;
    }
    
    .filter-select:hover {
    border-color: rgba(102, 126, 234, 0.4);
    background-color: rgba(255, 255, 255, 0.08);
    }
    
    .filter-select:focus {
        outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}

/* ============================================
   TRACKS GRID - Modern Feed Layout
   ============================================ */
.tracks-grid {
        display: flex;
    flex-direction: column;
    gap: 2.5rem;
    max-width: 90rem;
    margin: 0 auto;
}

/* ============================================
   MONTH GROUPING - Collapsible Sections
   ============================================ */
.month-group {
    margin-bottom: 1rem;
}

.month-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.2rem 1.8rem;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.1) 100%);
    border: 1px solid rgba(102, 126, 234, 0.25);
    border-radius: 14px;
    cursor: pointer;
    transition: all 0.3s ease;
    user-select: none;
    margin-bottom: 0;
}

.month-header:hover {
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.22) 0%, rgba(118, 75, 162, 0.15) 100%);
    border-color: rgba(102, 126, 234, 0.4);
    transform: translateY(-1px);
}

.month-header-left {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.month-icon {
    font-size: 1.4rem;
}

.month-title {
    font-size: 1.3rem;
    font-weight: 600;
    color: #fff;
    letter-spacing: 0.02em;
}

.month-count {
    font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.6);
    font-weight: 400;
    margin-left: 0.5rem;
}

.month-toggle {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.9rem;
}

.month-toggle i {
    font-size: 1.1rem;
    transition: transform 0.3s ease;
}

.month-header.collapsed .month-toggle i {
    transform: rotate(-90deg);
}

.month-tracks {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1.5rem 0 0.5rem 0;
    overflow: hidden;
    transition: max-height 0.4s ease, opacity 0.3s ease, padding 0.3s ease;
}

.month-tracks.collapsed {
    max-height: 0 !important;
    opacity: 0;
    padding: 0;
    pointer-events: none;
}

/* Stagger animation for tracks appearing */
.month-tracks .track-card-modern {
    animation: fadeSlideIn 0.3s ease forwards;
    opacity: 0;
}

@keyframes fadeSlideIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.month-tracks .track-card-modern:nth-child(1) { animation-delay: 0.05s; }
.month-tracks .track-card-modern:nth-child(2) { animation-delay: 0.1s; }
.month-tracks .track-card-modern:nth-child(3) { animation-delay: 0.15s; }
.month-tracks .track-card-modern:nth-child(4) { animation-delay: 0.2s; }
.month-tracks .track-card-modern:nth-child(5) { animation-delay: 0.25s; }

/* ============================================
   TRACK CARD - Next-Gen Design (Image-Based)
   ============================================ */
.track-card-modern {
    background: var(--glass);
    padding: 2rem;
        border-radius: 20px;
        backdrop-filter: blur(20px);
    border: 1px solid var(--border);
        transition: all 0.3s ease;
    position: relative;
            margin-bottom: 1.5rem;
        display: flex;
        flex-direction: column;
    gap: 1.5rem;
}

.track-card-modern:hover {
    transform: translateY(-4px);
    border-color: rgba(102, 126, 234, 0.4);
    box-shadow: 0 20px 60px var(--shadow);
}

/* Status Badge (Top Right) */
.track-status-badge {
        position: absolute;
    top: 1.5rem;
    right: 1.5rem;
    background: linear-gradient(135deg, var(--success), #38a169);
        color: white;
    padding: 0.4rem 0.8rem;
        border-radius: 12px;
    font-size: 0.75rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.5px;
    z-index: 10;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    pointer-events: none;
    white-space: nowrap;
}

.track-status-badge.private {
    background: linear-gradient(135deg, #9ca3af, #6b7280);
}

/* Track Card Content */
.track-card-content {
    display: flex;
    align-items: flex-start;
    gap: 2rem;
}

/* Track Main Info (Icon + Details) */
.track-main-info {
        display: flex;
    gap: 1.5rem;
    flex: 1;
    min-width: 0;
}

/* Track Icon */
.track-icon {
    width: 80px;
    height: 80px;
    min-width: 80px;
    border-radius: 16px;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
        display: flex;
        align-items: center;
    justify-content: center;
    font-size: 2rem;
        color: white;
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.3);
    flex-shrink: 0;
    position: relative;
    cursor: pointer;
}

.track-icon:hover .track-image-upload-overlay {
    opacity: 1;
}

/* Track Image Container */
.track-image-container {
    width: 80px;
    height: 80px;
    min-width: 80px;
    border-radius: 16px;
    overflow: hidden;
    flex-shrink: 0;
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.3);
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    position: relative;
    cursor: pointer;
}

.track-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: opacity 0.3s ease;
}

/* Upload Overlay - appears on hover */
.track-image-upload-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    opacity: 0;
    transition: opacity 0.3s ease;
    border-radius: 16px;
    z-index: 5;
}

.track-image-container:hover .track-image-upload-overlay {
    opacity: 1;
}

.track-image-container:hover .track-image {
    opacity: 0.7;
}

.track-image-upload-icon,
.track-image-download-icon {
    color: white;
    font-size: 1.5rem;
    pointer-events: none;
}

.track-image-action-button {
    width: 36px;
    height: 36px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;
    margin: 0;
}

.track-image-action-button:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: scale(1.1);
}

.track-image-action-button input[type="file"] {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    z-index: 10;
    font-size: 0;
    line-height: 0;
}

.track-image-upload-input {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    z-index: 10;
}

.track-image-upload-overlay.uploading {
    background: rgba(102, 126, 234, 0.8);
}

.track-image-upload-overlay.uploading .track-image-upload-icon {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* Track Details */
.track-details {
    flex: 1;
    min-width: 0;
}

.track-name {
    font-size: 1.5rem;
        font-weight: 800;
    color: var(--text-primary);
    margin: 0 0 0.5rem 0;
        line-height: 1.3;
}

.track-title-link {
    color: var(--text-primary);
    text-decoration: none;
    transition: color 0.2s ease, opacity 0.2s ease;
}

.track-title-link:hover {
    color: var(--primary-color);
    opacity: 0.9;
}

.track-artist-name {
    font-size: 1rem;
    color: var(--text-secondary);
    margin: 0 0 0.75rem 0;
}

.artist-name-link {
    color: var(--text-secondary);
    text-decoration: none;
    transition: color 0.2s ease, opacity 0.2s ease;
}

.artist-name-link:hover {
    color: var(--primary-color);
    opacity: 0.9;
}

.track-description {
    font-size: 0.9rem;
    color: var(--text-secondary);
    line-height: 1.5;
    margin: 0 0 1rem 0;
    opacity: 0.8;
}

/* Metadata Row */
.track-metadata-row {
        display: flex;
        flex-wrap: wrap;
    gap: 1.5rem;
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin-top: 0.5rem;
    }
    
.meta-item {
        display: flex;
        align-items: center;
    gap: 0.3rem;
    }
    
.meta-item strong {
    color: var(--text-primary);
    font-weight: 600;
    }
    
/* Action Buttons Row */
.track-actions-row {
        display: flex;
        align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
}

/* Large Play Button */
.play-btn-large {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
        border: none;
    color: white;
    font-size: 1.2rem;
        cursor: pointer;
        transition: all 0.3s ease;
        display: flex;
        align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.4);
    flex-shrink: 0;
}

.play-btn-large:hover {
    transform: scale(1.1);
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.6);
}

/* Icon Action Buttons */
.action-icon-btn {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 1rem;
        cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.action-icon-btn:hover {
        background: rgba(255, 255, 255, 0.1);
        border-color: rgba(102, 126, 234, 0.3);
    color: var(--text-primary);
        transform: translateY(-2px);
    }
    
.action-icon-btn i.fa-heart:hover {
    color: #ef4444;
}

.action-icon-btn.liked {
    background: rgba(239, 68, 68, 0.1);
    border-color: rgba(239, 68, 68, 0.3);
}

.action-icon-btn.liked i.fa-heart {
    color: #ef4444;
}

.action-icon-btn.liked:hover i.fa-heart {
    color: #dc2626;
}

/* Processing/Failed Indicators */
.processing-indicator,
.failed-indicator {
        display: flex;
        align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-radius: 10px;
    font-size: 0.9rem;
    font-weight: 600;
}

.processing-indicator {
    background: rgba(245, 158, 11, 0.1);
    color: var(--accent);
    border: 1px solid rgba(245, 158, 11, 0.3);
}

/* Modern Processing Indicator */
.processing-indicator-modern {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    background: linear-gradient(135deg, rgba(245, 158, 11, 0.1), rgba(245, 158, 11, 0.15));
    border: 1.5px solid rgba(245, 158, 11, 0.25);
    border-radius: 10px;
    backdrop-filter: blur(8px);
    box-shadow: 0 2px 10px rgba(245, 158, 11, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.1);
    min-width: 0;
    flex: 1;
    max-width: 100%;
    position: relative;
    z-index: 1;
    margin-right: 0;
}

.processing-spinner {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #f59e0b;
    font-size: 0.95rem;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

.processing-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    flex: 1;
    line-height: 1.3;
}

.processing-main {
    font-size: 0.875rem;
    font-weight: 600;
    color: #f59e0b;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    letter-spacing: 0.01em;
}

.processing-subtitle {
    font-size: 0.7rem;
    font-weight: 400;
    color: rgba(245, 158, 11, 0.65);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    letter-spacing: 0.01em;
}

.failed-indicator {
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger);
    border: 1px solid rgba(239, 68, 68, 0.3);
}

.track-card::before {
    content: '';
        position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.05), rgba(118, 75, 162, 0.05));
        opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
}

.track-card:hover {
    transform: translateY(-8px);
    border-color: rgba(102, 126, 234, 0.4);
    box-shadow: 0 25px 80px var(--shadow);
}

.track-card:hover::before {
    opacity: 1;
}

/* Track Header */
.track-header,
.compact-header {
    padding: 2.5rem;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 2rem;
    border-bottom: 1px solid var(--border);
}

.compact-header {
    flex-wrap: wrap;
}

.artist-mini {
        display: flex;
        align-items: center;
        gap: 1rem;
    flex: 1;
    min-width: 0;
}

.artist-avatar-mini {
    flex-shrink: 0;
}

.default-avatar-mini {
        width: 50px;
        height: 50px;
    border-radius: 12px;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
    font-weight: 800;
        font-size: 1.2rem;
    }
    
.artist-info-mini {
    flex: 1;
    min-width: 0;
}

.track-title-mini {
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-weight: 800;
    color: var(--text-primary);
    margin-bottom: 0.3rem;
    line-height: 1.2;
    word-wrap: break-word;
}

.artist-name-mini {
    font-size: 1.1rem;
    color: var(--primary);
        font-weight: 600;
    }
    
.track-header-content {
    flex: 1;
    min-width: 0;
}

.track-title {
    font-size: clamp(1.8rem, 4vw, 2.4rem);
    font-weight: 800;
    color: var(--text-primary);
    margin-bottom: 0.5rem;
    line-height: 1.2;
    word-wrap: break-word;
}

.track-artist {
    font-size: 1.3rem;
    color: var(--primary);
    font-weight: 600;
         display: flex;
         align-items: center;
    gap: 0.5rem;
}

.track-status {
         display: flex;
    flex-direction: column;
    align-items: flex-end;
         gap: 0.5rem;
     }
     
.status-badge {
         padding: 0.5rem 1rem;
    border-radius: 12px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.status-complete {
    background: linear-gradient(135deg, var(--success), #38a169);
         color: white;
}

.status-processing {
    background: linear-gradient(135deg, var(--accent), #d97706);
         color: white;
    animation: pulse 2s infinite;
}

.status-failed {
    background: linear-gradient(135deg, var(--danger), #dc2626);
         color: white;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
}

/* Track Prompt */
.track-prompt {
    padding: 2rem 2.5rem;
    font-size: 1.3rem;
    color: var(--text-secondary);
    line-height: 1.7;
    background: rgba(255, 255, 255, 0.02);
    border-left: 4px solid var(--primary);
    margin: 0;
}

/* Track Metadata */
     .track-metadata {
    padding: 2rem 2.5rem;
         display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1.5rem;
    border-top: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.02);
     }
     
     .metadata-item {
         display: flex;
         flex-direction: column;
    gap: 0.5rem;
     }
     
     .metadata-label {
    font-size: 0.85rem;
    color: var(--text-secondary);
    font-weight: 600;
         text-transform: uppercase;
         letter-spacing: 0.5px;
     }
     
     .metadata-value {
    font-size: 1.1rem;
    color: var(--text-primary);
    font-weight: 700;
}

/* Track Actions */
.track-actions {
    padding: 2rem 2.5rem;
         display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    border-top: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.02);
}

.action-btn {
    flex: 1;
    min-width: 140px;
    padding: 1.2rem 2rem;
    border-radius: 14px;
    font-size: 1rem;
    font-weight: 600;
         cursor: pointer;
         transition: all 0.3s ease;
         display: flex;
         align-items: center;
         justify-content: center;
    gap: 0.8rem;
    border: none;
    text-decoration: none;
}

.action-btn-primary {
    background: linear-gradient(135deg, var(--primary), var(--secondary));
         color: white;
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.3);
}

.action-btn-primary:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 32px rgba(102, 126, 234, 0.4);
}

.action-btn-secondary {
    background: var(--glass);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

.action-btn-secondary:hover {
         background: rgba(255, 255, 255, 0.1);
    border-color: rgba(102, 126, 234, 0.3);
         transform: translateY(-2px);
}

.action-btn-compact {
    padding: 0.8rem 1.5rem;
         border-radius: 12px;
    font-size: 0.9rem;
    font-weight: 600;
         cursor: pointer;
         transition: all 0.3s ease;
    display: inline-flex;
         align-items: center;
         gap: 0.5rem;
    border: none;
    text-decoration: none;
    background: var(--glass);
    color: var(--text-primary);
    border: 1px solid var(--border);
     }
     
.action-btn-compact:hover {
         background: rgba(255, 255, 255, 0.1);
    border-color: rgba(102, 126, 234, 0.3);
    transform: translateY(-2px);
}

.action-btn-compact.primary {
    background: linear-gradient(135deg, var(--primary), var(--secondary));
         color: white;
         border: none;
    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
}

.action-btn-compact.primary:hover {
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
    transform: translateY(-3px);
}

.track-number-badge {
        position: absolute;
    top: 1.5rem;
    right: 1.5rem;
    background: linear-gradient(135deg, var(--primary), var(--secondary));
        color: white;
    padding: 0.5rem 1rem;
    border-radius: 12px;
        font-size: 0.9rem;
    font-weight: 800;
    z-index: 10;
    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
}

.track-badge {
    display: inline-block;
    background: linear-gradient(135deg, var(--accent), #d97706);
    color: white;
    padding: 0.4rem 0.8rem;
    border-radius: 10px;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.status-indicator {
    display: flex;
        align-items: center;
    gap: 0.5rem;
}

.error-message-modern {
    padding: 1.5rem;
    margin: 1.5rem 2.5rem;
    background: rgba(239, 68, 68, 0.1);
    border: 1px solid rgba(239, 68, 68, 0.3);
    border-radius: 12px;
    border-left: 4px solid var(--danger);
}

.error-header {
    color: var(--danger);
    font-weight: 700;
        margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.error-content {
    color: #fca5a5;
    font-size: 0.95rem;
    line-height: 1.6;
}

/* ============================================
   RESPONSIVE - Mobile First
   ============================================ */
@media (max-width: 768px) {
    .hero {
        padding: 6rem 0 4rem;
    }
    
    .library-content,
    .community-content {
        padding: 4rem 0;
        border-radius: 30px 30px 0 0;
    }
    
    .stats-grid,
    .community-stats {
            grid-template-columns: repeat(2, 1fr);
        gap: 1.5rem;
    }
    
    .filter-row {
        grid-template-columns: 1fr;
    }
    
    .filter-group {
        width: 100%;
    }
    
    #trackSearch {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box;
    }
        
    .track-card-modern {
        padding: 1.5rem;
    }
    
    .track-card-content {
        flex-direction: column;
        gap: 1.5rem;
    }
    
    .track-main-info {
            flex-direction: column;
        gap: 1rem;
    }
    
    .track-icon {
        width: 60px;
        height: 60px;
        min-width: 60px;
        font-size: 1.5rem;
    }
    
    .track-name {
        font-size: 1.3rem;
    }
    
    .track-metadata-row {
        flex-direction: column;
        gap: 0.75rem;
    }
    
    .track-actions-row {
        width: 100%;
        justify-content: flex-start;
        flex-wrap: wrap;
        gap: 0.5rem;
    }
    
    .play-btn-large {
        width: 48px;
        height: 48px;
        font-size: 1rem;
        flex-shrink: 0;
    }
    
    .action-icon-btn {
        width: 40px;
        height: 40px;
        font-size: 0.95rem;
        flex-shrink: 0;
    }
    
    /* Variations grid mobile */
    .variations-grid {
        grid-template-columns: 1fr !important;
        gap: 1rem;
        padding: 1rem;
    }
    
    /* Track metadata mobile */
    .track-metadata {
        grid-template-columns: 1fr !important;
        gap: 1rem;
    }
    
    /* Progress & Activity Section - Force single column on mobile */
    div[style*="grid-template-columns: 1fr 1fr"] {
        grid-template-columns: 1fr !important;
        gap: 2rem !important;
    }
    
    /* My Crates Section - Mobile Responsive */
    #cratesSection {
        padding: 1.5rem !important;
        margin-bottom: 2rem !important;
    }
    
    #cratesSection > div:first-child {
        flex-direction: column !important;
        align-items: flex-start !important;
        gap: 1rem !important;
    }
    
    #cratesSection h3 {
        font-size: 1.5rem !important;
    }
    
    #cratesSection button {
        padding: 0.75rem 1.5rem !important;
        font-size: 1rem !important;
        width: 100%;
    }
    
    #cratesList {
        grid-template-columns: 1fr !important;
        gap: 1.5rem !important;
        max-height: none !important;
    }
}

@media (max-width: 480px) {
    .hero {
        padding: 4rem 0 3rem;
    }
    
    .library-content,
    .community-content {
        padding: 3rem 0;
    }
    
    .stats-grid,
    .community-stats {
        grid-template-columns: 1fr;
        gap: 1rem;
    }
    
    .track-card-modern {
        padding: 1.2rem;
    }
    
    .track-icon {
        width: 50px;
        height: 50px;
        min-width: 50px;
        font-size: 1.3rem;
    }
    
    .track-name {
        font-size: 1.2rem;
    }
    
    /* Variations grid small mobile */
    .variations-grid {
        grid-template-columns: 1fr !important;
        gap: 0.75rem;
        padding: 0.75rem;
    }
    
    /* Track metadata small mobile */
    .track-metadata {
        grid-template-columns: 1fr !important;
        gap: 0.75rem;
    }
    
    /* Progress & Activity Section - Force single column on small mobile */
    div[style*="grid-template-columns: 1fr 1fr"] {
        grid-template-columns: 1fr !important;
        gap: 1.5rem !important;
    }
    
    /* My Crates Section - Small Mobile */
    #cratesSection {
        padding: 1.2rem !important;
    }
    
    #cratesSection h3 {
        font-size: 1.3rem !important;
    }
    
    #cratesSection button {
        padding: 0.65rem 1.2rem !important;
        font-size: 0.95rem !important;
    }
    
    #cratesList {
        gap: 1.2rem !important;
    }
}
    
    .play-btn-large {
        width: 44px;
        height: 44px;
        font-size: 0.9rem;
        flex-shrink: 0;
    }
    
    .action-icon-btn {
        width: 38px;
        height: 38px;
        font-size: 0.9rem;
        flex-shrink: 0;
    }
    
    .track-actions-row {
        gap: 0.4rem;
    }
}

/* ============================================
   UTILITIES
   ============================================ */
.empty-state {
    text-align: center;
    padding: 6rem 2rem;
    color: var(--text-secondary);
}

.empty-icon {
    font-size: 5rem;
    margin-bottom: 2rem;
    opacity: 0.5;
}

.empty-title {
    font-size: 2rem;
    color: var(--text-primary);
    margin-bottom: 1rem;
        font-weight: 700;
}

.empty-description {
    font-size: 1.2rem;
    margin-bottom: 2rem;
    max-width: 500px;
    margin-left: auto;
    margin-right: auto;
}

/* Alerts */
.alert {
    padding: 1.5rem 2rem;
    border-radius: 12px;
    margin: 2rem auto;
    max-width: 90rem;
    backdrop-filter: blur(20px);
    border: 1px solid;
}

.alert-success {
    background: rgba(72, 187, 120, 0.1);
    border-color: rgba(72, 187, 120, 0.3);
    color: #48bb78;
}

.alert-error {
    background: rgba(239, 68, 68, 0.1);
    border-color: rgba(239, 68, 68, 0.3);
    color: #ef4444;
}

/* ============================================
   MODAL BASE STYLES
   ============================================ */
.modal {
    display: none !important;
    position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(10px);
    z-index: 10000;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}

.modal-content {
    background: linear-gradient(135deg, var(--bg-medium) 0%, var(--bg-light) 100%);
    border: 1px solid var(--border);
    border-radius: 24px;
    max-width: 600px;
        width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    padding: 2rem;
    backdrop-filter: blur(20px);
    box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
    color: var(--text-primary);
}

/* Edit Modal Form Styles */
#editTrackModal .form-group {
        margin-bottom: 1.5rem;
    }
    
#editTrackModal .form-label {
        display: block;
    margin-bottom: 0.5rem;
    color: var(--text-primary);
        font-weight: 600;
    font-size: 0.95rem;
}

#editTrackModal .form-input {
    width: 100%;
    padding: 0.75rem 1rem;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    color: var(--text-primary);
    font-size: 0.95rem;
        transition: all 0.3s ease;
    box-sizing: border-box;
}

#editTrackModal .form-input:focus {
    outline: none;
    border-color: rgba(102, 126, 234, 0.5);
    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
    background: rgba(255, 255, 255, 0.08);
}

#editTrackModal .form-input::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

#editTrackModal textarea.form-input {
    resize: vertical;
    min-height: 120px;
    font-family: inherit;
}

#editTrackModal .form-label input[type="checkbox"] {
    margin-right: 0.5rem;
    width: auto;
    cursor: pointer;
}

#editTrackModal .form-actions {
        display: flex;
        gap: 1rem;
    justify-content: flex-end;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

#editTrackModal .btn {
    padding: 0.75rem 1.5rem;
        border: none;
    border-radius: 10px;
    font-size: 0.95rem;
    font-weight: 600;
        cursor: pointer;
    transition: all 0.3s ease;
    display: inline-flex;
        align-items: center;
        gap: 0.5rem;
}

#editTrackModal .btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
    }
    
#editTrackModal .btn-primary:hover {
        transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

#editTrackModal .btn:not(.btn-primary) {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-primary);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

#editTrackModal .btn:not(.btn-primary):hover {
    background: rgba(255, 255, 255, 0.15);
}

#editTrackModal h2 {
    color: var(--text-primary);
    margin: 0;
    font-size: 1.5rem;
        font-weight: 700;
}

#editTrackModal .btn i {
    font-size: 0.9rem;
}

/* ============================================
   VARIATIONS MODAL
   ============================================ */
.variations-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(10px);
    z-index: 10000;
        display: none;
        align-items: center;
        justify-content: center;
        padding: 2rem;
    }
    
.variations-modal.active {
        display: flex;
}

/* ============================================
   LYRICS MODAL
   ============================================ */
.lyrics-modal {
    display: none !important;
    position: fixed;
        top: 0;
    left: 0;
        width: 100%;
        height: 100%;
    background: rgba(0, 0, 0, 0.85);
        backdrop-filter: blur(10px);
    z-index: 10000;
        align-items: center;
    justify-content: center;
    padding: 2rem;
}

.lyrics-modal.active {
    display: flex !important;
}

/* ============================================
   DOWNLOAD MODAL
   ============================================ */
.download-modal {
    display: none !important;
    position: fixed;
    top: 0;
    left: 0;
        width: 100%;
        height: 100%;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(10px);
    z-index: 10000;
        align-items: center;
        justify-content: center;
    padding: 2rem;
}

.download-modal.active {
    display: flex !important;
}

.variations-content {
    background: linear-gradient(135deg, var(--bg-medium) 0%, var(--bg-light) 100%);
    border: 1px solid var(--border);
    border-radius: 24px;
    max-width: 90rem;
    max-height: 90vh;
    width: 100%;
        overflow: hidden;
        display: flex;
    flex-direction: column;
    backdrop-filter: blur(20px);
    box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
}

.variations-header {
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    padding: 2rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
}

.variations-title {
        color: white;
    font-size: 1.8rem;
    font-weight: 800;
    margin: 0;
}

.close-variations {
    background: rgba(255, 255, 255, 0.2);
        border: none;
        color: white;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 1.2rem;
    transition: all 0.3s ease;
        display: flex;
        align-items: center;
        justify-content: center;
}

.close-variations:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: rotate(90deg);
}

.variations-grid {
        display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.5rem;
    padding: 2rem;
    overflow-y: auto;
    flex: 1;
}

.variation-card {
    background: var(--glass);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 1.5rem;
    cursor: pointer;
        transition: all 0.3s ease;
        position: relative;
}

.variation-card:hover {
    transform: translateY(-4px);
        border-color: rgba(102, 126, 234, 0.4);
    box-shadow: 0 12px 32px var(--shadow);
}

.variation-card.selected {
    border-color: var(--primary);
    background: rgba(102, 126, 234, 0.1);
    box-shadow: 0 0 0 2px var(--primary);
}

.variation-header {
        display: flex;
    justify-content: space-between;
    align-items: center;
        margin-bottom: 1rem;
}

.variation-title {
    font-weight: 700;
    color: var(--text-primary);
    font-size: 1.1rem;
}

.variation-index {
    background: var(--primary);
        color: white;
    padding: 0.3rem 0.6rem;
    border-radius: 8px;
    font-size: 0.75rem;
    font-weight: 700;
}

.variation-duration {
    color: var(--text-secondary);
    font-size: 0.9rem;
        margin-bottom: 1rem;
}

.variation-actions {
        display: flex;
        gap: 0.5rem;
    flex-wrap: wrap;
}

.variation-btn {
    background: var(--glass);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.6rem 1rem;
    border-radius: 10px;
        cursor: pointer;
    font-size: 0.85rem;
        font-weight: 600;
        transition: all 0.3s ease;
        display: flex;
        align-items: center;
        gap: 0.5rem;
}

.variation-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(102, 126, 234, 0.3);
}

.variation-btn.play {
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    border: none;
            color: white;
}

.variation-btn.download {
    background: linear-gradient(135deg, var(--success), #38a169);
            border: none;
            color: white;
}

.variation-btn.select {
    background: linear-gradient(135deg, var(--accent), #d97706);
    border: none;
            color: white;
}

.variation-btn.select.selected {
    background: linear-gradient(135deg, var(--success), #38a169);
}

.variations-footer {
            padding: 2rem;
    border-top: 1px solid var(--border);
    background: rgba(255, 255, 255, 0.02);
}

.variations-info {
    color: var(--text-secondary);
    font-size: 0.9rem;
            margin-bottom: 1.5rem;
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    line-height: 1.6;
}

.variations-actions {
            display: flex;
            gap: 1rem;
            justify-content: flex-end;
}

.variations-btn {
    padding: 0.9rem 2rem;
    border-radius: 12px;
            cursor: pointer;
    font-weight: 600;
            transition: all 0.3s ease;
    border: none;
    font-size: 1rem;
}

.variations-btn.cancel {
    background: var(--glass);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

.variations-btn.cancel:hover {
    background: rgba(255, 255, 255, 0.1);
}

.variations-btn.save {
    background: linear-gradient(135deg, var(--primary), var(--secondary));
    color: white;
}

.variations-btn.save:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
}

.variations-btn.save:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

    </style>
    
    <!-- Hero Section -->
    <section class="hero">
        <div class="container">
            <div class="hero-content">
                <div class="hero-badge">🎵 <?= t('library.hero_badge') ?></div>
                <h1 class="hero-title"><?= t('library.hero_title') ?></h1>
                <p class="hero-subtitle"><?= t('library.hero_subtitle') ?></p>
            </div>
        </div>
    </section>

    <!-- Success/Error Messages -->
    <?php if (isset($_SESSION['success_message'])): ?>
        <div class="alert alert-success" style="margin: 1rem; padding: 1rem; background: #d4edda; color: #155724; border: 1px solid #c3e6cb; border-radius: 8px;">
            <?= htmlspecialchars($_SESSION['success_message']) ?>
        </div>
        <?php unset($_SESSION['success_message']); ?>
    <?php endif; ?>
    
    <?php if (isset($_SESSION['error_message'])): ?>
        <div class="alert alert-error" style="margin: 1rem; padding: 1rem; background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 8px;">
            <?= htmlspecialchars($_SESSION['error_message']) ?>
        </div>
        <?php unset($_SESSION['error_message']); ?>
    <?php endif; ?>
    
    <!-- Community Content -->
    <section class="community-content">
        <div class="community-container">
            <!-- Quick Actions -->
            <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 2rem; margin-bottom: 4rem;">
                <a href="/#create" style="background: rgba(255, 255, 255, 0.05); padding: 3rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; text-align: center; text-decoration: none; color: white;">
                    <div style="font-size: 3rem; color: #667eea; margin-bottom: 1.5rem;">🎵</div>
                    <div style="font-size: 2rem; font-weight: 700; margin-bottom: 1rem; color: white;"><?= t('library.create_music') ?></div>
                    <div style="color: #a0aec0; font-size: 1.4rem; margin-bottom: 1.5rem; line-height: 1.5;"><?= t('library.create_music_desc') ?></div>
                    <div style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 1rem 2rem; border-radius: 12px; font-weight: 600; font-size: 1.3rem; cursor: pointer; transition: all 0.3s ease; text-decoration: none; display: inline-flex; align-items: center; gap: 0.8rem;">
                        <i class="fas fa-plus"></i> <?= t('btn.start_creating') ?>
                    </div>
                </a>
                
                <a href="/artists.php" style="background: rgba(255, 255, 255, 0.05); padding: 3rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; text-align: center; text-decoration: none; color: white;">
                    <div style="font-size: 3rem; color: #667eea; margin-bottom: 1.5rem;">👥</div>
                    <div style="font-size: 2rem; font-weight: 700; margin-bottom: 1rem; color: white;"><?= t('library.discover_artists') ?></div>
                    <div style="color: #a0aec0; font-size: 1.4rem; margin-bottom: 1.5rem; line-height: 1.5;"><?= t('library.discover_artists_desc') ?></div>
                    <div style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 1rem 2rem; border-radius: 12px; font-weight: 600; font-size: 1.3rem; cursor: pointer; transition: all 0.3s ease; text-decoration: none; display: inline-flex; align-items: center; gap: 0.8rem;">
                        <i class="fas fa-users"></i> <?= t('library.browse_artists') ?>
                    </div>
                </a>
            </div>
            
            <!-- Library Stats -->
            <div class="community-stats">
                <div class="stat-card">
                    <div class="stat-number"><?= $user_stats['total_tracks'] ?></div>
                    <div class="stat-label"><?= t('library.total_tracks') ?></div>
                    <div style="font-size: 1.2rem; margin-top: 0.5rem; color: #10b981;">+<?= $user_stats['completed_tracks'] ?> <?= t('library.completed') ?></div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= round(($user_stats['total_duration'] ?? 0) / 60, 1) ?></div>
                    <div class="stat-label"><?= t('library.total_minutes') ?></div>
                    <div style="font-size: 1.2rem; margin-top: 0.5rem; color: #a0aec0;"><?= $user_stats['total_duration'] ?? 0 ?> <?= t('library.seconds') ?></div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= $credits ?></div>
                    <div class="stat-label"><?= t('library.credits_left') ?></div>
                    <div style="font-size: 1.2rem; margin-top: 0.5rem; color: #a0aec0;">
                        <?php if ($subscription_info && $subscription_usage): ?>
                            <?= ucfirst($subscription_info['plan_name']) ?> <?= t('library.plan_label') ?> • 
                            <?= ($subscription_usage['track_limit'] - ($subscription_usage['tracks_created'] ?? 0)) ?> <?= t('library.subscription_tracks_left') ?>
                        <?php else: ?>
                            <?= ucfirst($plan) ?> <?= t('library.plan') ?>
                        <?php endif; ?>
                    </div>
                </div>
                <div class="stat-card">
                    <div class="stat-number"><?= $user_level ?></div>
                    <div class="stat-label"><?= t('library.creator_level') ?></div>
                    <div style="font-size: 1.2rem; margin-top: 0.5rem; color: #10b981;"><?= $xp ?> XP</div>
                </div>
            </div>
            
            <!-- Progress & Activity Section -->
            <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; margin-bottom: 4rem;">
                <!-- Progress Overview -->
                <div style="background: rgba(255, 255, 255, 0.05); padding: 2.5rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1);">
                    <h3 style="font-size: 2rem; font-weight: 700; color: white; margin-bottom: 2rem;"><?= t('library.progress_overview') ?></h3>
                    
                    <div style="margin-bottom: 2rem;">
                        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
                            <span style="font-size: 1.4rem; font-weight: 600; color: white;"><?= t('library.completion_rate') ?></span>
                            <span style="font-size: 1.4rem; color: #a0aec0;"><?php echo $user_stats['total_tracks'] > 0 ? round(($user_stats['completed_tracks'] / $user_stats['total_tracks']) * 100) : 0; ?>%</span>
                        </div>
                        <div style="width: 100%; height: 8px; background: rgba(255, 255, 255, 0.1); border-radius: 4px; overflow: hidden;">
                            <div style="height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); border-radius: 4px; transition: width 0.3s ease; width: <?php echo $user_stats['total_tracks'] > 0 ? ($user_stats['completed_tracks'] / $user_stats['total_tracks']) * 100 : 0; ?>%;"></div>
                        </div>
                    </div>
                    
                    <div style="margin-bottom: 2rem;">
                        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
                            <span style="font-size: 1.4rem; font-weight: 600; color: white;"><?= t('library.next_level') ?></span>
                            <span style="font-size: 1.4rem; color: #a0aec0;"><?php echo $user_level < 5 ? $user_level + 1 : t('library.max'); ?></span>
                        </div>
                        <div style="width: 100%; height: 8px; background: rgba(255, 255, 255, 0.1); border-radius: 4px; overflow: hidden;">
                            <?php 
                            $next_level_xp = $user_level < 5 ? ($user_level * 200) : 1000;
                            $progress = min(100, ($xp / $next_level_xp) * 100);
                            ?>
                            <div style="height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); border-radius: 4px; transition: width 0.3s ease; width: <?php echo $progress; ?>%;"></div>
                        </div>
                    </div>
                    
                    <div>
                        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
                            <span style="font-size: 1.4rem; font-weight: 600; color: white;"><?= t('library.credits_usage') ?></span>
                            <span style="font-size: 1.4rem; color: #a0aec0;"><?php echo $credits; ?> <?= t('library.remaining') ?></span>
                        </div>
                        <div style="width: 100%; height: 8px; background: rgba(255, 255, 255, 0.1); border-radius: 4px; overflow: hidden;">
                            <div style="height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); border-radius: 4px; transition: width 0.3s ease; width: <?php echo max(0, 100 - ($credits / 5) * 100); ?>%;"></div>
                        </div>
                    </div>
                    <?php if ($subscription_info && $subscription_usage): ?>
                    <div style="margin-top: 2rem;">
                        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
                            <span style="font-size: 1.4rem; font-weight: 600; color: white;">
                                <i class="fas fa-crown" style="color: #48bb78; margin-right: 0.5rem;"></i>
                                <?= ucfirst($subscription_info['plan_name']) ?> <?= t('library.subscription_label') ?>
                            </span>
                            <span style="font-size: 1.4rem; color: #48bb78;">
                                <?= ($subscription_usage['track_limit'] - ($subscription_usage['tracks_created'] ?? 0)) ?> / <?= $subscription_usage['track_limit'] ?> <?= t('subscription.tracks_left') ?>
                            </span>
                        </div>
                        <div style="width: 100%; height: 8px; background: rgba(255, 255, 255, 0.1); border-radius: 4px; overflow: hidden;">
                            <div style="height: 100%; background: linear-gradient(90deg, #48bb78, #059669); border-radius: 4px; transition: width 0.3s ease; width: <?php echo min(100, (($subscription_usage['tracks_created'] ?? 0) / max(1, $subscription_usage['track_limit'])) * 100); ?>%;"></div>
                        </div>
                        <div style="font-size: 0.9rem; color: #a0aec0; margin-top: 0.5rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
                            <i class="fas fa-calendar-alt"></i>
                            <span>
                                <?= t('subscription.resets_on') ?> 
                                <strong style="color: #48bb78;">
                                    <?php 
                                    if ($subscription_info['current_period_end']) {
                                        $period_end = strtotime($subscription_info['current_period_end']);
                                        $now = time();
                                        $days_remaining = max(0, floor(($period_end - $now) / 86400));
                                        $formatted_date = date('F j, Y', $period_end);
                                        echo $formatted_date;
                                        if ($days_remaining > 0) {
                                            echo ' (' . $days_remaining . ' ' . ($days_remaining === 1 ? t('subscription.day_remaining') : t('subscription.days_remaining')) . ')';
                                        }
                                    } else {
                                        echo t('subscription.your_next_billing_date');
                                    }
                                    ?>
                                </strong>
                            </span>
                        </div>
                    </div>
                    <?php endif; ?>
                </div>
                
                <!-- Recent Activity -->
                <div style="background: rgba(255, 255, 255, 0.05); padding: 2.5rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1);">
                    <h3 style="font-size: 2rem; font-weight: 700; color: white; margin-bottom: 2rem;"><?= t('library.recent_activity') ?></h3>
                    
                    <?php if (empty($recent_activity)): ?>
                        <div style="text-align: center; padding: 2rem 0; color: #a0aec0;">
                            <div style="font-size: 4rem; margin-bottom: 1rem; opacity: 0.5;">📝</div>
                            <h4 style="font-size: 1.6rem; color: white; margin-bottom: 0.5rem;"><?= t('library.no_activity') ?></h4>
                            <p style="font-size: 1.2rem; color: #a0aec0;"><?= t('library.no_activity_desc') ?></p>
                        </div>
                    <?php else: ?>
                        <?php foreach (array_slice($recent_activity, 0, 5) as $activity): ?>
                        <div style="display: flex; align-items: center; gap: 1.5rem; padding: 1.5rem 0; border-bottom: 1px solid rgba(255, 255, 255, 0.1);">
                            <div style="width: 4rem; height: 4rem; border-radius: 50%; background: linear-gradient(135deg, #667eea, #764ba2); display: flex; align-items: center; justify-content: center; font-size: 1.6rem; color: white;">🎵</div>
                            <div style="flex: 1;">
                                <div style="font-size: 1.4rem; font-weight: 600; color: white; margin-bottom: 0.5rem;"><?php echo htmlspecialchars($activity['title']); ?></div>
                                <div style="font-size: 1.2rem; color: #a0aec0;"><?php echo date('M j, g:i A', strtotime($activity['created_at'])); ?></div>
                            </div>
                            <div style="padding: 0.5rem 1rem; border-radius: 20px; font-size: 1.2rem; font-weight: 600; background: <?php echo $activity['status'] === 'complete' ? 'rgba(16, 185, 129, 0.2)' : ($activity['status'] === 'processing' ? 'rgba(245, 158, 11, 0.2)' : 'rgba(239, 68, 68, 0.2)'); ?>; color: <?php echo $activity['status'] === 'complete' ? '#10b981' : ($activity['status'] === 'processing' ? '#f59e0b' : '#ef4444'); ?>;">
                                <?php echo ucfirst($activity['status']); ?>
                            </div>
                        </div>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </div>
            </div>
            
            <!-- Credit History -->
            <?php if (!empty($credit_history)): ?>
            <div style="background: rgba(255, 255, 255, 0.05); padding: 2.5rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); margin-bottom: 4rem;">
                <h3 style="font-size: 2rem; font-weight: 700; color: white; margin-bottom: 2rem;"><?= t('library.credit_history') ?></h3>
                
                <?php foreach ($credit_history as $transaction): ?>
                <div style="display: flex; justify-content: space-between; align-items: center; padding: 1rem 0; border-bottom: 1px solid rgba(255, 255, 255, 0.1);">
                    <div style="flex: 1;">
                        <div style="font-size: 1.4rem; font-weight: 600; color: white; margin-bottom: 0.5rem;"><?php echo htmlspecialchars($transaction['description'] ?? 'Credit transaction'); ?></div>
                        <div style="font-size: 1.2rem; color: #a0aec0;"><?php echo date('M j, g:i A', strtotime($transaction['created_at'])); ?></div>
                    </div>
                    <div style="font-size: 1.6rem; font-weight: 700; color: <?php echo $transaction['amount'] > 0 ? '#10b981' : '#ef4444'; ?>;">
                        <?php echo $transaction['amount'] > 0 ? '+' : ''; ?><?php echo $transaction['amount']; ?>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>
            <?php endif; ?>
            
            <!-- My Crates Section -->
            <div id="cratesSection" style="background: rgba(255, 255, 255, 0.05); padding: 2.5rem; border-radius: 20px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); margin-bottom: 4rem;">
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
                    <h3 style="font-size: 2rem; font-weight: 700; color: white; margin: 0;">🎧 <?= t('library.crates.title') ?></h3>
                    <button onclick="showCreateCrateModal()" style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 1rem 2rem; border-radius: 12px; font-weight: 600; font-size: 1.3rem; cursor: pointer; transition: all 0.3s ease;">
                        <i class="fas fa-plus"></i> <?= t('library.crates.create_new') ?>
                    </button>
                </div>
                
                <div id="cratesList" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 2rem; max-height: 600px; overflow-y: auto; padding-right: 0.5rem;">
                    <!-- Crates will be loaded here via JavaScript -->
                    <div style="text-align: center; padding: 2rem; color: #a0aec0;">
                        <i class="fas fa-spinner fa-spin" style="font-size: 2rem; margin-bottom: 1rem;"></i>
                        <p><?= t('library.crates.loading') ?></p>
                    </div>
                </div>
            </div>
            
            <!-- Unified Filter Controls -->
            <div class="unified-filters">
                <!-- Search Bar -->
                <div class="filter-row" style="margin-bottom: 1rem;">
                    <div class="filter-group" style="flex: 1; max-width: 100%;">
                        <label class="filter-label"><?= t('library.search_tracks') ?></label>
                        <input type="text" 
                               name="search" 
                               id="trackSearch" 
                               class="filter-select" 
                               placeholder="<?= t('library.search_placeholder') ?>" 
                               value="<?= htmlspecialchars($_GET['search'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
                               style="width: 100%; padding: 0.75rem 1rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; color: white; font-size: 0.95rem;">
                    </div>
                </div>
                
                <div class="filter-row">
                    <div class="filter-group">
                        <label class="filter-label"><?= t('library.status') ?></label>
                        <select name="status" class="filter-select">
                            <option value="all" <?= $status_filter === 'all' ? 'selected' : '' ?>><?= t('library.all_tracks') ?></option>
                            <option value="complete" <?= $status_filter === 'complete' ? 'selected' : '' ?>><?= t('library.completed_tracks') ?></option>
                            <option value="processing" <?= $status_filter === 'processing' ? 'selected' : '' ?>><?= t('library.processing_tracks') ?></option>
                            <option value="failed" <?= $status_filter === 'failed' ? 'selected' : '' ?>><?= t('library.failed_tracks') ?></option>
                        </select>
                    </div>
                    
                    <div class="filter-group">
                        <label class="filter-label"><?= t('library.sort_by') ?></label>
                        <select name="sort" class="filter-select">
                            <option value="latest" <?= $sort_filter === 'latest' ? 'selected' : '' ?>><?= t('library.latest_first') ?></option>
                            <option value="oldest" <?= $sort_filter === 'oldest' ? 'selected' : '' ?>><?= t('library.oldest_first') ?></option>
                            <option value="popular" <?= $sort_filter === 'popular' ? 'selected' : '' ?>><?= t('library.most_popular') ?></option>
                            <option value="most-played" <?= $sort_filter === 'most-played' ? 'selected' : '' ?>><?= t('library.most_played') ?></option>
                        </select>
                    </div>
                    
                    <div class="filter-group">
                        <label class="filter-label"><?= t('library.time') ?></label>
                        <select name="time" class="filter-select">
                            <option value="all" <?= $time_filter === 'all' ? 'selected' : '' ?>><?= t('library.all_time') ?></option>
                            <option value="today" <?= $time_filter === 'today' ? 'selected' : '' ?>><?= t('library.today') ?></option>
                            <option value="week" <?= $time_filter === 'week' ? 'selected' : '' ?>><?= t('library.this_week') ?></option>
                            <option value="month" <?= $time_filter === 'month' ? 'selected' : '' ?>><?= t('library.this_month') ?></option>
                        </select>
                    </div>
                    
                    <div class="filter-group">
                        <label class="filter-label"><?= t('library.genre') ?></label>
                        <select name="genre" class="filter-select">
                            <option value=""><?= t('library.all_genres') ?> (<?= count($available_genres) ?>)</option>
                            <?php foreach ($available_genres as $genre): ?>
                                <option value="<?= htmlspecialchars($genre, ENT_QUOTES, 'UTF-8') ?>" <?= $genre_filter === $genre ? 'selected' : '' ?>>
                                    <?= htmlspecialchars($genre, ENT_QUOTES, 'UTF-8') ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                </div>
            </div>
            
            <!-- Analysis Status & Batch Actions -->
            <?php
            // Count tracks needing analysis for current user
            $pdo = getDBConnection();
            $analysisStmt = $pdo->prepare("
                SELECT COUNT(*) as needing_analysis
                FROM music_tracks
                WHERE user_id = ?
                AND status = 'complete'
                AND audio_url IS NOT NULL
                AND audio_url != ''
                AND (
                    JSON_EXTRACT(metadata, '$.bpm') IS NULL
                    OR JSON_EXTRACT(metadata, '$.bpm') = ''
                    OR JSON_EXTRACT(metadata, '$.analysis_source') IS NULL
                    OR JSON_EXTRACT(metadata, '$.analysis_source') = ''
                )
            ");
            $analysisStmt->execute([$_SESSION['user_id']]);
            $analysisStats = $analysisStmt->fetch(PDO::FETCH_ASSOC);
            $needingAnalysis = (int)$analysisStats['needing_analysis'];
            ?>
            <?php if ($needingAnalysis > 0): ?>
            <div style="background: rgba(251, 191, 36, 0.1); border: 1px solid rgba(251, 191, 36, 0.3); border-radius: 12px; padding: 1.5rem; margin-bottom: 2rem; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;">
                <div>
                    <h3 style="color: #fbbf24; margin: 0 0 0.5rem 0; font-size: 1.2rem;">
                        <i class="fas fa-exclamation-triangle"></i> Analysis Needed
                    </h3>
                    <p style="color: rgba(255, 255, 255, 0.8); margin: 0; font-size: 0.95rem;">
                        <?= $needingAnalysis ?> track<?= $needingAnalysis !== 1 ? 's' : '' ?> need<?= $needingAnalysis === 1 ? 's' : '' ?> BPM and key analysis
                    </p>
                </div>
                <button onclick="batchAnalyzeTracks()" class="btn-batch-analyze" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 8px; font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; transition: all 0.3s ease;">
                    <i class="fas fa-magic"></i> Analyze All Tracks
                </button>
            </div>
            <?php endif; ?>
            
            <!-- Tracks Grid -->
            <div class="tracks-grid">
                <?php if (empty($recent_tracks)): ?>
                    <div style="grid-column: 1 / -1; text-align: center; padding: 4rem;">
                        <h3><?= t('library.no_tracks_found') ?></h3>
                        <p><?= t('library.no_tracks_desc') ?></p>
                    </div>
                <?php else: ?>
                    <!-- Library Tracks Grid -->
                    <div class="tracks-grid">
                        <?php if (empty($tracks_with_variations)): ?>
                            <div class="empty-state">
                                <div class="empty-icon">🎵</div>
                                <?php if ($status_filter === 'processing'): ?>
                                    <h2 class="empty-title"><?= t('library.no_processing') ?></h2>
                                    <p class="empty-description">
                                        <?= t('library.no_processing_desc') ?>
                                    </p>
                                    <a href="?status=all" class="create-first-btn">
                                        <i class="fas fa-list"></i>
                                        <?= t('library.view_all_tracks') ?>
                                    </a>
                                <?php elseif ($status_filter === 'failed'): ?>
                                    <h2 class="empty-title"><?= t('library.no_failed') ?></h2>
                                    <p class="empty-description">
                                        <?= t('library.no_failed_desc') ?>
                                    </p>
                                    <a href="?status=all" class="create-first-btn">
                                        <i class="fas fa-list"></i>
                                        <?= t('library.view_all_tracks') ?>
                                    </a>
                                <?php elseif ($status_filter === 'complete'): ?>
                                    <h2 class="empty-title"><?= t('library.no_completed') ?></h2>
                                    <p class="empty-description">
                                        <?= t('library.no_completed_desc') ?>
                                    </p>
                                    <a href="/#create" class="create-first-btn">
                                        <i class="fas fa-plus"></i>
                                        <?= t('library.create_first_track') ?>
                                    </a>
                                <?php else: ?>
                                <h2 class="empty-title"><?= t('library.no_tracks_yet') ?></h2>
                                <p class="empty-description">
                                    <?= t('library.no_tracks_yet_desc') ?>
                                </p>
                                <a href="/#create" class="create-first-btn">
                                    <i class="fas fa-plus"></i>
                                    <?= t('library.create_first_track') ?>
                                </a>
                                <?php endif; ?>
                            </div>
                        <?php else: ?>
                            <?php 
                            // Group tracks by month for better organization
                            $tracks_by_month = [];
                            foreach ($tracks_with_variations as $track) {
                                $month_key = date('Y-m', strtotime($track['created_at']));
                                if (!isset($tracks_by_month[$month_key])) {
                                    $tracks_by_month[$month_key] = [];
                                }
                                $tracks_by_month[$month_key][] = $track;
                            }
                            
                            // Count total tracks first to get the correct numbering
                            $total_tracks = count($tracks_with_variations);
                            $track_number = $total_tracks; // Start from the oldest track (highest number)
                            
                            // Iterate through months
                            foreach ($tracks_by_month as $month_key => $month_tracks):
                                $month_date = DateTime::createFromFormat('Y-m', $month_key);
                                $month_display = $month_date ? $month_date->format('F Y') : $month_key;
                                $track_count = count($month_tracks);
                            ?>
                            <div class="month-group">
                                <div class="month-header" onclick="toggleMonthGroup(this)">
                                    <div class="month-header-left">
                                        <span class="month-icon">📅</span>
                                        <span class="month-title"><?= htmlspecialchars($month_display, ENT_QUOTES, 'UTF-8') ?></span>
                                        <span class="month-count">(<?= $track_count ?> <?= $track_count === 1 ? 'track' : 'tracks' ?>)</span>
                                    </div>
                                    <div class="month-toggle">
                                        <i class="fas fa-chevron-down"></i>
                                    </div>
                                </div>
                                <div class="month-tracks">
                            <?php foreach ($month_tracks as $track): 
                                $displayTitle = $track['title'] ?: 'Untitled Track';
                                
                                // Get selected variation index from metadata first (needed for duration calculation)
                                $trackMetadataForDuration = json_decode($track['metadata'] ?? '{}', true) ?: [];
                                $selectedVariationIndexForDuration = $trackMetadataForDuration['selected_variation'] ?? $track['selected_variation_index'] ?? 0;
                                
                                // Get the selected variation to use its duration if available
                                $selectedVariationForDuration = null;
                                if (!empty($track['variations']) && is_array($track['variations'])) {
                                    foreach ($track['variations'] as $variation) {
                                        if (isset($variation['variation_index']) && $variation['variation_index'] == $selectedVariationIndexForDuration) {
                                            $selectedVariationForDuration = $variation;
                                            break;
                                        }
                                    }
                                    if (!$selectedVariationForDuration && isset($track['variations'][$selectedVariationIndexForDuration])) {
                                        $selectedVariationForDuration = $track['variations'][$selectedVariationIndexForDuration];
                                    }
                                }
                                
                                // Use selected variation's duration if available, otherwise use track's duration
                                $duration_seconds = $track['duration'] ?? 0;
                                if ($selectedVariationForDuration && !empty($selectedVariationForDuration['duration'])) {
                                    $duration_seconds = $selectedVariationForDuration['duration'];
                                }
                                
                                // Format duration as mm:ss
                                $duration_minutes = floor($duration_seconds / 60);
                                $duration_secs = $duration_seconds % 60;
                                $duration = sprintf('%d:%02d', $duration_minutes, $duration_secs);
                                $created_date = date('M j, Y', strtotime($track['created_at']));
                                
                                // Parse metadata - only use actual values, no defaults
                                    $metadata = json_decode($track['metadata'] ?? '{}', true) ?: [];
                                    
                                // Extract error message from metadata if track is failed
                                $error_message = null;
                                if ($track['status'] === 'failed' && !empty($metadata)) {
                                    // Try multiple locations for error message
                                    $raw_message = $metadata['msg'] ?? 
                                                   $metadata['error'] ?? 
                                                   $metadata['error_msg'] ?? 
                                                   $metadata['message'] ?? 
                                                   null;
                                    
                                    // Format error message for better display
                                    if ($raw_message) {
                                        // ONLY remove API.Box references - keep the exact error message
                                        $raw_message = preg_replace('/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/i', '', $raw_message);
                                        $raw_message = trim($raw_message);
                                        
                                        // Clean up multiple spaces that might result from removal
                                        $raw_message = preg_replace('/\s+/', ' ', $raw_message);
                                        
                                        // Check if this is actually a success message (not an error)
                                        $is_success_message = preg_match('/\b(successfully|success|complete|done|ready|finished)\b/i', $raw_message);
                                        
                                        // Only treat as error if it's NOT a success message
                                        if (!$is_success_message && !empty($raw_message)) {
                                            $error_message = $raw_message;
                                        }
                                        // If it's a success message, leave $error_message as null (don't show anything)
                                    }
                                    
                                    // If no error message found and we have a failed track, use default
                                    // But only if we didn't find a success message (which would leave $error_message as null)
                                    if ($error_message === null && empty($raw_message ?? null)) {
                                        $error_message = "Track generation failed. Please try again.";
                                    }
                                }
                                    $genre = $metadata['genre'] ?? null;
                                    
                                    // BPM: Use analyzed value if available, otherwise fallback to default
                                    // SINGLE SOURCE OF TRUTH: Read from main fields only
                                    $hasAnalyzedBPM = isset($metadata['bpm']) && isset($metadata['analysis_source']);
                                    $rawBpm = $metadata['bpm'] ?? null;
                                    
                                    // CLEAN: Only normalize clearly wrong values (188 -> 94), preserve valid BPMs
                                    $bpm = $rawBpm;
                                    if ($bpm) {
                                        // 188 is a common error (94*2) - fix it specifically
                                        if (abs($bpm - 188) < 2) {
                                            $bpm = 94;
                                        }
                                        // Values > 200: Almost always wrong
                                        elseif ($bpm > 200) {
                                            $maxIterations = 10;
                                            $iterations = 0;
                                            while ($bpm > 200 && $iterations < $maxIterations) {
                                                $bpm = $bpm / 2;
                                                $iterations++;
                                            }
                                            if ($bpm > 200) $bpm = 200; // Final clamp
                                        }
                                        // Values < 50: Very low, likely wrong
                                        elseif ($bpm < 50 && $bpm > 0) {
                                            $doubled = $bpm * 2;
                                            if ($doubled <= 200) {
                                                $bpm = $doubled;
                                            }
                                        }
                                        // Otherwise keep the original (60-200 is valid)
                                    }
                                    
                                    // KEY: Use analyzed value if available (same priority as track.php)
                                    // SINGLE SOURCE OF TRUTH: Read from main fields only
                                    $hasAnalyzedKey = isset($metadata['key']) && isset($metadata['analysis_source']);
                                    $key = $metadata['key'] ?? null;
                                    
                                    // CAMELOT/NUMERICAL KEY: Read from main field
                                    $numericalKey = $metadata['numerical_key'] ?? '';
                                    
                                    $mood = $metadata['mood'] ?? null;
                                
                                // Only try to extract from prompt if we don't have analyzed data
                                if (empty($numericalKey) && !isset($metadata['analyzed_camelot']) && !empty($track['prompt'])) {
                                    // Try to extract from prompt if not in metadata
                                    if (preg_match('/key[:\s]+([0-9]+[A-G]?)\s*[–\-]?\s*/i', $track['prompt'], $keyMatches)) {
                                        $numericalKey = trim($keyMatches[1]);
                                    }
                                }
                            ?>
                                <?php 
                                // Get selected variation index from metadata
                                $trackMetadataForAttr = json_decode($track['metadata'] ?? '{}', true) ?: [];
                                $selectedVariationIndexForAttr = $trackMetadataForAttr['selected_variation'] ?? $track['selected_variation_index'] ?? 0;
                                
                                // Handle track image - same logic as community_fixed.php
                                $imageUrl = $track['image_url'] ?? null;
                                
                                // Reject external URLs
                                if (!empty($imageUrl) && (strpos($imageUrl, 'http://') === 0 || strpos($imageUrl, 'https://') === 0)) {
                                    $imageUrl = null;
                                }
                                
                                // Normalize image URL format
                                if ($imageUrl && !preg_match('/^https?:\/\//', $imageUrl)) {
                                    if (!str_starts_with($imageUrl, '/')) {
                                        $imageUrl = '/' . ltrim($imageUrl, '/');
                                    }
                                }
                                
                                // If still empty, try metadata
                                if (empty($imageUrl) || $imageUrl === 'null' || $imageUrl === 'NULL') {
                                    if (!empty($track['metadata'])) {
                                        $metadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
                                        if (isset($metadata['image_url']) && !empty($metadata['image_url'])) {
                                            $metaImageUrl = $metadata['image_url'];
                                            if (strpos($metaImageUrl, 'http://') !== 0 && strpos($metaImageUrl, 'https://') !== 0) {
                                                if (!str_starts_with($metaImageUrl, '/')) {
                                                    $metaImageUrl = '/' . ltrim($metaImageUrl, '/');
                                                }
                                                $imageUrl = $metaImageUrl;
                                            }
                                        } elseif (isset($metadata['cover_url']) && !empty($metadata['cover_url'])) {
                                            $metaCoverUrl = $metadata['cover_url'];
                                            if (strpos($metaCoverUrl, 'http://') !== 0 && strpos($metaCoverUrl, 'https://') !== 0) {
                                                if (!str_starts_with($metaCoverUrl, '/')) {
                                                    $metaCoverUrl = '/' . ltrim($metaCoverUrl, '/');
                                                }
                                                $imageUrl = $metaCoverUrl;
                                            }
                                        }
                                    }
                                    
                                    // Try to find image file by task_id pattern
                                    if (empty($imageUrl) && !empty($track['task_id'])) {
                                        $uploadsDir = $_SERVER['DOCUMENT_ROOT'] . '/uploads/track_covers/';
                                        if (is_dir($uploadsDir)) {
                                            $pattern = $uploadsDir . "track_{$track['task_id']}_*";
                                            $files = glob($pattern);
                                            if (!empty($files)) {
                                                $mostRecent = end($files);
                                                $imageUrl = '/uploads/track_covers/' . basename($mostRecent);
                                            }
                                        }
                                    }
                                    
                                    // Fallback to default
                                    if (empty($imageUrl)) {
                                        $imageUrl = '/assets/images/default-track.jpg';
                                    }
                                }
                                ?>
                                <div class="track-card-modern" data-track-id="<?= $track['id'] ?>" data-status="<?= $track['status'] ?>" data-variations="<?= htmlspecialchars(json_encode($track['variations'] ?? []), ENT_QUOTES, 'UTF-8') ?>" data-selected-variation="<?= $selectedVariationIndexForAttr ?>" data-prompt="<?= htmlspecialchars($track['prompt'] ?? '', ENT_QUOTES, 'UTF-8') ?>" data-created-at="<?= htmlspecialchars($track['created_at'], ENT_QUOTES, 'UTF-8') ?>">
                                    <!-- Status Badge (Top Right) -->
                                    <?php if ($track['is_public'] ?? 0): ?>
                                        <div class="track-status-badge"><?= t('library.card.public') ?></div>
                                    <?php else: ?>
                                        <div class="track-status-badge private"><?= t('library.card.private') ?></div>
                                            <?php endif; ?>
                                            
                                    <!-- Track Content -->
                                    <div class="track-card-content">
                                        <!-- Track Image/Icon & Info -->
                                        <div class="track-main-info">
                                            <!-- Track Image or Icon -->
                                            <?php if ($imageUrl && $imageUrl !== '/assets/images/default-track.jpg'): ?>
                                                <div class="track-image-container" data-track-id="<?= $track['id'] ?>" data-user-id="<?= $track['user_id'] ?>" data-image-url="<?= htmlspecialchars($imageUrl, ENT_QUOTES, 'UTF-8') ?>">
                                                    <img src="<?= htmlspecialchars($imageUrl, ENT_QUOTES, 'UTF-8') ?>" alt="<?= htmlspecialchars($displayTitle, ENT_QUOTES, 'UTF-8') ?>" class="track-image" loading="lazy">
                                                    <?php if ($track['user_id'] == $_SESSION['user_id']): ?>
                                                        <div class="track-image-upload-overlay">
                                                            <button type="button" class="track-image-action-button track-image-download-btn" data-image-url="<?= htmlspecialchars($imageUrl, ENT_QUOTES, 'UTF-8') ?>" data-track-title="<?= htmlspecialchars($displayTitle, ENT_QUOTES, 'UTF-8') ?>" title="<?= htmlspecialchars(t('library.image.download'), ENT_QUOTES, 'UTF-8') ?>">
                                                                <i class="fas fa-download track-image-download-icon"></i>
                                                            </button>
                                                            <label class="track-image-action-button" for="track-image-upload-<?= $track['id'] ?>" title="<?= htmlspecialchars(t('library.image.upload'), ENT_QUOTES, 'UTF-8') ?>">
                                                                <i class="fas fa-camera track-image-upload-icon"></i>
                                                                <input type="file" id="track-image-upload-<?= $track['id'] ?>" class="track-image-upload-input" accept="image/jpeg,image/jpg,image/png,image/gif,image/webp" data-track-id="<?= $track['id'] ?>">
                                                            </label>
                                                        </div>
                                                    <?php endif; ?>
                                                </div>
                                            <?php else: ?>
                                                <div class="track-icon" data-track-id="<?= $track['id'] ?>" data-user-id="<?= $track['user_id'] ?>">
                                                    <i class="fas fa-music"></i>
                                                    <?php if ($track['user_id'] == $_SESSION['user_id']): ?>
                                                        <div class="track-image-upload-overlay">
                                                            <label class="track-image-action-button" for="track-image-upload-icon-<?= $track['id'] ?>" title="<?= htmlspecialchars(t('library.image.upload'), ENT_QUOTES, 'UTF-8') ?>">
                                                                <i class="fas fa-camera track-image-upload-icon"></i>
                                                                <input type="file" id="track-image-upload-icon-<?= $track['id'] ?>" class="track-image-upload-input" accept="image/jpeg,image/jpg,image/png,image/gif,image/webp" data-track-id="<?= $track['id'] ?>">
                                                            </label>
                                                        </div>
                                                    <?php endif; ?>
                                                </div>
                                            <?php endif; ?>
                                            
                                            <!-- Track Details -->
                                            <div class="track-details">
                                                <h3 class="track-name"><a href="/track.php?id=<?= $track['id'] ?>" class="track-title-link" target="_blank" rel="noopener noreferrer"><?= htmlspecialchars($displayTitle, ENT_QUOTES, 'UTF-8') ?></a></h3>
                                                <p class="track-artist-name"><?= t('library.card.by') ?> <a href="/artist_profile.php?id=<?= $track['user_id'] ?>" class="artist-name-link"><?= htmlspecialchars($user_name, ENT_QUOTES, 'UTF-8') ?></a></p>
                                                <?php if ($track['prompt']): ?>
                                                    <p class="track-description" title="<?= htmlspecialchars($track['prompt'], ENT_QUOTES, 'UTF-8') ?>">
                                                        <strong><?= t('library.card.original_prompt') ?></strong> <?= htmlspecialchars($track['prompt'], ENT_QUOTES, 'UTF-8') ?>
                                                    </p>
                                                <?php elseif ($track['description']): ?>
                                                    <p class="track-description"><?= htmlspecialchars($track['description'], ENT_QUOTES, 'UTF-8') ?></p>
                                            <?php endif; ?>
                                            
                                                <!-- Metadata Row - Only show values that exist in metadata -->
                                                <div class="track-metadata-row">
                                                    <?php if (!empty($duration)): ?>
                                                        <span class="meta-item"><strong><?= t('library.card.duration') ?></strong> <?= $duration ?></span>
                                                    <?php endif; ?>
                                                    <?php if (!empty($bpm)): ?>
                                                        <span class="meta-item" id="bpm-meta-<?= $track['id'] ?>">
                                                            <strong><?= t('library.card.bpm') ?></strong> <span class="bpm-value-display"><?= $bpm ?></span> BPM
                                                            <?php if ($hasAnalyzedBPM): ?>
                                                                <i class="fas fa-check-circle" style="color: #4ade80; margin-left: 4px;" title="Analyzed"></i>
                                                            <?php else: ?>
                                                                <i class="fas fa-exclamation-circle" style="color: #fbbf24; margin-left: 4px;" title="Needs Analysis"></i>
                                                            <?php endif; ?>
                                                            <?php if ($track['user_id'] == $_SESSION['user_id'] && $bpm): ?>
                                                                <button class="bpm-edit-btn" onclick="openBPMCorrectionModal(<?= $track['id'] ?>, <?= $bpm ?>)" title="Edit BPM" style="background: none; border: none; color: #667eea; cursor: pointer; margin-left: 4px; padding: 2px 4px;">
                                                                    <i class="fas fa-edit" style="font-size: 0.75rem;"></i>
                                                                </button>
                                                            <?php endif; ?>
                                                        </span>
                                                    <?php elseif ($track['status'] === 'complete' && $track['user_id'] == $_SESSION['user_id']): ?>
                                                        <span class="meta-item" style="color: #fbbf24;" id="bpm-meta-<?= $track['id'] ?>">
                                                            <strong>BPM:</strong> <span class="bpm-value-display" style="font-style: italic;">Not analyzed</span>
                                                            <i class="fas fa-exclamation-circle" style="margin-left: 4px;" title="Needs Analysis"></i>
                                                            <button class="analyze-inline-btn" onclick="analyzeSingleTrack(<?= $track['id'] ?>, '<?= htmlspecialchars($displayTitle, ENT_QUOTES) ?>')" title="Analyze BPM & Key" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.75rem; cursor: pointer; margin-left: 8px; display: inline-flex; align-items: center; gap: 4px;">
                                                                <i class="fas fa-search"></i> Analyze
                                                            </button>
                                                        </span>
                                                    <?php endif; ?>
                                                    <?php if (!empty($genre)): ?>
                                                        <span class="meta-item"><strong><?= t('library.card.genre') ?></strong> <?= htmlspecialchars($genre, ENT_QUOTES, 'UTF-8') ?></span>
                                                    <?php endif; ?>
                                                    <?php if (!empty($mood)): ?>
                                                        <span class="meta-item"><strong><?= t('library.card.mood') ?></strong> <?= htmlspecialchars($mood, ENT_QUOTES, 'UTF-8') ?></span>
                                                    <?php endif; ?>
                                                    <?php if (!empty($key)): ?>
                                                        <span class="meta-item" id="key-meta-<?= $track['id'] ?>">
                                                            <strong><?= !empty($numericalKey) ? t('library.card.musical_key') : t('library.card.key') ?></strong> 
                                                            <span class="key-value-display"><?= htmlspecialchars($key, ENT_QUOTES, 'UTF-8') ?></span>
                                                            <?php if (!empty($numericalKey)): ?>
                                                                <span class="camelot-value-display">(<?= htmlspecialchars($numericalKey, ENT_QUOTES, 'UTF-8') ?>)</span>
                                                            <?php endif; ?>
                                                            <?php if ($hasAnalyzedKey): ?>
                                                                <i class="fas fa-check-circle" style="color: #4ade80; margin-left: 4px;" title="Analyzed"></i>
                                                            <?php else: ?>
                                                                <i class="fas fa-exclamation-circle" style="color: #fbbf24; margin-left: 4px;" title="Needs Analysis"></i>
                                                            <?php endif; ?>
                                                            <?php if ($track['user_id'] == $_SESSION['user_id'] && $key): ?>
                                                                <button class="key-edit-btn" onclick="openKeyCorrectionModal(<?= $track['id'] ?>, '<?= htmlspecialchars($key, ENT_QUOTES) ?>', '<?= htmlspecialchars($numericalKey ?? '', ENT_QUOTES) ?>')" title="Edit Key" style="background: none; border: none; color: #667eea; cursor: pointer; margin-left: 4px; padding: 2px 4px;">
                                                                    <i class="fas fa-edit" style="font-size: 0.75rem;"></i>
                                                                </button>
                                                            <?php endif; ?>
                                                        </span>
                                                    <?php elseif ($track['status'] === 'complete' && $track['user_id'] == $_SESSION['user_id']): ?>
                                                        <span class="meta-item" style="color: #fbbf24;" id="key-meta-<?= $track['id'] ?>">
                                                            <strong>Key:</strong> <span class="key-value-display" style="font-style: italic;">Not analyzed</span>
                                                            <i class="fas fa-exclamation-circle" style="margin-left: 4px;" title="Needs Analysis"></i>
                                                            <?php if (empty($bpm)): ?>
                                                                <button class="analyze-inline-btn" onclick="analyzeSingleTrack(<?= $track['id'] ?>, '<?= htmlspecialchars($displayTitle, ENT_QUOTES) ?>')" title="Analyze BPM & Key" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.75rem; cursor: pointer; margin-left: 8px; display: inline-flex; align-items: center; gap: 4px;">
                                                                    <i class="fas fa-search"></i> Analyze
                                                                </button>
                                                            <?php endif; ?>
                                                        </span>
                                                    <?php endif; ?>
                                            </div>
                                            </div>
                                            </div>
                                        
                                        <!-- Action Buttons -->
                                        <div class="track-actions-row">
                                    <?php if ($track['status'] === 'complete'): ?>
                                    <?php 
                                    // Get the selected variation if it exists
                                    $selectedVariation = null;
                                    
                                    // Extract selected_variation_index from metadata (stored as 'selected_variation' in metadata JSON)
                                    $trackMetadata = json_decode($track['metadata'] ?? '{}', true) ?: [];
                                    $selectedVariationIndex = $trackMetadata['selected_variation'] ?? $track['selected_variation_index'] ?? 0;
                                    
                                    // Get the selected variation from the variations array
                                    if (!empty($track['variations']) && is_array($track['variations'])) {
                                        // Find variation by variation_index (not array index)
                                        foreach ($track['variations'] as $variation) {
                                            if (isset($variation['variation_index']) && $variation['variation_index'] == $selectedVariationIndex) {
                                                $selectedVariation = $variation;
                                                break;
                                            }
                                        }
                                        // Fallback: use array index if variation_index doesn't match
                                        if (!$selectedVariation && isset($track['variations'][$selectedVariationIndex])) {
                                            $selectedVariation = $track['variations'][$selectedVariationIndex];
                                        }
                                    }
                                    
                                    // Use selected variation's audio URL if available, otherwise use track's audio URL
                                    $audioUrl = $track['audio_url'];
                                    if ($selectedVariation && !empty($selectedVariation['audio_url'])) {
                                        $audioUrl = $selectedVariation['audio_url'];
                                    }
                                    
                                    // Ensure audio URL is not empty
                                    if (empty($audioUrl)) {
                                        $audioUrl = $track['audio_url'] ?? '';
                                    }
                                    // Use signed proxy URL to protect direct audio file paths
                                    // CRITICAL: Pass user_id and session_id for token binding (new protection)
                                    $user_id = $_SESSION['user_id'] ?? null;
                                    $session_id = session_id();
                                    $proxyAudioUrl = getSignedAudioUrl($track['id'], null, null, $user_id, $session_id);
                                                ?>
                                                <button class="play-btn-large" onclick="playTrackFromButton('<?= htmlspecialchars($proxyAudioUrl) ?>', '<?= htmlspecialchars($displayTitle) ?>', '<?= htmlspecialchars($user_name) ?>')" 
                                                        data-audio-url="<?= htmlspecialchars($proxyAudioUrl) ?>" 
                                                        data-title="<?= htmlspecialchars($displayTitle) ?>" 
                                                        data-artist="<?= htmlspecialchars($user_name) ?>"
                                                        data-track-id="<?= $track['id'] ?>"
                                                        title="<?= t('library.card.play_track') ?>">
                                                    <i class="fas fa-play"></i>
                                                </button>
                                                
                                                <?php if ($track['variation_count'] > 0): ?>
                                                    <button class="action-icon-btn" onclick="showVariations(<?= $track['id'] ?>)" title="<?= t('library.card.view_variations') ?> (<?= $track['variation_count'] ?>)">
                                                        <i class="fas fa-layer-group"></i>
                                                    </button>
                                                <?php endif; ?>
                                                
                                                <button class="action-icon-btn" onclick="shareTrack(<?= $track['id'] ?>)" title="<?= t('library.card.share') ?>">
                                                    <i class="fas fa-share-alt"></i>
                                                    </button>
                                                
                                                <button class="action-icon-btn" onclick="showAddToCrateModal(<?= $track['id'] ?>)" title="Add to Crate">
                                                    <i class="fas fa-folder-plus"></i>
                                                </button>
                                                
                                                <?php 
                                                // Check if user is admin (master upload is admin-only)
                                                $isAdmin = isset($_SESSION['is_admin']) && $_SESSION['is_admin'];
                                                
                                                if ($isAdmin): ?>
                                                    <!-- Upload Mastered Version Button (Admin only) -->
                                                    <label class="action-icon-btn" for="mastered-upload-<?= $track['id'] ?>" title="Upload Mastered Version (Admin only - MP3)">
                                                        <i class="fas fa-upload"></i>
                                                        <input type="file" id="mastered-upload-<?= $track['id'] ?>" class="mastered-upload-input" accept="audio/mpeg,audio/mp3,.mp3" data-track-id="<?= $track['id'] ?>" style="display: none;">
                                                    </label>
                                                <?php endif; ?>
                                                
                                                <button class="action-icon-btn <?= (isset($track['user_liked']) && (int)$track['user_liked'] > 0) ? 'liked' : '' ?>" 
                                                        data-liked="<?= (isset($track['user_liked']) && (int)$track['user_liked'] > 0) ? '1' : '0' ?>"
                                                        onclick="toggleLike(<?= $track['id'] ?>, this)" title="<?= t('library.card.like') ?>">
                                                    <i class="fas fa-heart"></i>
                                                </button>
                                                
                                                <?php
                                                // Check if this track has stems (check metadata regardless of music_type)
                                                // Stems can exist for any track type if stem separation was performed
                                                $hasStems = false;
                                                $stemCount = 0;
                                                $trackMetadata = json_decode($track['metadata'] ?? '{}', true) ?: [];
                                                
                                                // Check for stem_files array in metadata (stored by callback.php)
                                                $stemFiles = $trackMetadata['stem_files'] ?? [];
                                                if (empty($stemFiles)) {
                                                    // Fallback: check for stems array (legacy format)
                                                    $stems = $trackMetadata['stems'] ?? [];
                                                    $stemFiles = $stems;
                                                }
                                                
                                                // Also check stem_count if available
                                                if (empty($stemFiles) && isset($trackMetadata['stem_count']) && $trackMetadata['stem_count'] > 0) {
                                                    // Track has stem_count but no stem_files array - might be processing
                                                    $stemCount = (int)$trackMetadata['stem_count'];
                                                }
                                                
                                                if (!empty($stemFiles) && is_array($stemFiles)) {
                                                    $hasStems = true;
                                                    $stemCount = count($stemFiles);
                                                }
                                                ?>
                                                
                                                <?php if ($hasStems && $stemCount > 0): ?>
                                                    <button class="action-icon-btn" onclick="showStemsModal(<?= $track['id'] ?>)" title="View Stems (<?= $stemCount ?> stems)">
                                                        <i class="fas fa-layer-group"></i>
                                                    </button>
                                                <?php elseif ($track['status'] === 'complete'): ?>
                                                    <!-- Only show stem separation button for complete tracks -->
                                                    <button class="action-icon-btn" onclick="openStemSeparationForTrack(<?= $track['id'] ?>)" title="Separate into Stems">
                                                        <i class="fas fa-cut"></i>
                                                    </button>
                                                <?php endif; ?>
                                                
                                                <?php if ($track['user_id'] == $_SESSION['user_id'] && $track['status'] === 'complete' && (empty($bpm) || empty($key) || !$hasAnalyzedBPM || !$hasAnalyzedKey)): ?>
                                                    <button class="action-icon-btn" onclick="analyzeSingleTrack(<?= $track['id'] ?>, '<?= htmlspecialchars($displayTitle, ENT_QUOTES) ?>')" title="Analyze BPM & Key">
                                                        <i class="fas fa-search"></i>
                                                    </button>
                                                <?php endif; ?>
                                                
                                                <button class="action-icon-btn edit-track-btn" 
                                                        data-track-id="<?= $track['id'] ?>"
                                                        data-track-title="<?= htmlspecialchars($displayTitle, ENT_QUOTES) ?>"
                                                        data-track-prompt="<?= htmlspecialchars($track['prompt'] ?? '', ENT_QUOTES) ?>"
                                                        data-track-price="<?= $track['price'] ?? 0 ?>"
                                                        data-track-public="<?= $track['is_public'] ?? 0 ?>"
                                                        title="<?= t('library.card.edit_track') ?>">
                                                    <i class="fas fa-edit"></i>
                                                </button>
                                            <?php elseif ($track['status'] === 'processing' || !empty($track['_was_failed_but_checking'])): ?>
                                                <div class="processing-indicator-modern">
                                                    <div class="processing-spinner">
                                                        <i class="fas fa-spinner fa-spin"></i>
                                                    </div>
                                                    <div class="processing-text">
                                                        <span class="processing-main"><?= t('library.card.processing') ?></span>
                                                        <span class="processing-subtitle"><?= !empty($track['_was_failed_but_checking']) ? 'Verifying status...' : t('library.card.processing_subtitle') ?></span>
                                                    </div>
                                                </div>
                                            <?php elseif ($track['status'] === 'failed'): ?>
                                                <?php
                                                // DOUBLE CHECK: Verify this track is actually failed, not still processing
                                                // If it has a valid task_id and is recent, don't show Retry/Delete
                                                $task_id = $track['task_id'] ?? $track['api_task_id'] ?? null;
                                                $created_at = strtotime($track['created_at']);
                                                $hours_old = (time() - $created_at) / 3600;
                                                $might_still_be_processing = false;
                                                
                                                if ($task_id && 
                                                    $task_id !== 'unknown' && 
                                                    !str_starts_with($task_id, 'temp_') && 
                                                    !str_starts_with($task_id, 'retry_') &&
                                                    $hours_old < 2) {
                                                    $might_still_be_processing = true;
                                                }
                                                ?>
                                                
                                                <?php if ($might_still_be_processing): ?>
                                                    <!-- Still might be processing - show Check Status only -->
                                                    <div class="processing-actions" style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
                                                        <button class="action-btn secondary" onclick="checkTrackStatus(<?= $track['id'] ?>)" title="Check Status - Track may still be processing" style="padding: 0.5rem 1rem; background: #6b7280; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                                                            <i class="fas fa-sync-alt"></i>
                                                            Check Status
                                                        </button>
                                                    </div>
                                                <?php else: ?>
                                                    <!-- Confirmed failed - show Retry/Delete -->
                                                    <div class="failed-actions-modern" style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
                                                        <button class="action-btn primary" onclick="retryTrack(<?= $track['id'] ?>)" title="Create a new version with the same prompt" style="padding: 0.5rem 1rem; background: #667eea; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                                                            <i class="fas fa-redo"></i>
                                                            Retry
                                                        </button>
                                                        <button class="action-btn danger" onclick="deleteFailedTrack(<?= $track['id'] ?>)" title="Delete this failed track" style="padding: 0.5rem 1rem; background: #ef4444; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                                                            <i class="fas fa-trash"></i>
                                                            Delete
                                                        </button>
                                                    </div>
                                                <?php endif; ?>
                                            <?php else: ?>
                                                <!-- Unknown status - treat as processing to be safe -->
                                                <div class="processing-actions" style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
                                                    <button class="action-btn secondary" onclick="checkTrackStatus(<?= $track['id'] ?>)" title="Check Status" style="padding: 0.5rem 1rem; background: #6b7280; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                                                        <i class="fas fa-sync-alt"></i>
                                                        Check Status
                                                    </button>
                                                </div>
                                        <?php endif; ?>
                                    </div>
                                    </div>
                                    
                                    <!-- Error Message for Failed Tracks -->
                                    <?php if ($track['status'] === 'failed' && $error_message): ?>
                                        <div class="error-message-modern">
                                            <div class="error-header">
                                                <i class="fas fa-exclamation-triangle"></i>
                                                <strong>Error Details:</strong>
                                            </div>
                                            <div class="error-content">
                                                <?= htmlspecialchars($error_message) ?>
                                            </div>
                                        </div>
                                    <?php endif; ?>
                                </div>
                                <?php $track_number--; // Decrement track number for next track (oldest to newest) ?>
                            <?php endforeach; // End tracks in month ?>
                                </div><!-- .month-tracks -->
                            </div><!-- .month-group -->
                            <?php endforeach; // End months ?>
                        <?php endif; ?>
                    </div>
                     

                <?php endif; ?>
            </div>
            
            <!-- Pagination Controls -->
            <?php if ($total_pages > 1): ?>
            <div class="pagination-container" style="margin-top: 3rem; padding: 2rem 0; border-top: 1px solid rgba(255, 255, 255, 0.1);">
                <div style="display: flex; justify-content: center; align-items: center; gap: 1rem; flex-wrap: wrap;">
                    <?php
                    // Build query string for pagination links (preserve filters)
                    $query_params = $_GET;
                    unset($query_params['page']);
                    $query_string = !empty($query_params) ? '&' . http_build_query($query_params) : '';
                    ?>
                    
                    <!-- Previous Button -->
                    <?php if ($current_page > 1): ?>
                        <a href="?page=<?= $current_page - 1 ?><?= $query_string ?>" 
                           class="pagination-btn" 
                           style="padding: 0.75rem 1.5rem; background: rgba(102, 126, 234, 0.2); border: 1px solid rgba(102, 126, 234, 0.3); border-radius: 8px; color: #fff; text-decoration: none; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 0.5rem;">
                            <i class="fas fa-chevron-left"></i> Previous
                        </a>
                    <?php else: ?>
                        <span class="pagination-btn disabled" style="padding: 0.75rem 1.5rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: rgba(255, 255, 255, 0.3); display: inline-flex; align-items: center; gap: 0.5rem; cursor: not-allowed;">
                            <i class="fas fa-chevron-left"></i> Previous
                        </span>
                    <?php endif; ?>
                    
                    <!-- Page Numbers -->
                    <div style="display: flex; gap: 0.5rem; align-items: center;">
                        <?php
                        $start_page = max(1, $current_page - 2);
                        $end_page = min($total_pages, $current_page + 2);
                        
                        // Show first page if not in range
                        if ($start_page > 1): ?>
                            <a href="?page=1<?= $query_string ?>" 
                               class="pagination-number" 
                               style="padding: 0.75rem 1rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: #fff; text-decoration: none; min-width: 2.5rem; text-align: center; transition: all 0.3s ease;">
                                1
                            </a>
                            <?php if ($start_page > 2): ?>
                                <span style="color: rgba(255, 255, 255, 0.3);">...</span>
                            <?php endif; ?>
                        <?php endif; ?>
                        
                        <?php for ($i = $start_page; $i <= $end_page; $i++): ?>
                            <?php if ($i == $current_page): ?>
                                <span class="pagination-number active" 
                                      style="padding: 0.75rem 1rem; background: linear-gradient(135deg, rgba(102, 126, 234, 0.3), rgba(118, 75, 162, 0.3)); border: 1px solid rgba(102, 126, 234, 0.5); border-radius: 8px; color: #fff; min-width: 2.5rem; text-align: center; font-weight: 600;">
                                    <?= $i ?>
                                </span>
                            <?php else: ?>
                                <a href="?page=<?= $i ?><?= $query_string ?>" 
                                   class="pagination-number" 
                                   style="padding: 0.75rem 1rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: #fff; text-decoration: none; min-width: 2.5rem; text-align: center; transition: all 0.3s ease;">
                                    <?= $i ?>
                                </a>
                            <?php endif; ?>
                        <?php endfor; ?>
                        
                        <!-- Show last page if not in range -->
                        <?php if ($end_page < $total_pages): ?>
                            <?php if ($end_page < $total_pages - 1): ?>
                                <span style="color: rgba(255, 255, 255, 0.3);">...</span>
                            <?php endif; ?>
                            <a href="?page=<?= $total_pages ?><?= $query_string ?>" 
                               class="pagination-number" 
                               style="padding: 0.75rem 1rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: #fff; text-decoration: none; min-width: 2.5rem; text-align: center; transition: all 0.3s ease;">
                                <?= $total_pages ?>
                            </a>
                        <?php endif; ?>
                    </div>
                    
                    <!-- Next Button -->
                    <?php if ($current_page < $total_pages): ?>
                        <a href="?page=<?= $current_page + 1 ?><?= $query_string ?>" 
                           class="pagination-btn" 
                           style="padding: 0.75rem 1.5rem; background: rgba(102, 126, 234, 0.2); border: 1px solid rgba(102, 126, 234, 0.3); border-radius: 8px; color: #fff; text-decoration: none; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 0.5rem;">
                            Next <i class="fas fa-chevron-right"></i>
                        </a>
                    <?php else: ?>
                        <span class="pagination-btn disabled" style="padding: 0.75rem 1.5rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px; color: rgba(255, 255, 255, 0.3); display: inline-flex; align-items: center; gap: 0.5rem; cursor: not-allowed;">
                            Next <i class="fas fa-chevron-right"></i>
                        </span>
                    <?php endif; ?>
                    
                    <!-- Page Info -->
                    <div style="margin-left: 1rem; color: rgba(255, 255, 255, 0.6); font-size: 0.9rem;">
                        Page <?= $current_page ?> of <?= $total_pages ?> 
                        <span style="color: rgba(255, 255, 255, 0.4);">(<?= number_format($total_tracks) ?> tracks total)</span>
                    </div>
                </div>
            </div>
            <?php endif; ?>
        </div>
    </section>
</div>

<script>
console.log('🎵 Community Fixed - JavaScript loading');

// Toggle month group collapse/expand
function toggleMonthGroup(header) {
    const monthTracks = header.nextElementSibling;
    const isCollapsed = header.classList.contains('collapsed');
    
    if (isCollapsed) {
        // Expand
        header.classList.remove('collapsed');
        monthTracks.classList.remove('collapsed');
        // Set max-height for smooth animation
        monthTracks.style.maxHeight = monthTracks.scrollHeight + 'px';
        setTimeout(() => {
            monthTracks.style.maxHeight = 'none';
        }, 400);
    } else {
        // Collapse
        monthTracks.style.maxHeight = monthTracks.scrollHeight + 'px';
        // Force reflow
        monthTracks.offsetHeight;
        monthTracks.style.maxHeight = '0';
        header.classList.add('collapsed');
        monthTracks.classList.add('collapsed');
    }
    
    // Save state to localStorage
    const monthKey = header.querySelector('.month-title').textContent;
    const collapsedMonths = JSON.parse(localStorage.getItem('library_collapsed_months') || '{}');
    collapsedMonths[monthKey] = !isCollapsed;
    localStorage.setItem('library_collapsed_months', JSON.stringify(collapsedMonths));
}

// Restore collapsed state on page load
document.addEventListener('DOMContentLoaded', function() {
    const collapsedMonths = JSON.parse(localStorage.getItem('library_collapsed_months') || '{}');
    document.querySelectorAll('.month-header').forEach(header => {
        const monthKey = header.querySelector('.month-title').textContent;
        if (collapsedMonths[monthKey]) {
            const monthTracks = header.nextElementSibling;
            header.classList.add('collapsed');
            monthTracks.classList.add('collapsed');
            monthTracks.style.maxHeight = '0';
        }
    });
});

// Enhanced filter function with genre support
function filterTracks() {
    const sortFilter = document.getElementById('sort-filter').value;
    const timeFilter = document.getElementById('time-filter').value;
    const genreFilter = document.getElementById('genre-filter').value;
    
    const url = new URL(window.location);
    url.searchParams.set('sort', sortFilter);
    url.searchParams.set('time', timeFilter);
    
    if (genreFilter) {
        url.searchParams.set('genre', genreFilter);
    } else {
        url.searchParams.delete('genre');
    }
    
    // Reload page with new filters
    window.location.search = url.search;
}

function filterByGenre(genre) {
    const currentUrl = new URL(window.location);
    currentUrl.searchParams.set('genre', genre);
    currentUrl.searchParams.delete('page'); // Reset to page 1 when filtering
    // Reload page with new filters
    window.location.search = currentUrl.search;
}

// Working like function with API integration (matching community_fixed.php)
function toggleLike(trackId, button) {
    console.log('❤️ Toggling like for track:', trackId);
    
    // Prevent double-clicks
    if (button.disabled) return;
    button.disabled = true;
    
    fetch('/api/toggle_like.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({track_id: trackId})
    })
    .then(r => {
        if (!r.ok) {
            throw new Error(`HTTP error! status: ${r.status}`);
        }
        return r.json();
    })
    .then(data => {
        console.log('❤️ Like API response:', data);
        if (data.success) {
            // Update button state based on API response
            if (data.liked) {
                button.classList.add('liked');
            } else {
                button.classList.remove('liked');
            }
            
            // Update like count if displayed
            const countSpan = button.querySelector('span');
            if (countSpan) {
                countSpan.textContent = data.like_count || 0;
            }
            
            console.log('❤️ Like toggled successfully. Liked:', data.liked);
        } else {
            console.error('❤️ Like failed:', data.error);
            if (typeof showNotification === 'function') {
                showNotification(data.error || 'Failed to like track', 'error');
            }
        }
        button.disabled = false;
    })
    .catch(error => {
        console.error('❤️ Like error:', error);
        if (typeof showNotification === 'function') {
            showNotification('Failed to like track. Please try again.', 'error');
        }
        button.disabled = false;
    });
}

// Share track function - now shows modal with options
function shareTrack(trackId) {
    console.log('🚀 Share button clicked for track:', trackId);
    
    if (!trackId) {
        console.error('🚀 No track ID provided');
        if (typeof showNotification === 'function') {
            showNotification('Invalid track ID', 'error');
        }
        return;
    }
    
    // Get track details from the page
    let trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) {
        // Try alternative selector - find button and get parent card
        const shareButton = document.querySelector(`[onclick*="shareTrack(${trackId})"]`);
        if (shareButton) {
            trackCard = shareButton.closest('.track-card, .library-item, [class*="track"], [class*="card"], .item');
        }
    }
    
    // Get track title and artist name from the card, or use defaults
    let trackTitle = 'Track';
    let artistName = 'Artist';
    
    if (trackCard) {
        const trackNameElement = trackCard.querySelector('.track-name, [class*="title"], h3, h4');
        if (trackNameElement) {
            trackTitle = trackNameElement.textContent?.trim() || trackNameElement.querySelector('a')?.textContent?.trim() || 'Track';
        }
        const artistNameElement = trackCard.querySelector('.track-artist-name, [class*="artist"], [class*="by"]');
        if (artistNameElement) {
            artistName = artistNameElement.textContent?.replace(/^By\s+/i, '').trim() || artistNameElement.querySelector('a')?.textContent?.trim() || 'Artist';
        }
    } else {
        console.warn('🚀 Track card not found, using default values');
    }
    
    // Check if track is public first
    fetch('/api_track_management.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'generate_share_token', 
            track_id: trackId
        })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log('Share token response:', data);
        if (data.success) {
            // Show share modal with options
            showShareOptionsModal(trackId, trackTitle, artistName, data.is_public === 1, data.share_url);
        } else {
            console.warn('Token generation failed:', data.message);
            // If token generation fails, still show modal but with limited options
            // Try to determine if track is private from the card or assume it might be
            showShareOptionsModal(trackId, trackTitle, artistName, null, null);
        }
    })
    .catch(error => {
        console.error('Error checking track status:', error);
        // Show modal anyway - assume it might be private to show warning
        showShareOptionsModal(trackId, trackTitle, artistName, null, null);
    });
}

// Show share options modal
function showShareOptionsModal(trackId, trackTitle, artistName, isPublic, shareUrl) {
    // Create or get modal
    let modal = document.getElementById('shareOptionsModal');
    if (!modal) {
        modal = document.createElement('div');
        modal.id = 'shareOptionsModal';
        modal.className = 'modal';
        document.body.appendChild(modal);
    }
    
    const isPrivate = isPublic === false;
    const shareText = `🎵 Check out "${trackTitle}" by ${artistName} on SoundStudioPro!`;
    
    modal.innerHTML = `
        <div class="modal-content">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2>${libraryTranslations.share_title}</h2>
                <button onclick="closeShareOptionsModal()" class="btn" style="background: transparent; border: none; font-size: 1.5rem; color: var(--text-primary); cursor: pointer;">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            
            ${isPrivate ? `
            <div style="background: rgba(255, 193, 7, 0.1); border: 1px solid rgba(255, 193, 7, 0.3); border-radius: 10px; padding: 1rem; margin-bottom: 1.5rem;">
                <div style="display: flex; align-items: start; gap: 0.75rem;">
                    <i class="fas fa-info-circle" style="color: #ffc107; font-size: 1.2rem; margin-top: 0.2rem;"></i>
                    <div>
                        <strong style="color: #ffc107; display: block; margin-bottom: 0.5rem;">${libraryTranslations.share_important_notice}</strong>
                        <p style="margin: 0; color: var(--text-primary); font-size: 0.9rem; line-height: 1.5;">
                            ${libraryTranslations.share_private_warning}
                        </p>
                    </div>
                </div>
            </div>
            
            <div style="margin-bottom: 1rem;">
                <label style="display: block; margin-bottom: 0.5rem; color: var(--text-primary); font-weight: 600; font-size: 0.9rem;">
                    ${libraryTranslations.share_expiration_label}
                </label>
                <select id="shareExpirationSelect" style="width: 100%; padding: 0.75rem; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; color: var(--text-primary); font-size: 0.95rem;">
                    <option value="3600">${libraryTranslations.share_expiration_1hour}</option>
                    <option value="21600">${libraryTranslations.share_expiration_6hours}</option>
                    <option value="86400">${libraryTranslations.share_expiration_24hours}</option>
                    <option value="604800">${libraryTranslations.share_expiration_7days}</option>
                    <option value="2592000">${libraryTranslations.share_expiration_30days}</option>
                </select>
            </div>
            ` : ''}
            
            <div style="display: flex; flex-direction: column; gap: 1rem;">
                <button onclick="shareWithLink(${trackId}, '${trackTitle.replace(/'/g, "\\'")}', '${artistName.replace(/'/g, "\\'")}', ${isPrivate ? 'true' : 'false'})" 
                        class="btn btn-primary" style="width: 100%; justify-content: center;">
                    <i class="fas fa-link"></i> ${libraryTranslations.share_share_with_link}
                    ${isPrivate ? '<span style="font-size: 0.8rem; opacity: 0.9; margin-left: 0.5rem;">(' + libraryTranslations.share_accessible_via_link + ')</span>' : ''}
                </button>
                
                ${isPrivate ? `
                <button onclick="makePublicAndShare(${trackId}, '${trackTitle.replace(/'/g, "\\'")}', '${artistName.replace(/'/g, "\\'")}')" 
                        class="btn" style="width: 100%; justify-content: center; background: rgba(76, 175, 80, 0.2); border: 1px solid rgba(76, 175, 80, 0.5); color: #4caf50;">
                    <i class="fas fa-globe"></i> ${libraryTranslations.share_make_public_and_share}
                </button>
                ` : ''}
                
                <button onclick="closeShareOptionsModal()" 
                        class="btn" style="width: 100%; justify-content: center; background: rgba(255, 255, 255, 0.1);">
                    ${libraryTranslations.share_cancel}
                </button>
            </div>
        </div>
    `;
    
    // Use setProperty with important flag to override !important in CSS
    modal.style.setProperty('display', 'flex', 'important');
    document.body.style.overflow = 'hidden';
    
    // Close on outside click
    modal.onclick = function(event) {
        if (event.target === modal) {
            closeShareOptionsModal();
        }
    };
}

// Close share options modal
function closeShareOptionsModal() {
    const modal = document.getElementById('shareOptionsModal');
    if (modal) {
        modal.style.setProperty('display', 'none', 'important');
        document.body.style.overflow = '';
    }
}

// Share with link (generates share token if needed)
function shareWithLink(trackId, trackTitle, artistName, isPrivate) {
    closeShareOptionsModal();
    
    // Get expiration time from select (if private track)
    let expiresIn = 3600; // Default 1 hour
    if (isPrivate) {
        const expirationSelect = document.getElementById('shareExpirationSelect');
        if (expirationSelect) {
            expiresIn = parseInt(expirationSelect.value) || 3600;
        }
    }
    
    // Generate or get share token
    fetch('/api_track_management.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'generate_share_token', 
            track_id: trackId,
            expires_in: expiresIn
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const shareUrl = data.share_url;
            const shareText = `🎵 Check out "${trackTitle}" by ${artistName} on SoundStudioPro!`;
            
            // Record the share
            fetch('/api_social.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ 
                    action: 'share', 
                    track_id: trackId, 
                    platform: 'web' 
                })
            }).catch(err => console.error('Share recording error:', err));
            
            // Perform share action
            if (navigator.share) {
                navigator.share({
                    title: `${trackTitle} by ${artistName}`,
                    text: shareText,
                    url: shareUrl
                })
                .then(() => {
                    if (typeof showNotification === 'function') {
                        showNotification(libraryTranslations.share_success, 'success');
                    }
                })
                .catch(error => {
                    console.log('Web Share API cancelled, using clipboard:', error);
                    copyToClipboard(shareText, shareUrl);
                });
            } else {
                copyToClipboard(shareText, shareUrl);
            }
        } else {
            if (typeof showNotification === 'function') {
                showNotification(libraryTranslations.share_failed, 'error');
            }
        }
    })
    .catch(error => {
        console.error('Error generating share token:', error);
        if (typeof showNotification === 'function') {
            showNotification(libraryTranslations.share_failed, 'error');
        }
    });
}

// Make public and share
function makePublicAndShare(trackId, trackTitle, artistName) {
    closeShareOptionsModal();
    
    // First make track public
    fetch('/api_track_management.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'toggle_visibility', 
            track_id: trackId,
            visibility: 1
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Now share with regular URL (no token needed since it's public)
            const trackUrl = `${window.location.origin}/track.php?id=${trackId}`;
            const shareText = `🎵 Check out "${trackTitle}" by ${artistName} on SoundStudioPro!`;
            
            // Record the share
            fetch('/api_social.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ 
                    action: 'share', 
                    track_id: trackId, 
                    platform: 'web' 
                })
            }).catch(err => console.error('Share recording error:', err));
            
            // Perform share action
            if (navigator.share) {
                navigator.share({
                    title: `${trackTitle} by ${artistName}`,
                    text: shareText,
                    url: trackUrl
                })
                .then(() => {
                    if (typeof showNotification === 'function') {
                        showNotification(libraryTranslations.share_make_public_success, 'success');
                    }
                })
                .catch(error => {
                    console.log('Web Share API cancelled, using clipboard:', error);
                    copyToClipboard(shareText, trackUrl);
                });
            } else {
                copyToClipboard(shareText, trackUrl);
            }
        } else {
            if (typeof showNotification === 'function') {
                showNotification(libraryTranslations.share_make_public_failed, 'error');
            }
        }
    })
    .catch(error => {
        console.error('Error making track public:', error);
        if (typeof showNotification === 'function') {
            showNotification(libraryTranslations.share_make_public_failed, 'error');
        }
    });
}

// Helper function to copy to clipboard (matching community_fixed.php pattern)
function copyToClipboard(text, url) {
    const shareData = `${text}\n${url}`;
    const isSecureContext = window.isSecureContext || location.protocol === 'https:' || location.hostname === 'localhost';
    
    if (isSecureContext && navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(shareData).then(() => {
            console.log('🚀 Link copied to clipboard');
            if (typeof showNotification === 'function') {
                showNotification('🔗 Track link copied to clipboard!', 'success');
            } else {
                alert('Track link copied to clipboard!');
            }
        }).catch(error => {
            console.error('🚀 Clipboard API error:', error);
            fallbackCopyToClipboard(shareData);
        });
    } else {
        fallbackCopyToClipboard(shareData);
    }
}

// Fallback copy using textarea (better mobile support)
function fallbackCopyToClipboard(shareData) {
    const textarea = document.createElement('textarea');
    textarea.value = shareData;
    textarea.style.position = 'fixed';
    textarea.style.left = '-9999px';
    textarea.style.top = '-9999px';
    textarea.style.opacity = '0';
    textarea.setAttribute('readonly', '');
    document.body.appendChild(textarea);
    
    if (/Android/i.test(navigator.userAgent)) {
        textarea.style.position = 'absolute';
        textarea.style.left = '0';
        textarea.style.top = '0';
        textarea.style.width = '1px';
        textarea.style.height = '1px';
        textarea.style.opacity = '0.01';
    }
    
    textarea.focus();
    textarea.select();
    textarea.setSelectionRange(0, shareData.length);
    
    try {
        const successful = document.execCommand('copy');
        document.body.removeChild(textarea);
        if (successful) {
            if (typeof showNotification === 'function') {
                showNotification('🔗 Track link copied to clipboard!', 'success');
            } else {
                alert('Track link copied to clipboard!');
            }
        } else {
            prompt('Copy this link:', shareData);
        }
    } catch (error) {
        document.body.removeChild(textarea);
        prompt('Copy this link:', shareData);
    }
}

// Working comments function with modal
function showComments(trackId) {
    // Create and show comments modal
    const modal = document.createElement('div');
    modal.className = 'comments-modal';
    modal.innerHTML = `
        <div class="comments-overlay">
            <div class="comments-container">
                <div class="comments-header">
                    <h3>Comments</h3>
                    <button class="close-btn" onclick="closeComments()">×</button>
                </div>
                <div class="comments-list" id="comments-list-${trackId}">
                    <div class="loading">Loading comments...</div>
                </div>
                <div class="comment-form">
                    <textarea id="comment-text-${trackId}" placeholder="Write a comment..." maxlength="500"></textarea>
                    <button onclick="addComment(${trackId})" class="btn btn-primary">Post Comment</button>
                </div>
            </div>
        </div>
    `;
    document.body.appendChild(modal);
    
    // Load comments
    loadComments(trackId);
}

function closeComments() {
    const modal = document.querySelector('.comments-modal');
    if (modal) {
        modal.remove();
    }
}

function loadComments(trackId) {
    console.log('🎵 Loading comments for track:', trackId);
    fetch(`/api_social.php?action=get_comments&track_id=${trackId}`)
    .then(response => {
        console.log('🎵 Load comments API response status:', response.status);
        return response.json();
    })
    .then(data => {
        console.log('🎵 Load comments API response data:', data);
        const commentsList = document.getElementById(`comments-list-${trackId}`);
        
        if (data.success && data.comments && data.comments.length > 0) {
            commentsList.innerHTML = data.comments.map(comment => `
                <div class="comment-item">
                    <div class="comment-avatar">
                        ${comment.profile_image ? 
                            `<img src="${comment.profile_image}" alt="${comment.user_name}" onerror="this.parentElement.innerHTML='<div class=\'default-avatar-small\'>${comment.user_name.charAt(0)}</div>'">` :
                            `<div class="default-avatar-small">${comment.user_name.charAt(0)}</div>`
                        }
                    </div>
                    <div class="comment-content">
                        <div class="comment-header">
                            <span class="comment-author">${comment.user_name}</span>
                            <span class="comment-time">${comment.created_at}</span>
                        </div>
                        <div class="comment-text">${comment.comment}</div>
                    </div>
                </div>
            `).join('');
        } else {
            commentsList.innerHTML = '<div class="no-comments">No comments yet. Be the first to comment!</div>';
        }
    })
    .catch(error => {
        console.warn('🎵 Load comments error:', error);
        document.getElementById(`comments-list-${trackId}`).innerHTML = '<div class="error">Failed to load comments</div>';
    });
}

function addComment(trackId) {
    if (!<?= $user_id ? 'true' : 'false' ?>) {
        showNotification('Please log in to comment', 'warning');
        return;
    }
    
    const textarea = document.getElementById(`comment-text-${trackId}`);
    const comment = textarea.value.trim();
    
    if (!comment) {
        showNotification('Please enter a comment', 'warning');
        return;
    }
    
    // Show loading state
    const submitBtn = textarea.nextElementSibling;
    const originalText = submitBtn.textContent;
    submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Posting...';
    submitBtn.disabled = true;
    
    fetch('/api_social.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'comment', 
            track_id: trackId, 
            comment: comment 
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            textarea.value = '';
            loadComments(trackId); // Reload comments
            showNotification('Comment posted!', 'success');
        } else {
            showNotification(data.message || 'Failed to post comment', 'error');
        }
    })
    .catch(error => {
        console.warn('🎵 Comment error:', error);
        showNotification('Failed to post comment. Please try again.', 'error');
    })
    .finally(() => {
        // Restore button
        submitBtn.textContent = originalText;
        submitBtn.disabled = false;
    });
}

// Notification system
function showNotification(message, type = 'info') {
    // Remove existing notifications
    const existingNotifications = document.querySelectorAll('.notification');
    existingNotifications.forEach(notification => notification.remove());
    
    // Create notification element
    const notification = document.createElement('div');
    notification.className = `notification notification-${type}`;
    notification.innerHTML = `
        <div class="notification-content">
            <i class="notification-icon ${getNotificationIcon(type)}"></i>
            <span class="notification-message">${message}</span>
            <button class="notification-close" onclick="this.parentElement.parentElement.remove()">
                <i class="fas fa-times"></i>
            </button>
        </div>
    `;
    
    // Add to page
    document.body.appendChild(notification);
    
    // Show animation
    setTimeout(() => {
        notification.classList.add('show');
    }, 100);
    
    // Auto remove after 5 seconds
    setTimeout(() => {
        notification.classList.remove('show');
        setTimeout(() => {
            if (notification.parentElement) {
                notification.remove();
            }
        }, 300);
    }, 5000);
}

function getNotificationIcon(type) {
    switch (type) {
        case 'success': return 'fas fa-check-circle';
        case 'error': return 'fas fa-exclamation-circle';
        case 'warning': return 'fas fa-exclamation-triangle';
        default: return 'fas fa-info-circle';
    }
}

// Enhanced global player initialization check
function waitForEnhancedPlayerCallback(callback, maxAttempts = 20) {
    if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
        callback();
        return;
    }
    
    if (maxAttempts > 0) {
        setTimeout(() => waitForEnhancedPlayerCallback(callback, maxAttempts - 1), 250);
    } else {
        console.warn('⚠️ Enhanced global player not available, attempting to initialize...');
        showNotification('Audio player not available. Please refresh the page.', 'error');
    }
}

// Enable play buttons when global player is ready
function enablePlayButtons() {
    console.log('🎵 Enabling play buttons - global player ready');
    
    // Enable all play buttons
    document.querySelectorAll('.action-btn.play-btn, .play-track-btn').forEach(btn => {
        btn.classList.add('ready');
        btn.disabled = false;
        
        // Remove loading state if present
        const icon = btn.querySelector('i');
        if (icon && icon.className.includes('fa-spinner')) {
            icon.className = 'fas fa-play';
        }
    });
    
    // Show ready notification
    showNotification('🎵 Audio player ready!', 'success');
}

// Professional music feed functions
function playTrack(trackId, audioUrl, title, artist) {
    console.log('🎵 Playing track:', { trackId, audioUrl, title, artist });
    
    // Ensure global player is ready before attempting playback
    if (!window.enhancedGlobalPlayer || typeof window.enhancedGlobalPlayer.playTrack !== 'function') {
        console.warn('❌ Global player not available');
        showNotification('Audio player not ready. Please refresh the page.', 'error');
        return;
    }
    
    // Ensure audio URL is absolute if it's relative
    let finalAudioUrl = audioUrl;
    if (audioUrl && !audioUrl.startsWith('http') && !audioUrl.startsWith('//')) {
        if (audioUrl.startsWith('/')) {
            finalAudioUrl = window.location.origin + audioUrl;
        } else {
            finalAudioUrl = window.location.origin + '/' + audioUrl;
        }
        console.log('🎵 Converted relative URL to absolute:', finalAudioUrl);
    }
    
    if (!finalAudioUrl || finalAudioUrl.trim() === '') {
        console.error('❌ Audio URL is empty!');
        showNotification('Audio file not available.', 'error');
        return;
    }
    
    try {
        // Call the global player's playTrack function
        const success = window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist);
        
        if (success) {
            // Update UI - Mark this track as currently playing
            document.querySelectorAll('.track-card').forEach(card => {
                card.classList.remove('currently-playing', 'playing');
            });
            
            // Reset all play buttons
            document.querySelectorAll('.action-btn.play-btn, .play-track-btn, .action-btn-compact.primary').forEach(btn => {
                btn.classList.remove('playing');
                const icon = btn.querySelector('i');
                if (icon) {
                    icon.className = 'fas fa-play';
                }
            });
            
            const currentCard = document.querySelector(`[data-track-id="${trackId}"]`);
            if (currentCard) {
                currentCard.classList.add('currently-playing', 'playing');
                
                // Update compact play button
                const compactPlayBtn = currentCard.querySelector('.action-btn.play-btn, .action-btn-compact.primary');
                if (compactPlayBtn) {
                    compactPlayBtn.classList.add('playing');
                    const icon = compactPlayBtn.querySelector('i');
                    if (icon) icon.className = 'fas fa-pause';
                }
                
                // Update full play button if exists
                const fullPlayBtn = currentCard.querySelector('.play-track-btn');
                if (fullPlayBtn) {
                    fullPlayBtn.classList.add('playing');
                    fullPlayBtn.innerHTML = '<i class="fas fa-pause"></i> <span>Playing</span>';
                }
            }
            
            // Record play analytics
            recordTrackPlay(trackId);
            
            // Show notification
            showNotification('🎵 Now playing: ' + title, 'success');
            
            console.log('✅ Track playing successfully');
        } else {
            console.warn('❌ Global player returned false');
            showNotification('Failed to start playback. Please try again.', 'error');
        }
    } catch (error) {
        console.warn('❌ Error during playback:', error);
        showNotification('Playback error: ' + error.message, 'error');
    }
}

function playTrackFromWaveform(trackId, audioUrl, title, artist) {
    playTrack(trackId, audioUrl, title, artist);
}

function addToCart(trackId, title, price, artistPlan = 'free') {
    if (!<?= $user_id ? 'true' : 'false' ?>) {
        showNotification('Please log in to add tracks to cart', 'warning');
        return;
    }
    
    console.log('🛒 Adding to cart:', { trackId, title, price, artistPlan });
    
    // Add loading state to button
    const button = event.target.closest('.btn-cart');
    const originalText = button.innerHTML;
    button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Adding...';
    button.disabled = true;
    
    // Send to cart.php via POST with artist plan info
    const formData = new FormData();
    formData.append('track_id', trackId);
    formData.append('action', 'add');
    formData.append('artist_plan', artistPlan);
    
    fetch('cart.php', {
        method: 'POST',
        body: formData
    })
    .then(response => response.text())
    .then(responseText => {
        console.log('🛒 Raw cart response:', responseText);
        
        let data;
        try {
            data = JSON.parse(responseText);
            console.log('🛒 Parsed cart response:', data);
        } catch (e) {
                    console.warn('🛒 Failed to parse JSON response:', e);
        console.warn('🛒 Raw response was:', responseText);
            throw new Error('Invalid JSON response from cart');
        }
        
        if (!data.success) {
            throw new Error(data.message || 'Failed to add to cart');
        }
        
        if (price == 0) {
            // Free track - make it feel like a premium purchase experience!
            showNotification(`🎵 "${title}" added to cart for FREE! 🛒 Ready to purchase and own!`, 'success');
        } else {
            // Paid track added to cart
            const revenueInfo = (artistPlan === 'free') ? ' (Platform Revenue)' : '';
            showNotification(`"${title}" added to cart! ($${price})${revenueInfo}`, 'success');
        }
        
        // Update cart UI if there's a cart counter
        const cartCounter = document.querySelector('.cart-count, .cart-counter');
        if (cartCounter && data.cart_count) {
            cartCounter.textContent = data.cart_count;
        }
        
        // Log debug info if available
        if (data.debug) {
            if (defined('DEVELOPMENT_MODE') && DEVELOPMENT_MODE) {
            console.log('🛒 Debug info:', data.debug);
        }
        }
        
        // Change button to "Added" state temporarily
        button.innerHTML = '<i class="fas fa-check"></i> Added!';
        button.classList.add('added');
        
        setTimeout(() => {
            button.innerHTML = originalText;
            button.classList.remove('added');
            button.disabled = false;
        }, 2000);
    })
    .catch(error => {
        console.warn('🛒 Cart error:', error);
        showNotification('Failed to add to cart: ' + error.message, 'error');
        
        // Restore button
        button.innerHTML = originalText;
        button.disabled = false;
    });
}

function toggleFollow(userId, button) {
    if (!<?= $user_id ? 'true' : 'false' ?>) {
        showNotification('Please log in to follow artists', 'warning');
        return;
    }
    
    console.log('👤 Toggling follow for user:', userId);
    
    // Add loading state
    button.style.pointerEvents = 'none';
    const originalText = button.innerHTML;
    button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
    
    fetch('/api_social.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action: 'follow', user_id: userId })
    })
    .then(response => {
        console.log('👤 Follow API response status:', response.status);
        return response.json();
    })
    .then(data => {
        console.log('👤 Follow API response data:', data);
        if (data.success) {
            button.classList.toggle('following');
            const isFollowing = button.classList.contains('following');
            button.innerHTML = `<i class="fas fa-user-${isFollowing ? 'check' : 'plus'}"></i> ${isFollowing ? 'Following' : 'Follow'}`;
            
            // Show success notification
            const action = isFollowing ? 'followed' : 'unfollowed';
            showNotification(`Artist ${action}!`, 'success');
        } else {
            showNotification(data.message || 'Failed to follow artist', 'error');
        }
    })
    .catch(error => {
        console.warn('👤 Follow error:', error);
        showNotification('Failed to follow artist. Please try again.', 'error');
    })
    .finally(() => {
        // Restore button
        button.style.pointerEvents = 'auto';
        if (!button.innerHTML.includes('Following') && !button.innerHTML.includes('Follow')) {
            button.innerHTML = originalText;
        }
    });
}

// Track play count functionality
function recordTrackPlay(trackId) {
    // Only record if not already recorded recently
    const lastPlayed = sessionStorage.getItem(`played_${trackId}`);
    const now = Date.now();
    
    if (!lastPlayed || (now - parseInt(lastPlayed)) > 30000) { // 30 seconds minimum between plays
        fetch('/api_social.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: 'play', track_id: trackId })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                sessionStorage.setItem(`played_${trackId}`, now.toString());
                console.log('🎵 Play count recorded for track:', trackId);
            }
        })
        .catch(error => {
            console.warn('🎵 Play count error:', error);
        });
    }
}

// Play button functionality is now handled by inline onclick="togglePlayPause()" calls
// This prevents conflicts and ensures proper parameter passing
document.addEventListener('DOMContentLoaded', function() {
    console.log('🎵 Community Fixed - Initialized (play buttons use inline handlers)');
    
    // Initialize like button states from server data
    // The buttons are already set with the 'liked' class from PHP, but we verify here
    document.querySelectorAll('.action-icon-btn[onclick*="toggleLike"]').forEach(button => {
        const onclickAttr = button.getAttribute('onclick');
        const trackIdMatch = onclickAttr.match(/toggleLike\((\d+)/);
        if (trackIdMatch) {
            const trackId = parseInt(trackIdMatch[1]);
            // Verify the like state matches the server state
            // The button should already have the 'liked' class if user_liked > 0
            if (button.classList.contains('liked')) {
                console.log('❤️ Like button initialized as liked for track:', trackId);
            }
        }
    });
});

// 🚀 VIRAL TRACK SHARING SYSTEM
function showShareModal(trackId, title, artist) {
    const trackUrl = `https://soundstudiopro.com/track/${trackId}`;
    const shareText = `🎵 Check out "${title}" by ${artist}`;
    
    // Update share URL input
    document.getElementById('shareUrl').value = trackUrl;
    
    // Update social share links
    const platforms = {
        twitter: `https://twitter.com/intent/tweet?text=${encodeURIComponent(shareText)}&url=${encodeURIComponent(trackUrl)}`,
        facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(trackUrl)}`,
        whatsapp: `https://wa.me/?text=${encodeURIComponent(shareText + ' ' + trackUrl)}`,
        linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(trackUrl)}`,
        discord: `https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=${encodeURIComponent(trackUrl)}&response_type=code&scope=webhook.incoming`
    };
    
    // Update platform buttons
    document.querySelector('[data-platform="twitter"]').onclick = () => openShare(platforms.twitter, 'twitter', trackId);
    document.querySelector('[data-platform="facebook"]').onclick = () => openShare(platforms.facebook, 'facebook', trackId);
    document.querySelector('[data-platform="whatsapp"]').onclick = () => openShare(platforms.whatsapp, 'whatsapp', trackId);
    document.querySelector('[data-platform="linkedin"]').onclick = () => openShare(platforms.linkedin, 'linkedin', trackId);
    document.querySelector('[data-platform="discord"]').onclick = () => copyDiscordLink(trackUrl, trackId);
    
    document.getElementById('shareModal').style.display = 'block';
    document.body.style.overflow = 'hidden';
}

function openShare(url, platform, trackId) {
    window.open(url, '_blank', 'width=600,height=400');
    recordShare(trackId, platform);
    closeShareModal();
}

function copyShareUrl() {
    const shareUrl = document.getElementById('shareUrl');
    shareUrl.select();
    shareUrl.setSelectionRange(0, 99999);
    navigator.clipboard.writeText(shareUrl.value);
    
    const copyBtn = document.querySelector('.copy-btn');
    const originalText = copyBtn.textContent;
    copyBtn.textContent = 'Copied!';
    copyBtn.classList.add('copied');
    
    setTimeout(() => {
        copyBtn.textContent = originalText;
        copyBtn.classList.remove('copied');
    }, 2000);
    
    // Record share
    const trackId = shareUrl.value.split('/track/')[1];
    recordShare(trackId, 'copy-link');
}

function copyDiscordLink(url, text, trackId) {
    const discordText = `🎵 ${text}\\n${url}`;
    navigator.clipboard.writeText(discordText).then(() => {
        recordShare(trackId, 'discord');
        showNotification('Discord message copied! Paste it in your server 🚀', 'success');
    });
}

function copyInstagramLink(url, text, trackId) {
    navigator.clipboard.writeText(url).then(() => {
        recordShare(trackId, 'instagram');
        showNotification('Link copied! Add it to your Instagram story 📸', 'success');
    });
}

function recordShare(trackId, platform) {
    fetch('/api_social.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'share', 
            track_id: trackId, 
            platform: platform 
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log(`🚀 Share recorded: ${platform} for track ${trackId}`);
            // Update share count in UI
            const shareButton = document.querySelector(`[onclick*="${trackId}"] .social-count`);
            if (shareButton) {
                const currentCount = parseInt(shareButton.textContent);
                shareButton.textContent = currentCount + 1;
            }
        }
    })
    .catch(error => {
        console.warn('🚀 Share recording error:', error);
    });
}

// Handle shared track highlighting from URL
function handleSharedTrack() {
    const urlParams = new URLSearchParams(window.location.search);
    const trackId = urlParams.get('track');
    
    if (trackId) {
        // Find the track card
        const trackCard = document.querySelector(`[data-track-id="${trackId}"]`)?.closest('.track-card');
        
        if (trackCard) {
            // Scroll to the track
            setTimeout(() => {
                trackCard.scrollIntoView({ 
                    behavior: 'smooth', 
                    block: 'center' 
                });
                
                // Add highlight effect
                trackCard.classList.add('highlighted');
                
                // Optional: Auto-play the track
                const playButton = trackCard.querySelector('.play-track-btn');
                if (playButton) {
                    setTimeout(() => {
                        playButton.click();
                    }, 1000);
                }
                
                // Remove highlight after animation
                setTimeout(() => {
                    trackCard.classList.remove('highlighted');
                }, 3000);
                
            }, 500);
            
            showNotification('🎵 Shared track found! Playing now...', 'success');
        } else {
            showNotification('Track not found on this page', 'warning');
        }
    }
}

// Initialize shared track handling
document.addEventListener('DOMContentLoaded', function() {
    handleSharedTrack();
});

// Close modal when clicking outside
document.addEventListener('click', function(e) {
    if (e.target.classList.contains('share-modal')) {
        closeShareModal();
    }
});

// DJ Mixing Features
function highlightCompatibleTracks(currentBpm, currentKey) {
    const tracks = document.querySelectorAll('.track-card');
    
    tracks.forEach(track => {
        const bpmElement = track.querySelector('.bpm-value');
        const keyElement = track.querySelector('.key-value');
        
        if (bpmElement && keyElement) {
            const trackBpm = parseInt(bpmElement.textContent);
            const trackKey = keyElement.textContent;
            
            // BPM compatibility (within 6% for mixing)
            const bpmDiff = Math.abs(trackBpm - currentBpm);
            const bpmCompatible = bpmDiff <= (currentBpm * 0.06);
            
            // Key compatibility (same key, relative major/minor, perfect 5th)
            const keyCompatible = isKeyCompatible(currentKey, trackKey);
            
            // Add visual indicators
            if (bpmCompatible) {
                bpmElement.parentElement.classList.add('bpm-compatible');
            }
            
            if (keyCompatible) {
                keyElement.parentElement.classList.add('key-compatible');
            }
            
            if (bpmCompatible && keyCompatible) {
                track.classList.add('perfect-mix-match');
            }
        }
    });
}

function isKeyCompatible(key1, key2) {
    // Simplified key compatibility - same key, relative major/minor
    if (key1 === key2) return true;
    
    // Basic major/minor relative matching
    const keyMap = {
        'C major': 'A minor',
        'A minor': 'C major',
        'G major': 'E minor',
        'E minor': 'G major',
        'D major': 'B minor',
        'B minor': 'D major',
        'A major': 'F# minor',
        'F# minor': 'A major',
        'E major': 'C# minor',
        'C# minor': 'E major',
        'F major': 'D minor',
        'D minor': 'F major',
        'Bb major': 'G minor',
        'G minor': 'Bb major'
    };
    
    return keyMap[key1] === key2;
}

function calculateBpmRange(bpm) {
    const range = Math.round(bpm * 0.06);
    return {
        min: bpm - range,
        max: bpm + range,
        half: Math.round(bpm / 2),
        double: bpm * 2
    };
}

// Enhanced track clicking for DJ mode
function selectTrackForDjMode(trackElement) {
    // Clear previous selections
    document.querySelectorAll('.track-card.dj-selected').forEach(card => {
        card.classList.remove('dj-selected');
    });
    
    // Mark as selected
    trackElement.classList.add('dj-selected');
    
    // Get technical info
    const bpmElement = trackElement.querySelector('.bpm-value');
    const keyElement = trackElement.querySelector('.key-value');
    
    if (bpmElement && keyElement) {
        const bpm = parseInt(bpmElement.textContent);
        const key = keyElement.textContent;
        
        // Highlight compatible tracks
        highlightCompatibleTracks(bpm, key);
        
        // Show DJ info panel
        showDjMixingPanel(bpm, key);
    }
}

function showDjMixingPanel(bpm, key) {
    const bpmRange = calculateBpmRange(bpm);
    
    // Create or update DJ panel
    let djPanel = document.getElementById('dj-mixing-panel');
    if (!djPanel) {
        djPanel = document.createElement('div');
        djPanel.id = 'dj-mixing-panel';
        djPanel.className = 'dj-mixing-panel';
        document.body.appendChild(djPanel);
    }
    
    djPanel.innerHTML = `
        <div class="dj-panel-header">
            <h3>🎧 DJ Mixing Info</h3>
            <button onclick="closeDjPanel()" class="close-dj-panel">×</button>
        </div>
        <div class="dj-panel-content">
            <div class="current-track-info">
                <div class="dj-info-item">
                    <label>Current BPM:</label>
                    <span class="dj-bpm">${bpm}</span>
                </div>
                <div class="dj-info-item">
                    <label>Current Key:</label>
                    <span class="dj-key">${key}</span>
                </div>
            </div>
            <div class="mixing-suggestions">
                <h4>🎯 Mixing Compatibility</h4>
                <div class="bpm-suggestions">
                    <p><strong>BPM Range:</strong> ${bpmRange.min} - ${bpmRange.max}</p>
                    <p><strong>Half Time:</strong> ${bpmRange.half} BPM</p>
                    <p><strong>Double Time:</strong> ${bpmRange.double} BPM</p>
                </div>
                <div class="key-suggestions">
                    <p><strong>Compatible Keys:</strong> Same key, relative major/minor</p>
                </div>
            </div>
        </div>
    `;
    
    djPanel.style.display = 'block';
}

function closeDjPanel() {
    const djPanel = document.getElementById('dj-mixing-panel');
    if (djPanel) {
        djPanel.style.display = 'none';
    }
    
    // Clear all highlighting
    document.querySelectorAll('.track-card').forEach(card => {
        card.classList.remove('dj-selected', 'perfect-mix-match');
    });
    
    document.querySelectorAll('.bpm-compatible').forEach(el => {
        el.classList.remove('bpm-compatible');
    });
    
    document.querySelectorAll('.key-compatible').forEach(el => {
        el.classList.remove('key-compatible');
    });
}

// Add click handlers for DJ mode
document.addEventListener('DOMContentLoaded', function() {
    document.querySelectorAll('.dj-tech-grid').forEach(grid => {
        grid.addEventListener('click', function(e) {
            e.preventDefault();
            const trackCard = this.closest('.track-card');
            selectTrackForDjMode(trackCard);
        });
    });
});

// Premium Rating System
function rateTrack(trackId, rating, starElement) {
    if (!<?= $user_id ? 'true' : 'false' ?>) {
        showNotification('Please log in to rate tracks', 'warning');
        return;
    }
    
    console.log('⭐ Rating track:', trackId, 'with', rating, 'stars');
    
    // Add loading state
    const ratingContainer = starElement.closest('.star-rating');
    ratingContainer.style.pointerEvents = 'none';
    
    fetch('/api_social.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'rate', 
            track_id: trackId, 
            rating: rating 
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Update visual rating
            const stars = ratingContainer.querySelectorAll('.star');
            stars.forEach((star, index) => {
                star.classList.remove('filled', 'user-rated');
                if (index < data.average_rating) {
                    star.classList.add('filled');
                }
                if (index < rating) {
                    star.classList.add('user-rated');
                }
            });
            
            // Update stats
            const avgElement = ratingContainer.closest('.track-rating-section').querySelector('.avg-rating');
            const countElement = ratingContainer.closest('.track-rating-section').querySelector('.rating-count');
            
            if (avgElement) avgElement.textContent = data.average_rating.toFixed(1) + '/10';
            if (countElement) countElement.textContent = `(${data.rating_count} ratings)`;
            
            showNotification(`⭐ Rated ${rating}/10 stars!`, 'success');
        } else {
            showNotification(data.message || 'Failed to rate track', 'error');
        }
    })
    .catch(error => {
        console.warn('⭐ Rating error:', error);
        showNotification('Failed to rate track. Please try again.', 'error');
    })
    .finally(() => {
        ratingContainer.style.pointerEvents = 'auto';
    });
}

// Enhanced Play/Pause Logic
    // Track currently playing track ID for state management
    let currentlyPlayingTrackId = null;

function togglePlayPause(button, trackId, audioUrl, title, artist) {
    const isCurrentlyPlaying = currentlyPlayingTrackId === trackId;
    const globalPlayer = window.enhancedGlobalPlayer;
    
    if (isCurrentlyPlaying && globalPlayer && globalPlayer.isPlaying) {
        // Pause current track
        globalPlayer.pause();
        button.innerHTML = '<i class="fas fa-play"></i><span>Play</span>';
        button.classList.remove('playing');
        
        // Remove playing states
        document.querySelectorAll('.track-card').forEach(card => {
            card.classList.remove('currently-playing');
        });
        
        currentlyPlayingTrackId = null;
        showNotification('⏸️ Paused', 'success');
    } else {
        // Play new track or resume
        if (globalPlayer && typeof globalPlayer.playTrack === 'function') {
            globalPlayer.playTrack(audioUrl, title, artist);
            
            // Update all play buttons
            document.querySelectorAll('.play-track-btn').forEach(btn => {
                btn.classList.remove('playing');
                btn.innerHTML = '<i class="fas fa-play"></i><span>Play</span>';
            });
            
            // Update current button
            button.classList.add('playing');
            button.innerHTML = '<i class="fas fa-pause"></i><span>Playing</span>';
            
            // Update track cards
            document.querySelectorAll('.track-card').forEach(card => {
                card.classList.remove('currently-playing');
            });
            
            const currentCard = document.querySelector(`[data-track-id="${trackId}"]`);
            if (currentCard) {
                currentCard.classList.add('currently-playing');
            }
            
            currentlyPlayingTrackId = trackId;
            recordTrackPlay(trackId);
            showNotification('🎵 Now playing: ' + title, 'success');
        } else {
            showNotification('Player not ready, please try again', 'error');
        }
    }
}

// View Track Charts Function
function viewTrackCharts(trackId, genre) {
    // Build chart URL with track context
    const chartUrl = `/charts.php?track=${trackId}&genre=${encodeURIComponent(genre)}&highlight=true`;
    
    // Open charts in new tab or redirect
    if (confirm('View this track in the global charts?')) {
        window.open(chartUrl, '_blank');
    }
}

// Charts Modal Functions
function showChartsModal(trackId, position, title, genre) {
    document.getElementById('currentPosition').textContent = '#' + position;
    document.getElementById('trackTitle').textContent = title;
    document.getElementById('genreRanking').textContent = '#' + Math.floor(Math.random() * 20 + 1) + ' in ' + genre;
    document.getElementById('weeklyPlays').textContent = (Math.floor(Math.random() * 1000) + 100).toLocaleString();
    document.getElementById('totalRating').textContent = (Math.random() * 3 + 7).toFixed(1) + '/10';
    
    // Random position change
    const change = Math.floor(Math.random() * 20) - 10;
    const changeElement = document.getElementById('positionChange');
    if (change > 0) {
        changeElement.textContent = '↗ +' + change + ' this week';
        changeElement.className = 'position-change';
    } else if (change < 0) {
        changeElement.textContent = '↘ ' + change + ' this week';
        changeElement.className = 'position-change down';
    } else {
        changeElement.textContent = '→ No change';
        changeElement.className = 'position-change';
    }
    
    document.getElementById('chartsModal').style.display = 'flex';
    document.body.style.overflow = 'hidden';
}

function closeChartsModal() {
    document.getElementById('chartsModal').style.display = 'none';
    document.body.style.overflow = 'auto';
}

function openFullCharts() {
    closeChartsModal();
    window.open('/charts.php', '_blank');
}

// Premium Modal Functions
function showPremiumModal() {
    document.getElementById('premiumModal').style.display = 'flex';
    document.body.style.overflow = 'hidden';
}

function closePremiumModal() {
    document.getElementById('premiumModal').style.display = 'none';
    document.body.style.overflow = 'auto';
}

function upgradeToPremium() {
    closePremiumModal();
    window.location.href = '/upgrade.php';
}

// Close modals when clicking outside
window.onclick = function(event) {
    const chartsModal = document.getElementById('chartsModal');
    const premiumModal = document.getElementById('premiumModal');
    
    if (event.target === chartsModal) {
        closeChartsModal();
    }
    if (event.target === premiumModal) {
        closePremiumModal();
    }
}

// Toggle Lyrics Function
function toggleLyrics(trackId) {
    const lyricsContent = document.getElementById('lyrics-' + trackId);
    const toggleButton = lyricsContent.previousElementSibling;
    const toggleSpan = toggleButton.querySelector('span');
    const toggleIcon = toggleButton.querySelector('.toggle-icon');
    
    if (lyricsContent.style.display === 'none') {
        lyricsContent.style.display = 'block';
        lyricsContent.classList.add('expanded');
        toggleButton.classList.add('active');
        toggleSpan.textContent = 'Hide Lyrics';
    } else {
        lyricsContent.classList.remove('expanded');
        toggleButton.classList.remove('active');
        toggleSpan.textContent = 'Show Lyrics';
        
        setTimeout(() => {
            lyricsContent.style.display = 'none';
        }, 400);
    }
}

// Add to Playlist Function
function addToPlaylist(trackId) {
    // TODO: Implement playlist functionality
    showNotification('🎵 Playlist feature coming soon!', 'info');
}











// Add to Cart Function
function addToCart(trackId, title, price, button) {
    button.disabled = true;
    button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
    
    fetch('/cart.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `action=add&track_id=${trackId}&title=${encodeURIComponent(title)}&price=${price}`
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            showNotification(`🛒 "${title}" added to cart!`, 'success');
            
            // Update cart counter if it exists - use the actual count from the API response
            const cartCounts = document.querySelectorAll('.cart-count, .cart-counter');
            if (cartCounts.length > 0 && data.cart_count !== undefined) {
                cartCounts.forEach(count => {
                    count.textContent = data.cart_count;
                    // Show the badge if count > 0
                    if (data.cart_count > 0) {
                        count.style.display = 'flex';
                        if (count.classList.contains('cart-counter')) {
                            count.style.display = 'block';
                        }
                    } else {
                        count.style.display = 'none';
                    }
                });
            } else if (cartCounts.length > 0) {
                // Fallback: manually increment if API didn't return count
                cartCounts.forEach(count => {
                    const currentCount = parseInt(count.textContent) || 0;
                    count.textContent = currentCount + 1;
                    count.style.display = 'flex';
                    if (count.classList.contains('cart-counter')) {
                        count.style.display = 'block';
                    }
                });
            }
            
            // Refresh cart modal if it's currently open
            const cartModal = document.getElementById('cartModal');
            if (cartModal && cartModal.style.display === 'flex') {
                if (typeof refreshCartModal === 'function') {
                    refreshCartModal();
                }
            }
        } else {
            showNotification(data.message || 'Failed to add to cart', 'error');
        }
    })
    .catch(error => {
        console.warn('Cart error:', error);
        showNotification('Network error', 'error');
    })
    .finally(() => {
        button.disabled = false;
        button.innerHTML = '<i class="fas fa-shopping-cart"></i>';
    });
}

// Record Track Play
function recordTrackPlay(trackId) {
    fetch('/api_social.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `action=play&track_id=${trackId}`
    })
    .catch(error => console.warn('Play tracking error:', error));
}

// Toggle Follow Function
function toggleFollow(userId, button) {
    const isFollowing = button.classList.contains('following');
    const action = isFollowing ? 'unfollow' : 'follow';
    
    fetch('/api_social.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `action=${action}&user_id=${userId}`
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            button.classList.toggle('following');
            const icon = button.querySelector('i');
            const text = button.querySelector('span') || button.childNodes[1];
            
            if (isFollowing) {
                icon.className = 'fas fa-user-plus';
                if (text) text.textContent = ' Follow';
                showNotification('Unfollowed artist', 'info');
            } else {
                icon.className = 'fas fa-user-check';
                if (text) text.textContent = ' Following';
                showNotification('Following artist!', 'success');
            }
        } else {
            showNotification('Failed to update follow status', 'error');
        }
    })
    .catch(error => {
        console.warn('Follow error:', error);
        showNotification('Network error', 'error');
    });
}
</script>



<script>
// Initialize enhanced global player integration
document.addEventListener('DOMContentLoaded', function() {
    console.log('🎵 Community page loaded, waiting for enhanced global player...');
    
    // Wait for enhanced global player to be ready, then enable play buttons
    waitForEnhancedPlayerCallback(() => {
        enablePlayButtons();
    });
});
</script>
<!-- Include the existing modals and JavaScript functions -->
<!-- This ensures all functionality is preserved -->

<!-- Stems Modal -->
<div id="stemsModal" class="variations-modal">
    <div class="variations-content">
        <div class="variations-header">
            <h2 class="variations-title">🎵 Track Stems</h2>
            <button class="close-variations" onclick="closeStemsModal()">
                <i class="fas fa-times"></i>
            </button>
        </div>
        
        <div id="stemsGrid" class="variations-grid">
            <!-- Stems will be loaded here -->
        </div>
    </div>
</div>

<!-- Variations Modal -->
<div id="variationsModal" class="variations-modal">
    <div class="variations-content">
        <div class="variations-header">
            <h2 class="variations-title"><?= t('library.variations.title') ?></h2>
            <button class="close-variations" onclick="closeVariations()">
                <i class="fas fa-times"></i>
            </button>
        </div>
        
        <div id="variationsGrid" class="variations-grid">
            <!-- Variations will be loaded here -->
        </div>
        
        <div class="variations-footer">
            <div class="variations-info">
                <i class="fas fa-info-circle"></i>
                <?= t('library.variations.info') ?>
            </div>
            <div class="variations-actions">
                <button class="variations-btn cancel" onclick="closeVariations()">
                    <?= t('library.variations.cancel') ?>
                </button>
                <button id="saveVariationBtn" class="variations-btn save" onclick="saveVariationSelection()" disabled>
                    <?= t('library.variations.save_selection') ?>
                </button>
            </div>
        </div>
    </div>
</div>

<!-- Lyrics Modal -->
<div id="lyricsModal" class="lyrics-modal">
    <div class="lyrics-content">
        <div class="lyrics-header">
            <h2 class="lyrics-title">Track Lyrics</h2>
            <button class="close-lyrics" onclick="closeLyrics()">
                <i class="fas fa-times"></i>
            </button>
        </div>
        
        <div id="lyricsContent" class="lyrics-body">
            <!-- Lyrics will be loaded here -->
        </div>
        
        <div class="lyrics-footer">
            <div class="lyrics-actions">
                <button class="lyrics-btn cancel" onclick="closeLyrics()">
                    Close
                </button>
                <button class="lyrics-btn copy" onclick="copyLyrics()">
                    <i class="fas fa-copy"></i> Copy Lyrics
                </button>
            </div>
        </div>
    </div>
</div>

<!-- Download Modal -->
<div id="downloadModal" class="download-modal">
    <div class="download-content">
        <div class="download-header">
            <h2 class="download-title">Download Track</h2>
            <button class="close-download" onclick="closeDownload()">
                <i class="fas fa-times"></i>
            </button>
        </div>
        
        <div id="downloadContent" class="download-body">
            <!-- Download options will be loaded here -->
        </div>
        
        <div class="download-footer">
            <div class="download-actions">
                <button class="download-btn cancel" onclick="closeDownload()">
                    Cancel
                </button>
            </div>
        </div>
    </div>
</div>

<script>
// Translation strings for JavaScript
const libraryTranslations = {
    play: '<?= addslashes(t('library.variations.play')) ?>',
    download: '<?= addslashes(t('library.variations.download')) ?>',
    select: '<?= addslashes(t('library.variations.select')) ?>',
    selected: '<?= addslashes(t('library.variations.selected')) ?>',
    variation: '<?= addslashes(t('library.variations.variation')) ?>',
    no_variations: '<?= addslashes(t('library.variations.no_variations')) ?>',
    audio_not_available: '<?= addslashes(t('library.variations.audio_not_available')) ?>',
    untitled_track: '<?= addslashes(t('library.variations.untitled_track')) ?>',
    // Crates translations
    crates_empty_title: '<?= addslashes(t('library.crates.empty_title')) ?>',
    crates_empty_desc: '<?= addslashes(t('library.crates.empty_desc')) ?>',
    crates_create_first: '<?= addslashes(t('library.crates.create_first')) ?>',
    crates_set_duration: '<?= addslashes(t('library.crates.set_duration')) ?>',
    crates_tracks_needed: '<?= addslashes(t('library.crates.tracks_needed')) ?>',
    crates_ready: '<?= addslashes(t('library.crates.ready')) ?>',
    crates_ready_short: '<?= addslashes(t('library.crates.ready_short')) ?>',
    crates_tracks: '<?= addslashes(t('library.crates.tracks')) ?>',
    crates_min_set: '<?= addslashes(t('library.crates.min_set')) ?>',
    crates_no_tracks: '<?= addslashes(t('library.crates.no_tracks')) ?>',
    crates_add_tracks_desc: '<?= addslashes(t('library.crates.add_tracks_desc')) ?>',
    crates_download: '<?= addslashes(t('library.crates.download')) ?>',
    crates_download_all: '<?= addslashes(t('library.crates.download_all')) ?>',
    crates_add_to_cart: '<?= addslashes(t('common.add_to_cart')) ?>',
    free: '<?= addslashes(t('common.free')) ?>',
    added_to_cart: '<?= addslashes(t('notification.added_to_cart')) ?>',
    added_to_cart_free: '<?= addslashes(t('notification.added_to_cart_free')) ?>',
    crates_remove: '<?= addslashes(t('library.crates.remove')) ?>',
    crates_drag_reorder: '<?= addslashes(t('library.crates.drag_reorder')) ?>',
    crates_order_updated: '<?= addslashes(t('library.crates.order_updated')) ?>',
    crates_updating_order: '<?= addslashes(t('library.crates.updating_order')) ?>',
    crates_error_loading: '<?= addslashes(t('library.crates.error_loading')) ?>',
    crates_error_loading_crate: '<?= addslashes(t('library.crates.error_loading_crate')) ?>',
    crates_error_loading_desc: '<?= addslashes(t('library.crates.error_loading_desc')) ?>',
    crates_track_added: '<?= addslashes(t('library.crates.track_added')) ?>',
    crates_track_removed: '<?= addslashes(t('library.crates.track_removed')) ?>',
    crates_crate_deleted: '<?= addslashes(t('library.crates.crate_deleted')) ?>',
    crates_crate_created: '<?= addslashes(t('library.crates.crate_created')) ?>',
    crates_already_added: '<?= addslashes(t('library.crates.already_added')) ?>',
    crates_loading_tracks: '<?= addslashes(t('library.crates.loading_tracks')) ?>',
    crates_delete_confirm: '<?= addslashes(t('library.crates.delete_confirm')) ?>',
    crates_remove_confirm: '<?= addslashes(t('library.crates.remove_confirm')) ?>',
    crates_loading: '<?= addslashes(t('library.crates.loading')) ?>',
    crates_details: '<?= addslashes(t('library.crates.details')) ?>',
    crates_name_required: '<?= addslashes(t('library.crates.name_required')) ?>',
    crates_visibility_public: '<?= addslashes(t('library.crates.visibility_public')) ?>',
    crates_visibility_private: '<?= addslashes(t('library.crates.visibility_private')) ?>',
    crates_share: '<?= addslashes(t('library.crates.share')) ?>',
    crates_link_copied: '<?= addslashes(t('library.crates.link_copied')) ?>',
    crates_now_public: '<?= addslashes(t('library.crates.now_public')) ?>',
    crates_now_private: '<?= addslashes(t('library.crates.now_private')) ?>',
    crates_track_public: '<?= addslashes(t('library.crates.track_public')) ?>',
    crates_track_private: '<?= addslashes(t('library.crates.track_private')) ?>',
    crates_desc_public: '<?= addslashes(t('library.crates.desc_public')) ?>',
    crates_desc_private: '<?= addslashes(t('library.crates.desc_private')) ?>',
    crates_desc_saved: '<?= addslashes(t('library.crates.desc_saved')) ?>',
    crates_add_description: '<?= addslashes(t('library.crates.add_description')) ?>',
    crates_save_description: '<?= addslashes(t('library.crates.save_description')) ?>',
    crates_renamed: '<?= addslashes(t('library.crates.crate_renamed')) ?>',
    crates_rename: '<?= addslashes(t('library.crates.rename')) ?>',
    crates_rename_modal_title: '<?= addslashes(t('library.crates.rename_modal_title')) ?>',
    crates_new_name: '<?= addslashes(t('library.crates.new_name')) ?>',
    // Menu translations
    view_track_page: '<?= addslashes(t('library.menu.view_track_page')) ?>',
    delete_track: '<?= addslashes(t('library.menu.delete_track')) ?>',
    delete_confirm: '<?= addslashes(t('library.menu.delete_confirm')) ?>',
    // Image upload/download translations
    image_download: '<?= addslashes(t('library.image.download')) ?>',
    image_upload_success: '<?= addslashes(t('library.image.upload_success')) ?>',
    image_upload_failed: '<?= addslashes(t('library.image.upload_failed')) ?>',
    image_upload_failed_unknown: '<?= addslashes(t('library.image.upload_failed_unknown')) ?>',
    image_upload_failed_retry: '<?= addslashes(t('library.image.upload_failed_retry')) ?>',
    image_invalid_file_type: '<?= addslashes(t('library.image.invalid_file_type')) ?>',
    image_file_too_large: '<?= addslashes(t('library.image.file_too_large')) ?>',
    // Share modal translations
    share_title: '<?= addslashes(t('library.share.title')) ?>',
    share_important_notice: '<?= addslashes(t('library.share.important_notice')) ?>',
    share_private_warning: '<?= addslashes(t('library.share.private_warning')) ?>',
    share_expiration_label: '<?= addslashes(t('library.share.expiration_label')) ?>',
    share_expiration_1hour: '<?= addslashes(t('library.share.expiration_1hour')) ?>',
    share_expiration_6hours: '<?= addslashes(t('library.share.expiration_6hours')) ?>',
    share_expiration_24hours: '<?= addslashes(t('library.share.expiration_24hours')) ?>',
    share_expiration_7days: '<?= addslashes(t('library.share.expiration_7days')) ?>',
    share_expiration_30days: '<?= addslashes(t('library.share.expiration_30days')) ?>',
    share_share_with_link: '<?= addslashes(t('library.share.share_with_link')) ?>',
    share_accessible_via_link: '<?= addslashes(t('library.share.accessible_via_link')) ?>',
    share_make_public_and_share: '<?= addslashes(t('library.share.make_public_and_share')) ?>',
    share_cancel: '<?= addslashes(t('library.share.cancel')) ?>',
    share_success: '<?= addslashes(t('library.share.success')) ?>',
    share_failed: '<?= addslashes(t('library.share.failed')) ?>',
    share_make_public_success: '<?= addslashes(t('library.share.make_public_success')) ?>',
    share_make_public_failed: '<?= addslashes(t('library.share.make_public_failed')) ?>'
};

// Global variables for variations functionality
window.trackVariations = [];
window.currentTrackId = null;
window.selectedVariationIndex = null;

// Show variations modal
function showVariations(trackId) {
    console.log('🎵 Showing variations for track:', trackId);
    
    // Get track data from PHP
    const trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) {
        console.warn('🎵 Track card not found for track ID:', trackId);
        alert('Track not found. Please refresh the page and try again.');
        return;
    }
    
    console.log('🎵 Track card found:', trackCard);
    
    // Get variations data from PHP
    const variationsData = trackCard.getAttribute('data-variations');
    console.log('🎵 Raw variations data:', variationsData);
    
    // Debug: Check if variations data exists
    if (!variationsData) {
        console.warn('🎵 No variations data attribute found');
        alert('No variations data found for this track.');
        return;
    }
    
    if (variationsData === '[]' || variationsData === 'null') {
        console.warn('🎵 Variations data is empty');
        alert('No variations available for this track.');
        return;
    }
    
    try {
        if (typeof window.trackVariations === 'undefined') {
            window.trackVariations = [];
        }
        window.trackVariations = JSON.parse(variationsData);
        console.log('🎵 Parsed variations:', window.trackVariations);
        
        if (!Array.isArray(window.trackVariations) || window.trackVariations.length === 0) {
                    console.warn('🎵 No variations in array');
        alert(libraryTranslations.no_variations);
        return;
        }
        
        window.currentTrackId = trackId;
        
        // Get main track title from the track card
        const trackTitleElement = trackCard.querySelector('.track-name');
        window.mainTrackTitle = trackTitleElement ? trackTitleElement.textContent.trim() : libraryTranslations.untitled_track;
        
        // Get current selection
        const currentSelection = trackCard.getAttribute('data-selected-variation') || '0';
        window.selectedVariationIndex = parseInt(currentSelection);
        
        console.log('🎵 About to populate variations grid');
        
        // Populate variations grid
        populateVariationsGrid();
        
        console.log('🎵 About to show modal');
        
        // Show modal
        const modal = document.getElementById('variationsModal');
        if (!modal) {
            console.warn('🎵 Variations modal not found');
            alert('Modal not found. Please refresh the page and try again.');
            return;
        }
        
        modal.classList.add('active');
        console.log('🎵 Modal should now be visible');
        
        // Force modal to be visible and on top
        modal.style.zIndex = '999999';
        modal.style.position = 'fixed';
        modal.style.top = '0';
        modal.style.left = '0';
        modal.style.width = '100%';
        modal.style.height = '100%';
        modal.style.display = 'flex';
        modal.style.alignItems = 'center';
        modal.style.justifyContent = 'center';
        
        console.log('🎵 Modal styles applied:', {
            zIndex: modal.style.zIndex,
            position: modal.style.position,
            display: modal.style.display
        });
        
        // Close on outside click (only if clicking the backdrop, not the content)
        const existingHandler = modal._closeHandler;
        if (existingHandler) {
            modal.removeEventListener('click', existingHandler);
        }
        
        modal._closeHandler = function(e) {
            // Only close if clicking the backdrop (the modal itself), not the content
            if (e.target === modal) {
                closeVariations();
            }
        };
        modal.addEventListener('click', modal._closeHandler);
        
        // Prevent content clicks from closing
        const content = modal.querySelector('.variations-content');
        if (content) {
            content.addEventListener('click', function(e) {
                e.stopPropagation();
            });
        }
        
    } catch (error) {
        console.warn('🎵 Error parsing variations data:', error);
        alert('Error loading variations. Please refresh the page and try again.');
    }
}

// Populate variations grid
function populateVariationsGrid() {
    const grid = document.getElementById('variationsGrid');
    grid.innerHTML = '';
    
    window.trackVariations.forEach((variation, index) => {
        const card = document.createElement('div');
        card.className = `variation-card ${index === window.selectedVariationIndex ? 'selected' : ''}`;
        card.onclick = () => selectVariation(index);
        
        // Handle duration - check if it exists and is valid
        let duration = '0:00';
        if (variation.duration && variation.duration > 0) {
            const minutes = Math.floor(variation.duration / 60);
            const seconds = Math.floor(variation.duration % 60);
            duration = minutes + 'm ' + seconds + 's';
        } else if (variation.metadata) {
            // Try to get duration from metadata
            try {
                const meta = typeof variation.metadata === 'string' ? JSON.parse(variation.metadata) : variation.metadata;
                if (meta && meta.duration && meta.duration > 0) {
                    const minutes = Math.floor(meta.duration / 60);
                    const seconds = Math.floor(meta.duration % 60);
                    duration = minutes + 'm ' + seconds + 's';
                }
            } catch (e) {
                console.warn('Error parsing variation metadata for duration:', e);
            }
        }
        
        const tags = variation.tags ? variation.tags.split(',').slice(0, 3) : [];
        
        card.innerHTML = `
            <div class="variation-header">
                <div class="variation-title">${window.mainTrackTitle || 'Variation ' + (index + 1)}</div>
                <div class="variation-index">${index + 1}</div>
            </div>
            <div class="variation-duration">
                <i class="fas fa-clock"></i> ${duration}
            </div>
            ${tags.length > 0 ? `
                <div class="variation-tags">
                    ${tags.map(tag => `<span class="variation-tag">${tag.trim()}</span>`).join('')}
                </div>
            ` : ''}
            <div class="variation-actions">
                <button class="variation-btn play" onclick="playVariation(${index})">
                    <i class="fas fa-play"></i> ${libraryTranslations.play}
                </button>
                <button class="variation-btn download" onclick="downloadVariation(${index})">
                    <i class="fas fa-download"></i> ${libraryTranslations.download}
                </button>
                <button class="variation-btn select ${index === window.selectedVariationIndex ? 'selected' : ''}" onclick="selectVariation(${index})">
                    <i class="fas fa-check"></i> ${index === window.selectedVariationIndex ? libraryTranslations.selected : libraryTranslations.select}
                </button>
            </div>
        `;
        
        grid.appendChild(card);
    });
    
    // Update save button state
    updateSaveButton();
}

// Select variation
function selectVariation(index) {
    window.selectedVariationIndex = index;
    
    // Update visual selection
    document.querySelectorAll('.variation-card').forEach((card, i) => {
        card.classList.toggle('selected', i === index);
    });
    
    document.querySelectorAll('.variation-btn.select').forEach((btn, i) => {
        btn.classList.toggle('selected', i === index);
        btn.innerHTML = `<i class="fas fa-check"></i> ${i === index ? libraryTranslations.selected : libraryTranslations.select}`;
    });
    
    updateSaveButton();
}

// Play variation
async function playVariation(index) {
    const variation = window.trackVariations[index];
    if (!variation) return;
    
    console.log('🎵 Playing variation:', variation);
    
    // Wait for enhanced global player to be ready
    await waitForEnhancedPlayer();
    
    // Get signed URL from API to prevent URL sharing
    const variationIndex = variation.variation_index !== undefined ? variation.variation_index : index;
    
    try {
        const response = await fetch('/api/get_audio_token.php?track_id=' + window.currentTrackId + '&variation=' + variationIndex);
        const data = await response.json();
        
        if (!data.success || !data.url) {
            console.error('Failed to get signed audio URL:', data.error);
            showNotification(libraryTranslations.audio_not_available, 'error');
            return;
        }
        
        let finalAudioUrl = data.url;
        console.log('🎵 Using signed proxy URL for variation:', finalAudioUrl);
        
        // Use the enhanced global player (same as community.php)
        if (typeof window.enhancedGlobalPlayer !== 'undefined' && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
            console.log('🎵 Using enhanced global player for variation');
            const trackTitle = window.mainTrackTitle || variation.title || libraryTranslations.variation + ' ' + (index + 1);
            window.enhancedGlobalPlayer.playTrack(finalAudioUrl, trackTitle, '<?= htmlspecialchars($user_name) ?>');
        } else {
            console.warn('🎵 Enhanced global player not available for variation playback');
            alert('Audio player not available. Please refresh the page and try again.');
        }
    } catch (err) {
        console.error('Error getting audio token:', err);
        showNotification(libraryTranslations.audio_not_available, 'error');
    }
}

// Download variation
async function downloadVariation(index) {
    const variation = window.trackVariations[index];
    if (!variation) {
        console.error('🎵 Variation not found at index:', index);
        showNotification('Variation not found', 'error');
        return;
    }
    
    console.log('🎵 Downloading variation:', variation);
    
    // Get track information from modal or track card
    let trackTitle = 'Untitled Track';
    let artistName = '<?= htmlspecialchars($user_name) ?>';
    let genre = '';
    let bpm = '';
    let key = '';
    let numericalKey = '';
    let mood = '';
    
    // Try to get track info from the track card
    if (window.currentTrackId) {
        const trackCard = document.querySelector(`[data-track-id="${window.currentTrackId}"]`);
        if (trackCard) {
            const titleEl = trackCard.querySelector('.track-name');
            if (titleEl) trackTitle = titleEl.textContent.trim();
            
            const artistEl = trackCard.querySelector('.track-artist-name');
            if (artistEl) artistName = artistEl.textContent.replace('By ', '').trim();
            
            // Get metadata from track card data attribute if available
            const trackPrompt = trackCard.getAttribute('data-prompt') || '';
            
            // Try to extract numerical key from prompt (e.g., "Key: 6B – D Major")
            if (trackPrompt) {
                const keyMatch = trackPrompt.match(/key[:\s]+([0-9]+[A-G]?)\s*[–\-]?\s*/i);
                if (keyMatch && keyMatch[1]) {
                    numericalKey = keyMatch[1].trim();
                }
            }
            
            // Get metadata from displayed elements
            const metadataRow = trackCard.querySelector('.track-metadata-row');
            if (metadataRow) {
                const metaItems = metadataRow.querySelectorAll('.meta-item');
                metaItems.forEach(item => {
                    const text = item.textContent.trim();
                    if (text.includes('Genre:')) {
                        genre = text.replace('Genre:', '').trim();
                    } else if (text.includes('BPM:')) {
                        bpm = text.replace('BPM:', '').trim();
                    } else if (text.includes('Key:')) {
                        key = text.replace('Key:', '').trim();
                    } else if (text.includes('Mood:')) {
                        mood = text.replace('Mood:', '').trim();
                    }
                });
            }
        }
    }
    
    // Sanitize filename
    function sanitizeFilename(str) {
        return str.replace(/[<>:"/\\|?*]/g, '').replace(/\s+/g, ' ').trim();
    }
    
    // Create comprehensive filename
    const cleanTitle = sanitizeFilename(trackTitle);
    const cleanArtist = sanitizeFilename(artistName);
    const cleanGenre = sanitizeFilename(genre);
    const cleanKey = sanitizeFilename(key);
    const cleanMood = sanitizeFilename(mood);
    const cleanNumericalKey = sanitizeFilename(numericalKey);
    
    let filename = `${cleanArtist} - ${cleanTitle} (Variation ${index + 1})`;
    
    // Add metadata to filename
    const metadataParts = [];
    if (cleanGenre) metadataParts.push(cleanGenre);
    if (bpm) metadataParts.push(`${bpm} BPM`);
    // Add numerical key first if available, then the musical key
    if (cleanNumericalKey) metadataParts.push(cleanNumericalKey);
    if (cleanKey) metadataParts.push(cleanKey);
    if (cleanMood) metadataParts.push(cleanMood);
    
    if (metadataParts.length > 0) {
        filename += ` [${metadataParts.join(', ')}]`;
    }
    
    filename += '.mp3';
    
    // Show loading message
    const toast = document.createElement('div');
    toast.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: rgba(102, 126, 234, 0.9);
        color: white;
        padding: 1rem 1.5rem;
        border-radius: 8px;
        font-weight: 600;
        z-index: 10000;
        backdrop-filter: blur(10px);
    `;
    toast.textContent = `⏳ Preparing download: ${filename}`;
    document.body.appendChild(toast);
    
    try {
        // Get signed URL from API (same as play function)
        const variationIndex = variation.variation_index !== undefined ? variation.variation_index : index;
        const response = await fetch('/api/get_audio_token.php?track_id=' + window.currentTrackId + '&variation=' + variationIndex);
        const data = await response.json();
        
        if (!data.success || !data.url) {
            console.error('Failed to get signed audio URL:', data.error);
            toast.style.background = 'rgba(245, 101, 101, 0.9)';
            toast.textContent = '❌ Failed to get download URL';
            setTimeout(() => {
                if (toast.parentNode) {
                    document.body.removeChild(toast);
                }
            }, 3000);
            showNotification('Failed to prepare download. Please try again.', 'error');
            return;
        }
        
        const downloadUrl = data.url;
        console.log('🎵 Using signed proxy URL for download:', downloadUrl);
        
        // Create a temporary link element to trigger download
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = filename;
        link.target = '_blank';
        
        // Add to DOM, click, and remove
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        
        // Update toast to success
        toast.style.background = 'rgba(72, 187, 120, 0.9)';
        toast.textContent = `✅ Downloading: ${filename}`;
        
        setTimeout(() => {
            if (toast.parentNode) {
                document.body.removeChild(toast);
            }
        }, 3000);
        
    } catch (error) {
        console.error('🎵 Error downloading variation:', error);
        toast.style.background = 'rgba(245, 101, 101, 0.9)';
        toast.textContent = '❌ Download failed. Please try again.';
        setTimeout(() => {
            if (toast.parentNode) {
                document.body.removeChild(toast);
            }
        }, 3000);
        showNotification('Download failed. Please try again.', 'error');
    }
}

// Update save button state
function updateSaveButton() {
    const saveBtn = document.getElementById('saveVariationBtn');
    if (!saveBtn) {
        console.warn('🎵 Save button not found');
        return;
    }
    
    if (window.currentTrackId === null) {
        saveBtn.disabled = true;
        saveBtn.textContent = 'No Track Selected';
        return;
    }
    
    const trackCard = document.querySelector(`[data-track-id="${window.currentTrackId}"]`);
    if (!trackCard) {
        saveBtn.disabled = true;
        saveBtn.textContent = 'Track Not Found';
        return;
    }
    
    const currentSelection = trackCard.getAttribute('data-selected-variation') || '0';
    
    if (window.selectedVariationIndex !== parseInt(currentSelection)) {
        saveBtn.disabled = false;
        saveBtn.textContent = 'Save Selection';
    } else {
        saveBtn.disabled = true;
        saveBtn.textContent = 'No Changes';
    }
}

// Save variation selection
function saveVariationSelection() {
    if (window.selectedVariationIndex === null || window.currentTrackId === null) {
        console.warn('🎵 No variation or track selected');
        return;
    }
    
    console.log('🎵 Saving variation selection:', { trackId: window.currentTrackId, variationIndex: window.selectedVariationIndex });
    
    // Disable save button during request
    const saveBtn = document.getElementById('saveVariationBtn');
    saveBtn.disabled = true;
    saveBtn.textContent = 'Saving...';
    
    fetch('/api_select_variation.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            track_id: window.currentTrackId,
            variation_index: window.selectedVariationIndex
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('🎵 Variation selection saved:', data);
            
            // Update the track card
            const trackCard = document.querySelector(`[data-track-id="${window.currentTrackId}"]`);
            if (trackCard) {
                trackCard.setAttribute('data-selected-variation', window.selectedVariationIndex);
                
                // Update the main audio URL and duration
                const variation = window.trackVariations[window.selectedVariationIndex];
                if (variation) {
                    // Update play button with signed proxy URL
                    const playBtn = trackCard.querySelector('.play-track-btn');
                    if (playBtn) {
                        const variationIndex = variation.variation_index !== undefined ? variation.variation_index : window.selectedVariationIndex;
                        // Fetch signed URL asynchronously
                        fetch('/api/get_audio_token.php?track_id=' + window.currentTrackId + '&variation=' + variationIndex)
                            .then(r => r.json())
                            .then(tokenData => {
                                if (tokenData.success && tokenData.url) {
                                    playBtn.setAttribute('data-audio-url', tokenData.url);
                                }
                            })
                            .catch(err => console.error('Failed to get audio token:', err));
                    }
                    
                    // Update duration display
                    const durationSpan = trackCard.querySelector('.track-details span:first-child');
                    if (durationSpan) {
                        const duration = Math.floor(variation.duration / 60) + 'm ' + Math.floor(variation.duration % 60) + 's';
                        durationSpan.innerHTML = `<i class="fas fa-clock"></i> ${duration}`;
                    }
                }
            }
            
            // Show success message
            if (typeof window.showNotification === 'function') {
                window.showNotification('Variation selection saved successfully!', 'success');
            } else {
                alert('✅ Variation selection saved successfully!');
            }
            
            // Close modal
            closeVariations();
            
        } else {
            console.warn('🎵 Failed to save variation selection:', data.error);
            
            if (typeof window.showNotification === 'function') {
                window.showNotification('Failed to save variation selection: ' + (data.error || 'Unknown error'), 'error');
            } else {
                alert('❌ Failed to save variation selection: ' + (data.error || 'Unknown error'));
            }
        }
    })
    .catch(error => {
        console.warn('🎵 Error saving variation selection:', error);
        
        if (typeof window.showNotification === 'function') {
            window.showNotification('Network error saving selection. Please check your connection and try again.', 'error');
        } else {
            alert('❌ Network error saving selection. Please check your connection and try again.');
        }
    })
    .finally(() => {
        // Re-enable save button
        saveBtn.disabled = false;
        updateSaveButton();
    });
}

// Close variations modal
function closeVariations() {
    const modal = document.getElementById('variationsModal');
    if (!modal) return;
    
    // Remove active class
    modal.classList.remove('active');
    
    // Remove inline styles that were set in showVariations
    modal.style.display = 'none';
    modal.style.zIndex = '';
    modal.style.position = '';
    modal.style.top = '';
    modal.style.left = '';
    modal.style.width = '';
    modal.style.height = '';
    modal.style.alignItems = '';
    modal.style.justifyContent = '';
    
    // Reset variables
    window.trackVariations = [];
    window.currentTrackId = null;
    window.selectedVariationIndex = null;
    
    console.log('🎵 Variations modal closed');
}

// Show lyrics modal
function showLyrics(trackId) {
    console.log('🎵 Showing lyrics for track:', trackId);
    
    // Get track data
    const trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) {
        console.warn('🎵 Track card not found for track ID:', trackId);
        alert('Track not found. Please refresh the page and try again.');
        return;
    }
    
    console.log('🎵 Track card found:', trackCard);
    
    // Get track title
    const titleElement = trackCard.querySelector('.track-title-mini');
    const trackTitle = titleElement ? titleElement.textContent : 'Unknown Track';
    console.log('🎵 Track title:', trackTitle);
    
    // Show lyrics modal
    const modal = document.getElementById('lyricsModal');
    const lyricsContent = document.getElementById('lyricsContent');
    
    console.log('🎵 Modal element:', modal);
    console.log('🎵 Lyrics content element:', lyricsContent);
    
    if (!modal || !lyricsContent) {
        console.warn('🎵 Modal elements not found');
        alert('Modal not found. Please refresh the page and try again.');
        return;
    }
    
    // For now, show placeholder lyrics since lyrics functionality needs to be implemented
    lyricsContent.innerHTML = `
        <div style="text-align: center; padding: 2rem;">
            <i class="fas fa-music" style="font-size: 3rem; color: #667eea; margin-bottom: 1rem;"></i>
            <h3 style="color: #ffffff; margin-bottom: 1rem;">${trackTitle}</h3>
            <p style="color: #a0aec0; margin-bottom: 2rem;">🎵 Lyrics feature coming soon!</p>
            <div style="background: rgba(102, 126, 234, 0.1); padding: 1.5rem; border-radius: 8px; border: 1px solid rgba(102, 126, 234, 0.3);">
                <p style="color: #cccccc; font-style: italic;">
                    "This will show the AI-generated lyrics for your track.<br>
                    Stay tuned for this exciting feature!"
                </p>
            </div>
        </div>
    `;
    
    // Show modal
    modal.classList.add('active');
    console.log('🎵 Lyrics modal activated');
    
    // Force modal to be visible and on top
    modal.style.zIndex = '999999';
    modal.style.position = 'fixed';
    modal.style.top = '0';
    modal.style.left = '0';
    modal.style.width = '100%';
    modal.style.height = '100%';
    modal.style.display = 'flex';
    modal.style.alignItems = 'center';
    modal.style.justifyContent = 'center';
    
    console.log('🎵 Lyrics modal styles applied:', {
        zIndex: modal.style.zIndex,
        position: modal.style.position,
        display: modal.style.display
    });
    
    // Close on outside click
    modal.addEventListener('click', function(e) {
        if (e.target === this) {
            closeLyrics();
        }
    });
}

// Close lyrics modal
function closeLyrics() {
    const modal = document.getElementById('lyricsModal');
    modal.classList.remove('active');
}

// Copy lyrics to clipboard
function copyLyrics() {
    const lyricsContent = document.getElementById('lyricsContent');
    if (lyricsContent) {
        const text = lyricsContent.textContent || lyricsContent.innerText;
        navigator.clipboard.writeText(text).then(() => {
            alert('✅ Lyrics copied to clipboard!');
        }).catch(() => {
            alert('❌ Failed to copy lyrics. Please select and copy manually.');
        });
    }
}

// Download track
function downloadTrack(trackId) {
    console.log('🎵 Downloading track:', trackId);
    
    // Get track data
    const trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) {
        console.warn('🎵 Track card not found for track ID:', trackId);
        alert('Track not found. Please refresh the page and try again.');
        return;
    }
    
    // Show download modal
    const modal = document.getElementById('downloadModal');
    const downloadContent = document.getElementById('downloadContent');
    
    if (!modal || !downloadContent) {
        console.warn('🎵 Download modal elements not found');
        alert('Download modal not found. Please refresh the page and try again.');
        return;
    }
    
    // Get track title - use the correct class name from the track card
    const titleElement = trackCard.querySelector('.track-name');
    const trackTitle = titleElement ? titleElement.textContent.trim() : 'Unknown Track';
    
    // Populate download modal
    downloadContent.innerHTML = `
        <div style="text-align: center; padding: 2rem;">
            <i class="fas fa-download" style="font-size: 3rem; color: #667eea; margin-bottom: 1rem;"></i>
            <h3 style="color: #ffffff; margin-bottom: 1rem;">${trackTitle}</h3>
            <p style="color: #a0aec0; margin-bottom: 2rem;">Choose your download option:</p>
            <div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
                <button onclick="downloadSingleTrack(${trackId})" style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 1rem 2rem; border-radius: 8px; cursor: pointer; margin: 0.5rem;">
                    <i class="fas fa-music"></i> Download Track
                </button>
                <button onclick="downloadAllVariations(${trackId})" style="background: linear-gradient(135deg, #48bb78, #38a169); color: white; border: none; padding: 1rem 2rem; border-radius: 8px; cursor: pointer; margin: 0.5rem;">
                    <i class="fas fa-layer-group"></i> Download All Variations
                </button>
            </div>
        </div>
    `;
    
    // Show modal
    modal.classList.add('active');
    console.log('🎵 Download modal activated');
    
    // Add click outside to close
    modal.addEventListener('click', function(e) {
        if (e.target === this) {
            closeDownload();
        }
    });
    
    // Force modal to be visible and on top
    modal.style.zIndex = '999999';
    modal.style.position = 'fixed';
    modal.style.top = '0';
    modal.style.left = '0';
    modal.style.width = '100%';
    modal.style.height = '100%';
    modal.style.display = 'flex';
    modal.style.alignItems = 'center';
    modal.style.justifyContent = 'center';
}

    // Close download modal
    function closeDownload() {
        const modal = document.getElementById('downloadModal');
        if (modal) {
            modal.classList.remove('active');
            // Reset any forced styles
            modal.style.zIndex = '';
            modal.style.position = '';
            modal.style.top = '';
            modal.style.left = '';
            modal.style.width = '';
            modal.style.height = '';
            modal.style.display = '';
            modal.style.alignItems = '';
            modal.style.justifyContent = '';
        }
    }

// Download single track
function downloadSingleTrack(trackId) {
    const trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) return;
    
    // Get the play button which has the audio data
    const playBtn = trackCard.querySelector('.action-btn-compact.primary');
    if (!playBtn) {
        showNotification('❌ Play button not found. Please try again.', 'error');
        return;
    }
    
    const audioUrl = playBtn.getAttribute('data-audio-url');
    const title = playBtn.getAttribute('data-title');
    const artist = playBtn.getAttribute('data-artist');
    
    if (!audioUrl) {
        showNotification('❌ Audio URL not found. Please try again.', 'error');
        return;
    }
    
    // Create download link
    const link = document.createElement('a');
    link.href = audioUrl;
    link.download = `${artist} - ${title}.mp3`;
    link.target = '_blank';
    
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    
    // Show success message
    showNotification('✅ Track downloaded successfully!', 'success');
    closeDownload();
}

// Download all variations
function downloadAllVariations(trackId) {
    const trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
    if (!trackCard) {
        showNotification('❌ Track not found.', 'error');
        return;
    }
    
    const variationsData = trackCard.getAttribute('data-variations');
    if (!variationsData || variationsData === '[]') {
        showNotification('❌ No variations available for this track.', 'warning');
        return;
    }
    
    try {
        const variations = JSON.parse(variationsData);
        if (!Array.isArray(variations) || variations.length === 0) {
            showNotification('❌ No variations available for this track.', 'warning');
            return;
        }
        
        // Get track information from the card
        const trackTitleEl = trackCard.querySelector('.track-name');
        const trackTitle = trackTitleEl ? trackTitleEl.textContent.trim() : 'Untitled Track';
        
        const artistEl = trackCard.querySelector('.track-artist-name');
        const artistName = artistEl ? artistEl.textContent.replace('By ', '').trim() : '<?= htmlspecialchars($user_name) ?>';
        
        // Get metadata from the card
        const metadataRow = trackCard.querySelector('.track-metadata-row');
        let genre = 'Unknown';
        let bpm = '';
        let key = '';
        let numericalKey = '';
        let mood = '';
        
        // Try to get numerical key from prompt stored in data attribute
        const trackPrompt = trackCard.getAttribute('data-prompt') || '';
        if (trackPrompt) {
            const keyMatch = trackPrompt.match(/key[:\s]+([0-9]+[A-G]?)\s*[–\-]?\s*/i);
            if (keyMatch && keyMatch[1]) {
                numericalKey = keyMatch[1].trim();
            }
        }
        
        if (metadataRow) {
            const metaItems = metadataRow.querySelectorAll('.meta-item');
            metaItems.forEach(item => {
                const text = item.textContent.trim();
                if (text.includes('Genre:')) {
                    genre = text.replace('Genre:', '').trim();
                } else if (text.includes('BPM:')) {
                    bpm = text.replace('BPM:', '').trim();
                } else if (text.includes('Key:')) {
                    key = text.replace('Key:', '').trim();
                } else if (text.includes('Mood:')) {
                    mood = text.replace('Mood:', '').trim();
                }
            });
        }
        
        // Sanitize filename (remove invalid characters)
        function sanitizeFilename(str) {
            return str.replace(/[<>:"/\\|?*]/g, '').replace(/\s+/g, ' ').trim();
        }
        
        // Download each variation with descriptive filename
        variations.forEach((variation, index) => {
            setTimeout(() => {
                const link = document.createElement('a');
                link.href = variation.audio_url;
                
                // Create comprehensive filename with all metadata
                const variationNum = index + 1;
                const totalVariations = variations.length;
                const cleanTitle = sanitizeFilename(trackTitle);
                const cleanArtist = sanitizeFilename(artistName);
                const cleanGenre = sanitizeFilename(genre);
                const cleanKey = sanitizeFilename(key);
                const cleanMood = sanitizeFilename(mood);
                
                // Build filename: Artist - Title (Variation X of Y) [Genre, BPM, NumericalKey, Key, Mood].mp3
                let filename = `${cleanArtist} - ${cleanTitle}`;
                if (totalVariations > 1) {
                    filename += ` (Variation ${variationNum} of ${totalVariations})`;
                }
                
                // Add metadata to filename
                const metadataParts = [];
                if (cleanGenre && cleanGenre !== 'Unknown') metadataParts.push(cleanGenre);
                if (bpm) metadataParts.push(`${bpm} BPM`);
                // Add numerical key first if available, then the musical key
                if (cleanNumericalKey) metadataParts.push(cleanNumericalKey);
                if (cleanKey) metadataParts.push(cleanKey);
                if (cleanMood) metadataParts.push(cleanMood);
                
                if (metadataParts.length > 0) {
                    filename += ` [${metadataParts.join(', ')}]`;
                }
                
                filename += '.mp3';
                
                link.download = filename;
                link.target = '_blank';
                
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }, index * 500); // Stagger downloads
        });
        
        showNotification(`✅ Downloading ${variations.length} variation(s) with full metadata!`, 'success');
        closeDownload();
        
    } catch (error) {
        console.warn('Error downloading variations:', error);
        showNotification('❌ Error downloading variations. Please try again.', 'error');
    }
}

// Genre expansion toggle function
function toggleGenreExpansion(button, hiddenGenres) {
    const trackCard = button.closest('.track-card');
    const expandedGenres = trackCard.querySelector('.expanded-genres');
    
    if (expandedGenres.style.display === 'none') {
        // Show expanded genres
        expandedGenres.style.display = 'flex';
        button.textContent = 'Show less';
        button.classList.add('expanded');
    } else {
        // Hide expanded genres
        expandedGenres.style.display = 'none';
        button.textContent = `+${hiddenGenres.length} more`;
        button.classList.remove('expanded');
    }
}

// Update currently playing track
function updateCurrentlyPlaying(trackId) {
    // Remove currently playing class from all tracks
    document.querySelectorAll('.track-card').forEach(card => {
        card.classList.remove('currently-playing', 'playing');
    });
    
    // Reset all play buttons to play state
    document.querySelectorAll('.play-btn-large, .play-track-btn, .action-btn.play-btn, .action-btn-compact.primary').forEach(btn => {
        btn.classList.remove('playing');
        const icon = btn.querySelector('i');
        if (icon) {
            icon.className = 'fas fa-play';
        }
        // Update button text if it has a span
        const span = btn.querySelector('span');
        if (span && span.textContent.includes('Playing')) {
            span.textContent = 'Play';
        }
    });
    
    // Add currently playing class to the current track and update its button
    if (trackId) {
        const currentCard = document.querySelector(`[data-track-id="${trackId}"]`);
        if (currentCard) {
            currentCard.classList.add('currently-playing', 'playing');
            
            // Update play-btn-large button
            const playBtnLarge = currentCard.querySelector('.play-btn-large');
            if (playBtnLarge) {
                playBtnLarge.classList.add('playing');
                const icon = playBtnLarge.querySelector('i');
                if (icon) {
                    icon.className = 'fas fa-pause';
                }
            }
            
            // Update play-track-btn button
            const playTrackBtn = currentCard.querySelector('.play-track-btn');
            if (playTrackBtn) {
                playTrackBtn.classList.add('playing');
                const icon = playTrackBtn.querySelector('i');
                if (icon) {
                    icon.className = 'fas fa-pause';
                }
                const span = playTrackBtn.querySelector('span');
                if (span) {
                    span.textContent = 'Playing';
                } else if (playTrackBtn.innerHTML.includes('<i')) {
                    playTrackBtn.innerHTML = '<i class="fas fa-pause"></i> <span>Playing</span>';
                }
            }
            
            // Update compact play button
            const compactPlayBtn = currentCard.querySelector('.action-btn.play-btn, .action-btn-compact.primary');
            if (compactPlayBtn) {
                compactPlayBtn.classList.add('playing');
                const icon = compactPlayBtn.querySelector('i');
                if (icon) {
                    icon.className = 'fas fa-pause';
                }
            }
        }
    }
}

// Build library playlist from all visible tracks
function buildLibraryPlaylist() {
    const playlist = [];
    document.querySelectorAll('.play-btn-large[data-track-id]').forEach(btn => {
        const trackId = btn.getAttribute('data-track-id');
        const audioUrl = btn.getAttribute('data-audio-url');
        const title = btn.getAttribute('data-title') || 'Untitled';
        const artist = btn.getAttribute('data-artist') || 'Unknown Artist';
        
        if (trackId && audioUrl) {
            playlist.push({
                id: parseInt(trackId),
                audio_url: audioUrl,
                title: title,
                artist_name: artist,
                user_id: null // Library tracks belong to current user
            });
        }
    });
    console.log('🎵 Library: Built playlist with', playlist.length, 'tracks');
    return playlist;
}

// Enhanced play track function with playing state AND playlist support
async function playTrackFromButton(audioUrl, title, artist) {
    console.log('🎵 Library: playTrackFromButton called with:', { audioUrl, title, artist });
    
    if (!audioUrl) {
        console.warn('No audio URL provided');
        return;
    }
    
    // Wait for enhanced global player to be ready
    await waitForEnhancedPlayer();
    
    // Get track ID and button element
    const trackId = getTrackIdFromAudioUrl(audioUrl);
    const button = document.querySelector(`[data-audio-url="${audioUrl}"]`);
    const isCurrentlyPlaying = button && button.classList.contains('playing');
    
    // Check if this track is currently playing - if so, pause it
    if (isCurrentlyPlaying) {
        // Check if global player is actually playing by checking the audio element
        const globalPlayer = window.enhancedGlobalPlayer;
        if (globalPlayer && typeof globalPlayer.togglePlayPause === 'function') {
            // Get the audio element from the global player
            const audioElement = document.getElementById('globalAudioElement');
            if (audioElement && !audioElement.paused && audioElement.src) {
                // Check if it's the same track by comparing track IDs (signed URLs have unique tokens)
                const getTrackIdFromUrl = (url) => {
                    if (!url) return null;
                    const match = url.match(/[?&]id=(\d+)/);
                    return match ? match[1] : null;
                };
                const currentTrackId = getTrackIdFromUrl(audioElement.src);
                const clickedTrackId = trackId || getTrackIdFromUrl(audioUrl);
                
                if (currentTrackId && clickedTrackId && currentTrackId === clickedTrackId) {
                    // Same track is playing - pause it
                    console.log('🎵 Library: Pausing current track');
                    globalPlayer.togglePlayPause();
                    
                    // Update button to play state
                    if (button) {
                        button.classList.remove('playing');
                        const icon = button.querySelector('i');
                        if (icon) {
                            icon.className = 'fas fa-play';
                        }
                    }
                    
                    // Remove playing states from all tracks
                    document.querySelectorAll('.track-card').forEach(card => {
                        card.classList.remove('currently-playing', 'playing');
                    });
                    
                    showNotification('⏸️ Paused', 'success');
                    return;
                }
            }
        }
    }
    
    // Use the enhanced global player (same as community.php)
    if (typeof window.enhancedGlobalPlayer !== 'undefined' && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
        
        // BUILD AND SET THE PLAYLIST for continuous playback
        const libraryPlaylist = buildLibraryPlaylist();
        if (libraryPlaylist.length > 0) {
            // Find the index of the current track
            const clickedTrackId = parseInt(trackId) || parseInt(getTrackIdFromAudioUrl(audioUrl));
            const trackIndex = libraryPlaylist.findIndex(t => t.id === clickedTrackId);
            const startIndex = trackIndex !== -1 ? trackIndex : 0;
            
            // Use loadPagePlaylist like artist_profile does - direct function that sets closure vars
            if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                window.enhancedGlobalPlayer.loadPagePlaylist(libraryPlaylist, 'library', startIndex);
                console.log('🎵 Library: Playlist loaded via loadPagePlaylist, index:', startIndex, 'of', libraryPlaylist.length);
            } else {
                // Fallback to window storage
                window._communityPlaylist = libraryPlaylist;
                window._communityPlaylistType = 'library';
                window._communityTrackIndex = startIndex;
                console.log('🎵 Library: Playlist stored on window, index:', startIndex, 'of', libraryPlaylist.length);
            }
        }
        
        // Now play the track
        window.enhancedGlobalPlayer.playTrack(audioUrl, title, artist);
        
        // Update currently playing state
        console.log('🎵 Library: Track ID for playing state:', trackId);
        updateCurrentlyPlaying(trackId);
        
        console.log('🎵 Library: Track sent via enhancedGlobalPlayer -', title, '(playlist:', libraryPlaylist.length, 'tracks)');
    } else {
        console.error('Enhanced global player not available');
        alert('Audio player not available. Please refresh the page and try again.');
    }
}

// Get track ID from audio URL
function getTrackIdFromAudioUrl(audioUrl) {
    // Find the button with this audio URL and get its track ID directly
    const button = document.querySelector(`[data-audio-url="${audioUrl}"]`);
    if (button) {
        return button.getAttribute('data-track-id');
    }
    return null;
}

// Toggle generation parameters visibility
function toggleGenerationParams(header) {
    const paramsGrid = header.nextElementSibling;
    const toggleIcon = header.querySelector('.toggle-icon');
    
    if (paramsGrid.style.display === 'none') {
        paramsGrid.style.display = 'grid';
        toggleIcon.classList.remove('fa-chevron-down');
        toggleIcon.classList.add('fa-chevron-up');
    } else {
        paramsGrid.style.display = 'none';
        toggleIcon.classList.remove('fa-chevron-up');
        toggleIcon.classList.add('fa-chevron-down');
    }
}

// Play track from waveform (like community_fixed.php)
function playTrackFromWaveform(trackId, audioUrl, title, artist) {
    console.log('🎵 Library: playTrackFromWaveform called with:', { trackId, audioUrl, title, artist });
    playTrackFromButton(audioUrl, title, artist);
}

// Wait for enhanced global player to be ready
function waitForEnhancedPlayer() {
    return new Promise((resolve) => {
        if (window.enhancedGlobalPlayer) {
            resolve();
        } else {
            const checkPlayer = () => {
                if (window.enhancedGlobalPlayer) {
                    resolve();
                } else {
                    setTimeout(checkPlayer, 100);
                }
            };
            checkPlayer();
        }
    });
}



// Other library functions
async function playTrackFromButtonElement(button) {
    const audioUrl = button.getAttribute('data-audio-url');
    const title = button.getAttribute('data-title');
    const artist = button.getAttribute('data-artist');
    
    if (!audioUrl) {
        showNotification('❌ Audio URL not found. Please try again.', 'error');
        return;
    }
    
    // Wait for enhanced global player to be ready
    await waitForEnhancedPlayer();
    
    // Ensure audio URL is absolute if it's relative
    let finalAudioUrl = audioUrl;
    if (audioUrl && !audioUrl.startsWith('http') && !audioUrl.startsWith('//')) {
        if (audioUrl.startsWith('/')) {
            finalAudioUrl = window.location.origin + audioUrl;
        } else {
            finalAudioUrl = window.location.origin + '/' + audioUrl;
        }
        console.log('🎵 Converted relative URL to absolute:', finalAudioUrl);
    }
    
    if (!finalAudioUrl || finalAudioUrl.trim() === '') {
        console.error('❌ Audio URL is empty!');
        showNotification('Audio file not available.', 'error');
        return;
    }
    
    // Use the enhanced global player (same as community.php)
    if (typeof window.enhancedGlobalPlayer !== 'undefined' && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
        window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist);
        console.log('🎵 Library: Track sent via enhancedGlobalPlayer -', title);
    } else {
        console.warn('Enhanced global player not available');
        alert('Audio player not available. Please refresh the page and try again.');
    }
}

// Track status monitoring system
let statusCheckInterval = null;
let processingTrackIds = [];

// Initialize status checking for processing tracks
function initStatusChecking() {
    // Find all processing tracks on the page - try multiple selectors
    let processingTracks = document.querySelectorAll('.track-card-modern[data-status="processing"]');
    
    // If no tracks found, try alternative selectors
    if (processingTracks.length === 0) {
        processingTracks = document.querySelectorAll('[data-status="processing"]');
    }
    
    processingTrackIds = Array.from(processingTracks)
        .map(track => track.getAttribute('data-track-id'))
        .filter(id => id !== null && id !== '');
    
    if (processingTrackIds.length > 0) {
        console.log('🎵 Found', processingTrackIds.length, 'processing tracks, starting status monitoring...');
        
        // Check immediately
        checkAllTrackStatuses();
        
        // Then check every 10 seconds (optimized for performance)
        // Only check when page is visible
        if (statusCheckInterval) {
            clearInterval(statusCheckInterval);
        }
        statusCheckInterval = setInterval(function() {
            if (!document.hidden && processingTrackIds.length > 0) {
                checkAllTrackStatuses();
            }
        }, 10000); // Increased from 5 to 10 seconds for better performance
    } else {
        // No processing tracks, stop checking
        if (statusCheckInterval) {
            clearInterval(statusCheckInterval);
            statusCheckInterval = null;
        }
    }
}

// Check all processing tracks
async function checkAllTrackStatuses() {
    if (processingTrackIds.length === 0) {
        initStatusChecking(); // Refresh the list
        return;
    }
    
    console.log('🔍 Checking status for', processingTrackIds.length, 'tracks...');
    
    // Check each processing track
    for (const trackId of processingTrackIds) {
        await checkTrackStatus(trackId);
        // Small delay to avoid overwhelming the server
        await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    // Update stats after checking
    updateStatsBar();
}

// Check individual track status
async function checkTrackStatus(trackId) {
    try {
        // Get track card first to check creation time
        let trackCard = document.querySelector(`.track-card-modern[data-track-id="${trackId}"]`);
        if (!trackCard) {
            trackCard = document.querySelector(`[data-track-id="${trackId}"]`);
        }
        if (!trackCard) {
            console.warn(`Track card not found for track ${trackId}`);
            // Even if card not found, still check API status to update database
            const response = await fetch(`/api/check_track_status.php?track_id=${trackId}&force_check=1`);
            const data = await response.json();
            if (data.success && data.data && data.data.status !== 'processing') {
                console.log(`✅ Track ${trackId} status updated in database: ${data.data.status}`);
            }
            return;
        }
        
        // Check if track has been processing for more than 5 minutes
        const trackCreated = trackCard.getAttribute('data-created-at');
        if (trackCreated) {
            const createdTime = new Date(trackCreated).getTime();
            const now = Date.now();
            const processingTime = (now - createdTime) / 1000 / 60; // minutes
            
            if (processingTime > 5) {
                // Track has been processing for more than 5 minutes - check API status
                console.log(`⏱️ Track ${trackId} has been processing for ${processingTime.toFixed(1)} minutes - checking API status...`);
                
                // Call API to check status
                const response = await fetch(`/api/check_track_status.php?track_id=${trackId}&force_check=1`);
                const data = await response.json();
        
                if (data.success && data.data) {
                    const newStatus = data.data.status;
                    
                    // If still processing after 5+ minutes, mark as failed
                    if (newStatus === 'processing') {
                        console.log(`⚠️ Track ${trackId} still processing after ${processingTime.toFixed(1)} minutes - marking as failed`);
                        
                        // Mark as failed via API
                        await fetch(`/api/mark_track_failed.php?track_id=${trackId}`, {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' }
                        }).catch(err => console.error('Error marking track as failed:', err));
                        
                        // Update UI immediately
                        updateTrackCardStatus(trackCard, 'failed', {
                            id: trackId,
                            error_message: 'Track generation timed out after 5 minutes. Please try again.'
                        });
                        
                        processingTrackIds = processingTrackIds.filter(id => id !== trackId);
                        return;
                    }
                }
            }
        }
        
        // Normal status check - always force check service for processing tracks
        const response = await fetch(`/api/check_track_status.php?track_id=${trackId}&force_check=1`);
        const data = await response.json();
        
        if (data.success && data.data) {
            const currentStatus = trackCard.getAttribute('data-status');
            const newStatus = data.data.status;
            
            // If status changed, update the UI
            if (newStatus && newStatus !== currentStatus) {
                console.log(`✅ Track ${trackId} status changed: ${currentStatus} → ${newStatus}`);
                updateTrackCardStatus(trackCard, newStatus, data.data);
                
                // Remove from processing list if no longer processing
                if (newStatus !== 'processing') {
                    processingTrackIds = processingTrackIds.filter(id => id !== trackId);
                }
            } else if (newStatus === 'complete' && currentStatus === 'processing') {
                // Force update if API says complete but UI still shows processing
                console.log(`🔧 Force updating track ${trackId} from processing to complete`);
                updateTrackCardStatus(trackCard, 'complete', data.data);
                processingTrackIds = processingTrackIds.filter(id => id !== trackId);
            } else if (newStatus === 'failed' && currentStatus === 'processing') {
                // Force update if API says failed but UI still shows processing
                console.log(`🔧 Force updating track ${trackId} from processing to failed`);
                updateTrackCardStatus(trackCard, 'failed', data.data);
                processingTrackIds = processingTrackIds.filter(id => id !== trackId);
            }
        }
    } catch (error) {
        console.error('Error checking track status:', error);
    }
}

// Update track card UI when status changes
async function updateTrackCardStatus(trackCard, newStatus, trackData) {
    // Update data attribute
    trackCard.setAttribute('data-status', newStatus);
    
    // Remove processing indicator if it exists (when transitioning from processing to complete)
    const processingIndicator = trackCard.querySelector('.processing-indicator-modern');
    if (processingIndicator) {
        processingIndicator.remove();
    }
    
    // Get the actions row
    const actionsRow = trackCard.querySelector('.track-actions-row');
    if (!actionsRow) return;
    
    // Clear current content
    actionsRow.innerHTML = '';
    
    if (newStatus === 'complete') {
        // Get signed URL from API
        let proxyAudioUrl = '';
        try {
            const response = await fetch('/api/get_audio_token.php?track_id=' + trackData.id);
            const tokenData = await response.json();
            if (tokenData.success && tokenData.url) {
                proxyAudioUrl = tokenData.url;
            }
        } catch (err) {
            console.error('Failed to get audio token:', err);
        }
        
        const title = trackData.title || 'Untitled Track';
        const artist = trackCard.querySelector('.track-artist-name')?.textContent.replace('By ', '') || 'Unknown';
        
        actionsRow.innerHTML = `
            <button class="play-btn-large" onclick="playTrackFromButton('${proxyAudioUrl}', '${title.replace(/'/g, "\\'")}', '${artist.replace(/'/g, "\\'")}')" 
                    data-audio-url="${proxyAudioUrl}" 
                    data-title="${title.replace(/'/g, "\\'")}" 
                    data-artist="${artist.replace(/'/g, "\\'")}"
                    data-track-id="${trackData.id}"
                    title="Play Track">
                <i class="fas fa-play"></i>
            </button>
            <button class="action-icon-btn" onclick="shareTrack(${trackData.id})" title="<?= addslashes(t('artist_profile.share_track')) ?>">
                <i class="fas fa-share-alt"></i>
            </button>
            <button class="action-icon-btn ${trackData.user_liked ? 'liked' : ''}" onclick="toggleLike(${trackData.id}, this)" title="<?= addslashes(t('artist_profile.like')) ?>">
                <i class="fas fa-heart"></i>
            </button>
            <button class="action-icon-btn edit-track-btn" 
                    data-track-id="${trackData.id}"
                    data-track-title="${(trackData.title || 'Untitled Track').replace(/"/g, '&quot;')}"
                    data-track-prompt="${(trackData.prompt || '').replace(/"/g, '&quot;')}"
                    data-track-price="${trackData.price || 0}"
                    data-track-public="${trackData.is_public || 0}"
                    title="Edit Track">
                <i class="fas fa-edit"></i>
            </button>
        `;
        
        // Show notification
        showNotification(`🎵 "${title}" is ready to play!`, 'success');
        
    } else if (newStatus === 'failed') {
        // Show failed actions (Retry and Delete buttons)
        const trackId = trackData.id || trackCard.getAttribute('data-track-id');
        
        // Extract error message from trackData
        let errorMsg = trackData.error_message || 'Track generation failed. Please try again.';
        
        // Try to extract from metadata if error_message not directly available
        if (!trackData.error_message && trackData.metadata) {
            try {
                const metadata = typeof trackData.metadata === 'string' 
                    ? JSON.parse(trackData.metadata) 
                    : trackData.metadata;
                const rawMsg = metadata.msg || 
                          metadata.error || 
                          metadata.error_msg || 
                          metadata.message || 
                          null;
                
                if (rawMsg) {
                    // Check if this is actually a success message (not an error)
                    const isSuccessMessage = /\b(successfully|success|complete|done|ready|finished)\b/i.test(rawMsg);
                    
                    // Only treat as error if it's NOT a success message
                    if (!isSuccessMessage) {
                        errorMsg = rawMsg;
                    }
                }
            } catch (e) {
                console.warn('Could not parse metadata for error message:', e);
            }
        }
        
        // Sanitize error message - ONLY remove API.Box references, keep the exact error message
        errorMsg = errorMsg.replace(/\b(API\.Box|api\.box|API\.box|not found on API\.Box|not found in API\.Box|Task not found in API\.Box|Track.*not found on API\.Box)\b/gi, '');
        errorMsg = errorMsg.trim();
        // Clean up multiple spaces
        errorMsg = errorMsg.replace(/\s+/g, ' ');
        if (!errorMsg) {
            errorMsg = 'Track generation failed. Please try again.';
        }
        
        actionsRow.innerHTML = `
            <div class="failed-actions-modern" style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
                <button class="action-btn primary" onclick="retryTrack(${trackId})" title="Create a new version with the same prompt" style="padding: 0.5rem 1rem; background: #667eea; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                    <i class="fas fa-redo"></i>
                    Retry
                </button>
                <button class="action-btn danger" onclick="deleteFailedTrack(${trackId})" title="Delete this failed track" style="padding: 0.5rem 1rem; background: #ef4444; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 0.9rem;">
                    <i class="fas fa-trash"></i>
                    Delete
                </button>
            </div>
        `;
        
        // Remove any existing error message div
        const existingError = trackCard.querySelector('.error-message-modern');
        if (existingError) {
            existingError.remove();
        }
        
        // Add error message display below actions
        const errorDiv = document.createElement('div');
        errorDiv.className = 'error-message-modern';
        errorDiv.style.cssText = 'padding: 1rem; margin-top: 1rem; background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3); border-radius: 8px; color: #ef4444;';
        errorDiv.innerHTML = `
            <div style="display: flex; align-items: start; gap: 0.5rem;">
                <i class="fas fa-exclamation-triangle"></i>
                <div>
                    <strong>Error:</strong> ${escapeHtml(errorMsg)}
                </div>
            </div>
        `;
        actionsRow.parentNode.insertBefore(errorDiv, actionsRow.nextSibling);
        
        showNotification(`❌ Track generation failed: ${errorMsg}`, 'error');
    }
    
    // Update stats
    updateStatsBar();
}

// Update stats bar with current counts
async function updateStatsBar() {
    try {
        const response = await fetch('/api/get_user_stats.php');
        const data = await response.json();
        
        if (data.success && data.data) {
            const stats = data.data;
            
            // Update stat numbers - be careful with selectors!
            // Stat card order: 1=Total Tracks, 2=Total Minutes, 3=Credits, 4=Creator Level
            const totalTracksEl = document.querySelector('.stat-card:nth-child(1) .stat-number');
            // Don't update total minutes (2nd card) - it's calculated from duration
            const creditsEl = document.querySelector('.stat-card:nth-child(3) .stat-number');
            
            if (totalTracksEl) totalTracksEl.textContent = stats.total_tracks || 0;
            // Update credits from API (which gets fresh from database)
            if (creditsEl && stats.credits !== undefined) {
                creditsEl.textContent = stats.credits;
            }
            // Don't update processing_tracks - that was overwriting credits before!
        }
    } catch (error) {
        console.error('Error updating stats bar:', error);
    }
}

function retryTrack(trackId) {
    if (!confirm('Retry this track? This will use 1 credit and create a new version with the same prompt.')) {
        return;
    }
    
    console.log('Retrying track:', trackId);
    
    fetch(`/api/retry_track.php?track_id=${trackId}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                showNotification('✅ Track retry started! Status updated to processing.', 'success');
                // Reload page after a short delay to show updated status
                setTimeout(() => {
                    window.location.reload();
                }, 1500);
            } else {
                showNotification('❌ ' + (data.message || 'Failed to retry track'), 'error');
            }
        })
        .catch(error => {
            console.error('Error retrying track:', error);
            showNotification('❌ Error retrying track. Please try again.', 'error');
        });
}

function deleteFailedTrack(trackId) {
    if (!confirm('Are you sure you want to delete this failed track? This action cannot be undone.')) {
        return;
    }
    
    console.log('Deleting failed track:', trackId);
    
    // Disable the button to prevent double-clicks
    const deleteBtn = document.querySelector(`button[onclick*="deleteFailedTrack(${trackId})"]`);
    let originalContent = null;
    if (deleteBtn) {
        deleteBtn.disabled = true;
        originalContent = deleteBtn.innerHTML;
        deleteBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Deleting...';
    }
    
    fetch(`/api/delete_track.php?track_id=${trackId}`)
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            if (data.success) {
                // Clean up notified track IDs for this deleted track
                if (window.trackMonitor && window.trackMonitor.notifiedTrackIds) {
                    window.trackMonitor.notifiedTrackIds.delete(`failed_${trackId}`);
                    window.trackMonitor.notifiedTrackIds.delete(`fixed_${trackId}`);
                    if (window.trackMonitor.saveNotifiedTrackIds) {
                        window.trackMonitor.saveNotifiedTrackIds();
                    }
                    console.log(`🎵 Removed track ${trackId} from notified track IDs`);
                }
                
                if (typeof showNotification === 'function') {
                    showNotification('✅ Track deleted successfully', 'success');
                }
                // Remove the track card from the page - use more specific selector
                const trackCard = document.querySelector(`.track-card-modern[data-track-id="${trackId}"]`) || 
                                 document.querySelector(`[data-track-id="${trackId}"]`) || 
                                 document.querySelector(`.track-card[data-id="${trackId}"]`) ||
                                 document.querySelector(`.track-item[data-track-id="${trackId}"]`);
                if (trackCard) {
                    trackCard.style.transition = 'opacity 0.3s';
                    trackCard.style.opacity = '0';
                    setTimeout(() => {
                        trackCard.remove();
                        // Reload if no tracks left or update stats
                        if (typeof updateStatsBar === 'function') {
                            updateStatsBar();
                        }
                    }, 300);
                } else {
                    // If we can't find the element, just reload
                    setTimeout(() => {
                        window.location.reload();
                    }, 1000);
                }
            } else {
                if (typeof showNotification === 'function') {
                    showNotification('❌ ' + (data.message || 'Failed to delete track'), 'error');
                }
                // Re-enable button on error
                if (deleteBtn && originalContent) {
                    deleteBtn.disabled = false;
                    deleteBtn.innerHTML = originalContent;
                }
            }
        })
        .catch(error => {
            console.error('Error deleting track:', error);
            if (typeof showNotification === 'function') {
                showNotification('❌ Error deleting track. Please try again.', 'error');
            }
            // Re-enable button on error
            if (deleteBtn && originalContent) {
                deleteBtn.disabled = false;
                deleteBtn.innerHTML = originalContent;
            }
        });
}

// Initialize enhanced global player integration
document.addEventListener('DOMContentLoaded', function() {
    console.log('🎵 Library page loaded, initializing enhanced global player...');
    
    // Wait for enhanced global player to be ready
    waitForEnhancedPlayer().then(() => {
        console.log('🎵 Enhanced global player ready for library page');
        
        // Test enhanced global player functions
        console.log('🎵 Available enhanced global player functions:', {
            enhancedGlobalPlayer: typeof window.enhancedGlobalPlayer,
            playTrack: typeof window.enhancedGlobalPlayer?.playTrack
        });
        
    }).catch(error => {
        console.warn('🎵 Enhanced global player initialization error:', error);
    });
    
    // Initialize status checking for processing tracks
    initStatusChecking();
    
    // Enhanced filter handling
    const filterSelects = document.querySelectorAll('select[name="sort"], select[name="time"], select[name="genre"], select[name="status"]');
    filterSelects.forEach(select => {
        select.addEventListener('change', function() {
            applyFilters();
        });
    });
    
    // Search input with debounce
    const searchInput = document.getElementById('trackSearch');
    let searchTimeout;
    if (searchInput) {
        searchInput.addEventListener('input', function() {
            clearTimeout(searchTimeout);
            searchTimeout = setTimeout(() => {
                applyFilters();
            }, 500); // Wait 500ms after user stops typing
        });
        
        // Also trigger on Enter key
        searchInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault(); // Prevent form submission
                clearTimeout(searchTimeout);
                applyFilters();
            }
        });
        
        // Also prevent form submit on the input
        searchInput.addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
            }
        });
    }
    
    // Function to apply all filters
    function applyFilters() {
            const url = new URL(window.location);
            const params = new URLSearchParams(url.search);
            
        // Get all filter values
        const status = document.querySelector('select[name="status"]')?.value || 'all';
        const sort = document.querySelector('select[name="sort"]')?.value || 'latest';
        const time = document.querySelector('select[name="time"]')?.value || 'all';
        const genre = document.querySelector('select[name="genre"]')?.value || '';
        const search = document.getElementById('trackSearch')?.value.trim() || '';
        
        // Update parameters
        if (status !== 'all') {
            params.set('status', status);
        } else {
            params.delete('status');
        }
        
        if (sort !== 'latest') {
            params.set('sort', sort);
        } else {
            params.delete('sort');
        }
        
        if (time !== 'all') {
            params.set('time', time);
        } else {
            params.delete('time');
        }
        
        if (genre) {
            params.set('genre', genre);
        } else {
            params.delete('genre');
        }
        
        if (search) {
            params.set('search', search);
        } else {
            params.delete('search');
        }
            
            // Reset to page 1 when filters change
            params.delete('page');
            
        // Navigate to new URL with filters
        window.location.search = params.toString();
    }
    
            // Close modal when clicking outside
        const modal = document.getElementById('variationsModal');
        if (modal) {
            modal.addEventListener('click', function(e) {
                if (e.target === this) {
                    closeVariations();
                }
            });
        }
        
        // All tracks loaded at once - no pagination needed
        console.log('🎵 All tracks loaded - infinite scroll not needed');
    });
</script>

    <!-- Track Edit Modal -->
    <div id="editTrackModal" class="modal">
        <div class="modal-content">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2><?= t('library.edit.title') ?></h2>
                <button onclick="closeEditModal()" class="btn">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <form method="POST" id="editTrackForm">
                <input type="hidden" name="action" value="update_track">
                <input type="hidden" name="csrf_token" value="<?= htmlspecialchars(generateCSRFToken(), ENT_QUOTES, 'UTF-8') ?>">
                <input type="hidden" name="track_id" id="editTrackId">
                
                <div class="form-group">
                    <label class="form-label"><?= t('library.edit.track_title') ?></label>
                    <input type="text" name="title" id="editTitle" class="form-input" required>
                </div>
                
                <div class="form-group">
                    <label class="form-label"><?= t('library.edit.original_prompt') ?></label>
                    <textarea name="description" id="editDescription" class="form-input" rows="5" placeholder="<?= htmlspecialchars(t('library.edit.prompt_placeholder')) ?>"></textarea>
                </div>
                
                <div class="form-group">
                    <label class="form-label"><?= t('library.edit.price') ?></label>
                    <select name="price" id="editPrice" class="form-input">
                        <option value="0.00"><?= t('library.edit.price_free') ?></option>
                        <option value="0.99">$0.99</option>
                        <option value="1.99">$1.99</option>
                        <option value="2.99">$2.99</option>
                    </select>
                    <small class="form-hint"><?= t('library.edit.price_hint') ?></small>
                </div>
                
                <div class="form-group">
                    <label class="form-label">
                        <input type="checkbox" name="is_public" id="editIsPublic">
                        <?= t('library.edit.make_public') ?>
                    </label>
                    <small class="form-hint"><?= t('library.edit.public_hint') ?></small>
                </div>
                
                <div class="form-actions">
                    <button type="submit" class="btn btn-primary"><?= t('library.edit.update_track') ?></button>
                    <button type="button" onclick="closeEditModal()" class="btn"><?= t('library.edit.cancel') ?></button>
                </div>
            </form>
        </div>
    </div>

    <script>
        function editTrack(trackId, title, description, price, isPublic) {
            const modal = document.getElementById('editTrackModal');
            if (!modal) {
                console.error('Edit modal not found');
                alert('Edit modal not found. Please refresh the page.');
                return;
            }
            
            document.getElementById('editTrackId').value = trackId;
            document.getElementById('editTitle').value = title;
            document.getElementById('editDescription').value = description || '';
            
            // Set price dropdown - match to nearest tier
            const priceSelect = document.getElementById('editPrice');
            const priceVal = parseFloat(price) || 0;
            const priceTiers = ['0.00', '0.99', '1.99', '2.99'];
            let selectedTier = '0.00';
            for (const tier of priceTiers) {
                if (Math.abs(priceVal - parseFloat(tier)) < 0.01) {
                    selectedTier = tier;
                    break;
                }
            }
            priceSelect.value = selectedTier;
            
            document.getElementById('editIsPublic').checked = isPublic == 1;
            
            // Override the !important rule by setting style directly with important
            modal.style.setProperty('display', 'flex', 'important');
            modal.style.setProperty('z-index', '10000', 'important');
        }

        function closeEditModal() {
            const modal = document.getElementById('editTrackModal');
            if (modal) {
                modal.style.setProperty('display', 'none', 'important');
            }
        }

        // Ensure modal is hidden on page load and set up click outside handler
        document.addEventListener('DOMContentLoaded', function() {
            const editModal = document.getElementById('editTrackModal');
            if (editModal) {
                // Force hide on page load
                editModal.style.setProperty('display', 'none', 'important');

        // Close modal when clicking outside
                editModal.addEventListener('click', function(event) {
                    if (event.target === editModal) {
                closeEditModal();
            }
                });
            }
            
            // Set up event listeners for edit buttons using data attributes
            // This handles both existing buttons and dynamically added ones
            function setupEditButtons() {
                document.querySelectorAll('.edit-track-btn').forEach(button => {
                    // Remove existing listeners to avoid duplicates
                    const newButton = button.cloneNode(true);
                    button.parentNode.replaceChild(newButton, button);
                    
                    newButton.addEventListener('click', function(e) {
                        e.preventDefault();
                        e.stopPropagation();
                        
                        const trackId = this.getAttribute('data-track-id');
                        const title = this.getAttribute('data-track-title') || 'Untitled Track';
                        const prompt = this.getAttribute('data-track-prompt') || '';
                        const price = parseFloat(this.getAttribute('data-track-price')) || 0;
                        const isPublic = parseInt(this.getAttribute('data-track-public')) || 0;
                        
                        if (trackId) {
                            editTrack(trackId, title, prompt, price, isPublic);
                        } else {
                            console.error('Edit button missing track ID');
                            alert('Error: Track ID not found. Please refresh the page.');
                        }
                    });
                });
            }
            
            // Set up initial buttons
            setupEditButtons();
            
            // Re-setup buttons when track cards are dynamically updated
            // Use MutationObserver to watch for new edit buttons
            const observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    if (mutation.addedNodes.length) {
                        mutation.addedNodes.forEach(function(node) {
                            if (node.nodeType === 1) { // Element node
                                if (node.classList && node.classList.contains('edit-track-btn')) {
                                    setupEditButtons();
                                } else if (node.querySelector && node.querySelector('.edit-track-btn')) {
                                    setupEditButtons();
                                }
                            }
                        });
                    }
                });
            });
            
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        });
    </script>

    <!-- Create Crate Modal -->
    <div id="createCrateModal" class="modal" style="display: none;">
        <div class="modal-content" style="max-width: 500px;">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2 style="margin: 0; color: white;"><?= t('library.crates.create_modal_title') ?></h2>
                <button onclick="closeCreateCrateModal()" style="background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer;">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <form id="createCrateForm" onsubmit="createCrate(event)">
                <div style="margin-bottom: 1.5rem;">
                    <label style="display: block; margin-bottom: 0.5rem; color: white; font-weight: 600;"><?= t('library.crates.name_label') ?></label>
                    <input type="text" id="crateName" required style="width: 100%; padding: 0.75rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); color: white; font-size: 1rem;" placeholder="<?= t('library.crates.name_placeholder') ?>">
                </div>
                <div style="margin-bottom: 1.5rem;">
                    <label style="display: block; margin-bottom: 0.5rem; color: white; font-weight: 600;"><?= t('library.crates.description_label') ?></label>
                    <textarea id="crateDescription" rows="3" style="width: 100%; padding: 0.75rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); color: white; font-size: 1rem; resize: vertical;" placeholder="<?= t('library.crates.description_placeholder') ?>"></textarea>
                </div>
                <div style="display: flex; gap: 1rem; justify-content: flex-end;">
                    <button type="button" onclick="closeCreateCrateModal()" style="padding: 0.75rem 1.5rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); color: white; cursor: pointer; font-weight: 600;">Cancel</button>
                    <button type="submit" style="padding: 0.75rem 1.5rem; border-radius: 8px; border: none; background: linear-gradient(135deg, #667eea, #764ba2); color: white; cursor: pointer; font-weight: 600;">Create Crate</button>
                </div>
            </form>
        </div>
    </div>

    <!-- Rename Crate Modal -->
    <div id="renameCrateModal" class="modal" style="display: none;">
        <div class="modal-content" style="max-width: 450px;">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2 style="margin: 0; color: white;"><?= t('library.crates.rename_modal_title') ?></h2>
                <button onclick="closeRenameCrateModal()" style="background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer;">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <form id="renameCrateForm" onsubmit="renameCrate(event)">
                <input type="hidden" id="renameCrateId" value="">
                <div style="margin-bottom: 1.5rem;">
                    <label style="display: block; margin-bottom: 0.5rem; color: white; font-weight: 600;"><?= t('library.crates.new_name') ?></label>
                    <input type="text" id="newCrateName" required style="width: 100%; padding: 0.75rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); color: white; font-size: 1rem;" placeholder="<?= t('library.crates.name_placeholder') ?>">
                </div>
                <div style="display: flex; gap: 1rem; justify-content: flex-end;">
                    <button type="button" onclick="closeRenameCrateModal()" style="padding: 0.75rem 1.5rem; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.1); color: white; cursor: pointer; font-weight: 600;">Cancel</button>
                    <button type="submit" style="padding: 0.75rem 1.5rem; border-radius: 8px; border: none; background: linear-gradient(135deg, #fbbf24, #f59e0b); color: #1a1a2e; cursor: pointer; font-weight: 600;"><i class="fas fa-pencil-alt"></i> <?= t('library.crates.rename') ?></button>
                </div>
            </form>
        </div>
    </div>

    <!-- View Crate Modal - Draggable & Resizable -->
    <div id="viewCrateModal" class="modal crate-floating-modal" style="display: none;">
        <div id="crateModalContent" class="modal-content crate-modal-draggable" style="width: 500px; height: 400px; min-width: 350px; min-height: 250px; display: flex; flex-direction: column; overflow: hidden; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); resize: both;">
            <!-- Draggable Header -->
            <div id="crateModalHeader" class="crate-modal-header" style="display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; background: rgba(102, 126, 234, 0.3); border-radius: 12px 12px 0 0; cursor: move; flex-shrink: 0; user-select: none;">
                <div style="display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0;">
                    <i class="fas fa-grip-vertical" style="color: #a0aec0; font-size: 0.9rem;"></i>
                    <h2 id="crateModalTitle" style="margin: 0; color: white; font-size: 1.1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"><?= t('library.crates.details') ?></h2>
                </div>
                <div style="display: flex; gap: 0.25rem; flex-shrink: 0; align-items: center;">
                    <!-- BPM Sort -->
                    <select id="crateBPMSort" onchange="sortCrateTracks('bpm', this.value)" style="background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: white; padding: 0.4rem 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.8rem; font-weight: 500;" title="Sort by BPM">
                        <option value="">BPM</option>
                        <option value="asc">BPM ↑</option>
                        <option value="desc">BPM ↓</option>
                    </select>
                    <!-- Key Sort -->
                    <select id="crateKeySort" onchange="sortCrateTracks('key', this.value)" style="background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: white; padding: 0.4rem 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.8rem; font-weight: 500;" title="Sort by Key">
                        <option value="">Key</option>
                        <option value="asc">Key ↑ (1A→12B)</option>
                        <option value="desc">Key ↓ (12B→1A)</option>
                        <option value="harmonic">Harmonic Journey</option>
                    </select>
                    <button id="playCrateBtn" onclick="window.playCrateAsPlaylist()" style="background: linear-gradient(135deg, #10b981, #059669); color: white; border: none; padding: 0.4rem 0.75rem; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 0.85rem; display: flex; align-items: center; gap: 0.3rem;" title="<?= t('library.crates.play_all') ?>">
                        <i class="fas fa-play"></i> <?= t('library.crates.play_all') ?>
                    </button>
                    <button id="downloadCrateBtn" onclick="window.downloadCrateAsZip()" style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 0.4rem 0.75rem; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 0.85rem; display: flex; align-items: center; gap: 0.3rem;" title="<?= t('library.crates.download_all') ?>">
                        <i class="fas fa-download"></i> <?= t('library.crates.download_all') ?>
                    </button>
                    <button onclick="closeViewCrateModal()" style="background: rgba(255,255,255,0.1); border: none; color: white; font-size: 1.1rem; cursor: pointer; padding: 0.3rem 0.5rem; border-radius: 6px;">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            </div>
            <!-- Set Info -->
            <div id="crateSetInfo" style="padding: 0.5rem 1rem; color: #a0aec0; font-size: 0.85rem; background: rgba(0,0,0,0.2); flex-shrink: 0;"></div>
            <!-- Crate Description (Editable) -->
            <div id="crateDescriptionSection" style="padding: 0.5rem 1rem; background: rgba(0,0,0,0.1); border-top: 1px solid rgba(255,255,255,0.05); flex-shrink: 0;">
                <div style="display: flex; align-items: flex-start; gap: 0.5rem;">
                    <div style="flex: 1; display: flex; flex-direction: column; gap: 0.25rem;">
                        <textarea id="crateDescriptionInput" placeholder="<?= t('library.crates.add_description') ?>" style="width: 100%; min-height: 40px; max-height: 80px; padding: 0.5rem; border-radius: 6px; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.05); color: #e0e0e0; font-size: 0.85rem; resize: vertical; font-family: inherit;"></textarea>
                        <div id="descriptionSaveStatus" style="font-size: 0.7rem; color: #a0aec0; display: none;"></div>
                    </div>
                    <div style="display: flex; flex-direction: column; gap: 0.25rem;">
                        <button id="saveDescriptionBtn" onclick="saveCrateDescription()" style="background: rgba(16, 185, 129, 0.2); border: 1px solid rgba(16, 185, 129, 0.4); color: #10b981; padding: 0.35rem 0.5rem; border-radius: 4px; cursor: pointer; font-size: 0.75rem; display: flex; align-items: center; gap: 0.25rem; transition: all 0.2s;" title="<?= t('library.crates.save_description') ?>">
                            <i class="fas fa-save"></i>
                        </button>
                        <button id="toggleDescriptionVisibilityBtn" onclick="toggleCrateDescriptionVisibility()" style="background: none; border: 1px solid rgba(255,255,255,0.2); color: #a0aec0; padding: 0.35rem 0.5rem; border-radius: 4px; cursor: pointer; font-size: 0.75rem; display: flex; align-items: center; gap: 0.25rem; transition: all 0.2s;" title="">
                            <i class="fas fa-eye"></i>
                        </button>
                    </div>
                </div>
            </div>
            <!-- Tracks List -->
            <div id="crateTracksList" style="display: flex; flex-direction: column; gap: 0.75rem; flex: 1; overflow-y: auto; padding: 0.75rem;">
                <!-- Tracks will be loaded here -->
            </div>
            <!-- Resize Handle Indicator -->
            <div style="position: absolute; bottom: 2px; right: 2px; width: 12px; height: 12px; cursor: nwse-resize; opacity: 0.5;">
                <i class="fas fa-grip-lines" style="transform: rotate(-45deg); font-size: 0.7rem; color: #a0aec0;"></i>
            </div>
        </div>
    </div>
    
    <style>
        /* Floating Crate Modal Styles */
        .crate-floating-modal {
            background: transparent !important;
            pointer-events: none;
        }
        .crate-floating-modal .crate-modal-draggable {
            pointer-events: auto;
            background: rgba(26, 26, 26, 0.98);
            backdrop-filter: blur(20px);
            border: 1px solid rgba(102, 126, 234, 0.3);
            border-radius: 12px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
        }
        .crate-modal-header:hover {
            background: rgba(102, 126, 234, 0.4);
        }
        .crate-modal-draggable::-webkit-resizer {
            background: transparent;
        }
    </style>

    <!-- Add to Crate Modal -->
    <div id="addToCrateModal" class="modal" style="display: none;">
        <div class="modal-content" style="max-width: 400px;">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2 style="margin: 0; color: white;"><?= t('library.crates.add_track') ?></h2>
                <button onclick="closeAddToCrateModal()" style="background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer;">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div id="cratesSelectList" style="display: flex; flex-direction: column; gap: 0.5rem; max-height: 400px; overflow-y: auto;">
                <!-- Crates will be loaded here -->
            </div>
            <div style="margin-top: 1rem; padding-top: 1rem; border-top: 1px solid rgba(255, 255, 255, 0.1);">
                <button onclick="showCreateCrateModal()" style="width: 100%; padding: 0.75rem; border-radius: 8px; border: 1px dashed rgba(255, 255, 255, 0.3); background: rgba(255, 255, 255, 0.05); color: white; cursor: pointer; font-weight: 600;">
                    <i class="fas fa-plus"></i> <?= t('library.crates.create_new') ?>
                </button>
            </div>
        </div>
    </div>

    <script>
        // Crate Management Functions
        let currentTrackIdForCrate = null;
        let crates = [];

        // Load crates on page load
        document.addEventListener('DOMContentLoaded', function() {
            loadCrates();
        });

        function loadCrates() {
            fetch('/api/get_user_crates.php')
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        crates = data.crates;
                        renderCrates();
                    } else {
                        console.error('Error loading crates:', data.error);
                        document.getElementById('cratesList').innerHTML = `<div style="text-align: center; padding: 2rem; color: #a0aec0;">${libraryTranslations.crates_error_loading}</div>`;
                    }
                })
                .catch(error => {
                    console.error('Error loading crates:', error);
                    document.getElementById('cratesList').innerHTML = '<div style="text-align: center; padding: 2rem; color: #a0aec0;">Error loading crates. Please refresh the page.</div>';
                });
        }

        function renderCrates() {
            const cratesList = document.getElementById('cratesList');
            
            if (crates.length === 0) {
                cratesList.innerHTML = `
                    <div style="grid-column: 1 / -1; text-align: center; padding: 3rem; color: #a0aec0;">
                        <div style="font-size: 4rem; margin-bottom: 1rem; opacity: 0.5;">📦</div>
                        <h4 style="font-size: 1.6rem; color: white; margin-bottom: 0.5rem;">${libraryTranslations.crates_empty_title}</h4>
                        <p style="font-size: 1.2rem; margin-bottom: 1.5rem;">${libraryTranslations.crates_empty_desc}</p>
                        <button onclick="showCreateCrateModal()" style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; border: none; padding: 1rem 2rem; border-radius: 12px; font-weight: 600; cursor: pointer;">
                            <i class="fas fa-plus"></i> ${libraryTranslations.crates_create_first}
                        </button>
                    </div>
                `;
                return;
            }

            cratesList.innerHTML = crates.map(crate => {
                const setDuration = crate.set_duration_minutes || 0;
                const is2HourSet = crate.is_2_hour_set || false;
                const progressPercent = crate.set_progress_percent || 0;
                const tracksNeeded = crate.tracks_needed_for_2h || 0;
                const isPublic = crate.is_public === true || crate.is_public === 1 || crate.is_public === '1';
                
                return `
                    <div style="background: rgba(255, 255, 255, 0.05); padding: 1.5rem; border-radius: 15px; border: 1px solid ${isPublic ? 'rgba(102, 126, 234, 0.3)' : 'rgba(255, 255, 255, 0.1)'}; transition: all 0.3s ease; cursor: pointer; position: relative;" 
                         onmouseover="this.style.background='rgba(255, 255, 255, 0.08)'" 
                         onmouseout="this.style.background='rgba(255, 255, 255, 0.05)'"
                         onclick="viewCrate(${crate.id})"
                         data-crate-id="${crate.id}">
                        <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 1rem;">
                            <div style="flex: 1; min-width: 0;">
                                <div style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;">
                                    <h4 style="font-size: 1.4rem; font-weight: 700; color: white; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;" title="${escapeHtml(crate.name)}">${escapeHtml(crate.name)}</h4>
                                    ${isPublic ? '<span style="background: linear-gradient(135deg, #667eea, #764ba2); color: white; font-size: 0.65rem; padding: 0.2rem 0.5rem; border-radius: 10px; font-weight: 600;">PUBLIC</span>' : ''}
                                </div>
                                ${crate.description ? `<p style="font-size: 1rem; color: #a0aec0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;" title="${escapeHtml(crate.description)}">${escapeHtml(crate.description)}</p>` : ''}
                            </div>
                            <div style="display: flex; gap: 0.4rem; flex-shrink: 0;">
                                <button onclick="event.stopPropagation(); toggleCrateVisibility(${crate.id}, this)" 
                                        style="background: ${isPublic ? 'rgba(102, 126, 234, 0.25)' : 'rgba(255, 255, 255, 0.1)'}; color: ${isPublic ? '#667eea' : '#a0aec0'}; border: 1px solid ${isPublic ? 'rgba(102, 126, 234, 0.4)' : 'rgba(255, 255, 255, 0.2)'}; padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s ease;" 
                                        title="${isPublic ? libraryTranslations.crates_visibility_public : libraryTranslations.crates_visibility_private}"
                                        data-is-public="${isPublic}">
                                    <i class="fas ${isPublic ? 'fa-box-open' : 'fa-box'}"></i>
                                </button>
                                <button onclick="event.stopPropagation(); shareCrate(${crate.id}, '${escapeHtml(crate.name)}')" 
                                        style="background: rgba(16, 185, 129, 0.15); color: #10b981; border: 1px solid rgba(16, 185, 129, 0.3); padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s ease;" 
                                        title="${libraryTranslations.crates_share || 'Share crate'}">
                                    <i class="fas fa-share-alt"></i>
                                </button>
                                <button onclick="event.stopPropagation(); showRenameCrateModal(${crate.id}, '${escapeHtml(crate.name).replace(/'/g, "\\'")}')" 
                                        style="background: rgba(251, 191, 36, 0.15); color: #fbbf24; border: 1px solid rgba(251, 191, 36, 0.3); padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.2s ease;" 
                                        title="${libraryTranslations.crates_rename || 'Rename'}">
                                    <i class="fas fa-pencil-alt"></i>
                                </button>
                                ${!crate.is_primary ? `<button onclick="event.stopPropagation(); deleteCrate(${crate.id})" style="background: rgba(239, 68, 68, 0.2); color: #ef4444; border: none; padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem;" title="Delete crate"><i class="fas fa-trash"></i></button>` : ''}
                            </div>
                        </div>
                        
                        <div style="margin-bottom: 1rem;">
                            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
                                <span style="font-size: 1rem; color: #a0aec0;">${libraryTranslations.crates_set_duration}</span>
                                <span style="font-size: 1.1rem; font-weight: 600; color: ${is2HourSet ? '#10b981' : '#f59e0b'};">
                                    ${setDuration.toFixed(1)} ${libraryTranslations.crates_min_set} ${is2HourSet ? '✓' : ''}
                                </span>
                            </div>
                            <div style="width: 100%; height: 6px; background: rgba(255, 255, 255, 0.1); border-radius: 3px; overflow: hidden;">
                                <div style="height: 100%; background: ${is2HourSet ? 'linear-gradient(90deg, #10b981, #059669)' : 'linear-gradient(90deg, #f59e0b, #d97706)'}; width: ${Math.min(100, progressPercent)}%; transition: width 0.3s ease;"></div>
                            </div>
                            <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 0.5rem; font-size: 0.9rem; color: #a0aec0;">
                                <span>${crate.track_count || 0} ${libraryTranslations.crates_tracks}</span>
                                ${!is2HourSet ? `<span>${tracksNeeded} ${libraryTranslations.crates_tracks_needed}</span>` : `<span style="color: #10b981;">✓ ${libraryTranslations.crates_ready}</span>`}
                            </div>
                        </div>
                    </div>
                `;
            }).join('');
        }

        function showCreateCrateModal() {
            const modal = document.getElementById('createCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'flex', 'important');
            }
            const nameInput = document.getElementById('crateName');
            const descInput = document.getElementById('crateDescription');
            if (nameInput) nameInput.value = '';
            if (descInput) descInput.value = '';
        }

        function closeCreateCrateModal() {
            const modal = document.getElementById('createCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'none', 'important');
            }
        }

        function createCrate(event) {
            event.preventDefault();
            
            const name = document.getElementById('crateName').value.trim();
            const description = document.getElementById('crateDescription').value.trim();
            
            if (!name) {
                alert(libraryTranslations.crates_name_required);
                return;
            }
            
            fetch('/api/create_crate.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    name: name,
                    description: description
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    closeCreateCrateModal();
                    loadCrates();
                    if (currentTrackIdForCrate) {
                        addTrackToCrate(data.crate_id, currentTrackIdForCrate);
                        currentTrackIdForCrate = null;
                    }
                } else {
                    alert('Error creating crate: ' + (data.error || 'Unknown error'));
                }
            })
            .catch(error => {
                console.error('Error creating crate:', error);
                alert('Error creating crate. Please try again.');
            });
        }

        // Rename crate modal functions
        function showRenameCrateModal(crateId, currentName) {
            const modal = document.getElementById('renameCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'flex', 'important');
            }
            document.getElementById('renameCrateId').value = crateId;
            const nameInput = document.getElementById('newCrateName');
            if (nameInput) {
                nameInput.value = currentName;
                nameInput.focus();
                nameInput.select();
            }
        }

        function closeRenameCrateModal() {
            const modal = document.getElementById('renameCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'none', 'important');
            }
            document.getElementById('renameCrateId').value = '';
            document.getElementById('newCrateName').value = '';
        }

        function renameCrate(event) {
            event.preventDefault();
            
            const crateId = document.getElementById('renameCrateId').value;
            const newName = document.getElementById('newCrateName').value.trim();
            
            if (!newName) {
                alert(libraryTranslations.crates_name_required);
                return;
            }
            
            fetch('/api/update_crate_name.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    crate_id: parseInt(crateId),
                    name: newName
                })
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('HTTP error ' + response.status);
                }
                return response.json();
            })
            .then(data => {
                if (data.success) {
                    closeRenameCrateModal();
                    loadCrates();
                    if (typeof showNotification === 'function') {
                        showNotification(libraryTranslations.crates_renamed || 'Crate renamed successfully', 'success');
                    }
                    // Also update the view modal title if it's open for this crate
                    if (currentCrateId == crateId) {
                        const modalTitle = document.getElementById('crateModalTitle');
                        if (modalTitle) {
                            modalTitle.textContent = newName;
                        }
                    }
                } else {
                    alert('Error: ' + (data.error || 'Unknown error'));
                }
            })
            .catch(error => {
                console.error('Error renaming crate:', error);
                alert('Error: ' + error.message);
            });
        }

        // Toggle crate visibility (public/private)
        function toggleCrateVisibility(crateId, button) {
            const icon = button.querySelector('i');
            const originalIcon = icon.className;
            icon.className = 'fas fa-spinner fa-spin';
            button.disabled = true;
            
            fetch('/api/toggle_crate_visibility.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ crate_id: crateId })
            })
            .then(response => response.json())
            .then(data => {
                button.disabled = false;
                if (data.success) {
                    const isPublic = data.is_public;
                    button.setAttribute('data-is-public', isPublic);
                    button.style.background = isPublic ? 'rgba(102, 126, 234, 0.25)' : 'rgba(255, 255, 255, 0.1)';
                    button.style.color = isPublic ? '#667eea' : '#a0aec0';
                    button.style.borderColor = isPublic ? 'rgba(102, 126, 234, 0.4)' : 'rgba(255, 255, 255, 0.2)';
                    button.title = isPublic ? (libraryTranslations.crates_visibility_public || 'Public - visible on profile') : (libraryTranslations.crates_visibility_private || 'Private - only you can see');
                    icon.className = isPublic ? 'fas fa-box-open' : 'fas fa-box';
                    
                    // Update the crate card border
                    const crateCard = button.closest('[data-crate-id]');
                    if (crateCard) {
                        crateCard.style.borderColor = isPublic ? 'rgba(102, 126, 234, 0.3)' : 'rgba(255, 255, 255, 0.1)';
                        // Update or remove PUBLIC badge
                        const titleContainer = crateCard.querySelector('h4').parentElement;
                        let badge = titleContainer.querySelector('.public-badge');
                        if (isPublic && !badge) {
                            const newBadge = document.createElement('span');
                            newBadge.className = 'public-badge';
                            newBadge.style.cssText = 'background: linear-gradient(135deg, #667eea, #764ba2); color: white; font-size: 0.65rem; padding: 0.2rem 0.5rem; border-radius: 10px; font-weight: 600;';
                            newBadge.textContent = 'PUBLIC';
                            titleContainer.appendChild(newBadge);
                        } else if (!isPublic && badge) {
                            badge.remove();
                        }
                    }
                    
                    // Update crates array
                    const crateIndex = crates.findIndex(c => c.id == crateId);
                    if (crateIndex !== -1) {
                        crates[crateIndex].is_public = isPublic;
                    }
                    
                    // If this crate is currently open in the modal, update the description toggle button
                    if (window.currentCrateData && window.currentCrateData.id == crateId) {
                        window.currentCrateIsPublic = isPublic;
                        window.currentCrateData.is_public = isPublic;
                        // Update the description toggle button state based on new crate visibility
                        updateDescriptionToggleButton(window.currentCrateDescriptionPublic, isPublic);
                    }
                    
                    showCrateNotification(data.message, 'success');
                } else {
                    icon.className = originalIcon;
                    showCrateNotification(data.error || 'Failed to update visibility', 'error');
                }
            })
            .catch(error => {
                button.disabled = false;
                icon.className = originalIcon;
                console.error('Error toggling crate visibility:', error);
                showCrateNotification('Error updating visibility. Please try again.', 'error');
            });
        }
        
        // Share crate - copy link to clipboard
        function shareCrate(crateId, crateName) {
            const shareUrl = `${window.location.origin}/crate/${crateId}`;
            
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(shareUrl)
                    .then(() => {
                        showCrateNotification(libraryTranslations.crates_link_copied || `Link to "${crateName}" copied to clipboard!`, 'success');
                    })
                    .catch(err => {
                        console.error('Clipboard error:', err);
                        fallbackCopyToClipboard(shareUrl, crateName);
                    });
            } else {
                fallbackCopyToClipboard(shareUrl, crateName);
            }
        }
        
        function fallbackCopyToClipboard(text, crateName) {
            const textarea = document.createElement('textarea');
            textarea.value = text;
            textarea.style.position = 'fixed';
            textarea.style.opacity = '0';
            document.body.appendChild(textarea);
            textarea.select();
            try {
                document.execCommand('copy');
                showCrateNotification(libraryTranslations.crates_link_copied || `Link to "${crateName}" copied!`, 'success');
            } catch (err) {
                showCrateNotification('Failed to copy link', 'error');
            }
            document.body.removeChild(textarea);
        }
        
        // Show notification for crate actions
        function showCrateNotification(message, type = 'info') {
            if (typeof showNotification === 'function') {
                showNotification(message, type);
            } else {
                // Fallback notification
                const notif = document.createElement('div');
                notif.style.cssText = `position: fixed; bottom: 20px; right: 20px; padding: 1rem 1.5rem; border-radius: 10px; color: white; font-weight: 500; z-index: 99999; animation: slideIn 0.3s ease; background: ${type === 'success' ? 'linear-gradient(135deg, #10b981, #059669)' : type === 'error' ? 'linear-gradient(135deg, #ef4444, #dc2626)' : 'linear-gradient(135deg, #667eea, #764ba2)'};`;
                notif.textContent = message;
                document.body.appendChild(notif);
                setTimeout(() => {
                    notif.style.animation = 'fadeOut 0.3s ease';
                    setTimeout(() => notif.remove(), 300);
                }, 3000);
            }
        }

        function viewCrate(crateId) {
            const modal = document.getElementById('viewCrateModal');
            const tracksList = document.getElementById('crateTracksList');
            
            // Show modal immediately with loading state
            modal.style.setProperty('display', 'flex', 'important');
            document.getElementById('crateModalTitle').textContent = libraryTranslations.crates_loading;
            tracksList.innerHTML = `<div style="text-align: center; padding: 2rem; color: #a0aec0;"><i class="fas fa-spinner fa-spin" style="font-size: 1.5rem; margin-bottom: 0.5rem;"></i><div>${libraryTranslations.crates_loading_tracks}</div></div>`;
            
            fetch(`/api/get_crate_tracks.php?crate_id=${crateId}`)
                .then(response => {
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }
                    return response.text().then(text => {
                        try {
                            return JSON.parse(text);
                        } catch (e) {
                            console.error('Invalid JSON response:', text);
                            throw new Error('Invalid JSON response from server');
                        }
                    });
                })
                .then(data => {
                    console.log('Crate data received:', data);
                    
                    if (data.success) {
                        document.getElementById('crateModalTitle').textContent = data.crate.name || libraryTranslations.crates_details;
                        
                        // Show description section (always visible for editing)
                        const descInput = document.getElementById('crateDescriptionInput');
                        const descStatus = document.getElementById('descriptionSaveStatus');
                        
                        descInput.value = data.crate.description || '';
                        descStatus.style.display = 'none';
                        
                        // Store crate public status
                        const crateIsPublic = (data.crate.is_public == 1 || data.crate.is_public === true);
                        window.currentCrateIsPublic = crateIsPublic;
                        
                        // Properly handle is_description_public: 
                        // - If null/undefined: default to true (public)
                        // - If 0: false (private)
                        // - If 1 or true: true (public)
                        const descPublicValue = data.crate.is_description_public;
                        if (descPublicValue === null || descPublicValue === undefined) {
                            window.currentCrateDescriptionPublic = true; // Default to public
                        } else {
                            window.currentCrateDescriptionPublic = (descPublicValue == 1 || descPublicValue === true);
                        }
                        console.log('Crate description visibility initialized:', { 
                            crateIsPublic: crateIsPublic,
                            raw: descPublicValue, 
                            calculated: window.currentCrateDescriptionPublic 
                        });
                        updateDescriptionToggleButton(window.currentCrateDescriptionPublic, crateIsPublic);
                        
                        const setDuration = data.total_set_duration_minutes || 0;
                        const is2HourSet = data.is_2_hour_set || false;
                        const progressPercent = data.set_progress_percent || 0;
                        
                        document.getElementById('crateSetInfo').innerHTML = `
                            <div style="display: flex; align-items: center; gap: 1rem;">
                                <span style="color: ${is2HourSet ? '#10b981' : '#f59e0b'}; font-weight: 600;">
                                    ${setDuration.toFixed(1)} ${libraryTranslations.crates_min_set} / 120 ${libraryTranslations.crates_min_set}
                                </span>
                                <div style="flex: 1; height: 4px; background: rgba(255, 255, 255, 0.1); border-radius: 2px; overflow: hidden;">
                                    <div style="height: 100%; background: ${is2HourSet ? 'linear-gradient(90deg, #10b981, #059669)' : 'linear-gradient(90deg, #f59e0b, #d97706)'}; width: ${Math.min(100, progressPercent)}%;"></div>
                                </div>
                                ${is2HourSet ? `<span style="color: #10b981;">✓ ${libraryTranslations.crates_ready_short}</span>` : `<span style="color: #a0aec0;">${Math.ceil((120 - setDuration) / 2.5)} ${libraryTranslations.crates_tracks_needed}</span>`}
                            </div>
                        `;
                        
                        if (!data.tracks || data.tracks.length === 0) {
                            tracksList.innerHTML = `<div style="text-align: center; padding: 2rem; color: #a0aec0;"><div style="font-size: 2rem; margin-bottom: 0.5rem;">📦</div><div>${libraryTranslations.crates_no_tracks}</div><div style="margin-top: 1rem; font-size: 0.9rem;">${libraryTranslations.crates_add_tracks_desc}</div></div>`;
                        } else {
                            // Store crate data for reordering
                            window.currentCrateData = { 
                                id: crateId, 
                                tracks: data.tracks, 
                                name: data.crate.name,
                                is_public: window.currentCrateIsPublic,
                                is_description_public: window.currentCrateDescriptionPublic
                            };
                            
                            // Helper function to escape HTML attributes
                            const escapeHtmlAttr = (str) => {
                                if (!str) return '';
                                return String(str)
                                    .replace(/&/g, '&amp;')
                                    .replace(/"/g, '&quot;')
                                    .replace(/'/g, '&#39;')
                                    .replace(/</g, '&lt;')
                                    .replace(/>/g, '&gt;');
                            };
                            
                            // Parse metadata for BPM and Key
                            data.tracks.forEach(track => {
                                if (track.metadata) {
                                    try {
                                        const metadata = typeof track.metadata === 'string' ? JSON.parse(track.metadata) : track.metadata;
                                        track.bpm = metadata.bpm || null;
                                        track.key = metadata.key || null;
                                        track.camelot = metadata.numerical_key || null;
                                    } catch (e) {
                                        track.bpm = null;
                                        track.key = null;
                                        track.camelot = null;
                                    }
                                } else {
                                    track.bpm = null;
                                    track.key = null;
                                    track.camelot = null;
                                }
                            });
                            
                            tracksList.innerHTML = data.tracks.map((track, index) => {
                                const trackDuration = parseFloat(track.duration) || 0;
                                const setDuration = parseFloat(track.set_duration_minutes) || (trackDuration >= 300 ? 2.5 : trackDuration * 0.5 / 60);
                                const minutes = Math.floor(trackDuration / 60);
                                const seconds = Math.floor(trackDuration % 60);
                                const position = track.position || (index + 1);
                                
                                // Format BPM and Key for display
                                const bpmDisplay = track.bpm ? track.bpm.toFixed(1) : '—';
                                const keyDisplay = track.key ? track.key : '—';
                                const camelotDisplay = track.camelot ? track.camelot : '';
                                
                                return `
                                    <div class="crate-track-item" 
                                         data-track-id="${track.id}" 
                                         data-position="${position}"
                                         data-bpm="${track.bpm || ''}"
                                         data-camelot="${track.camelot || ''}"
                                         style="display: flex; align-items: center; gap: 1rem; padding: 1rem; background: rgba(255, 255, 255, 0.03); border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; cursor: move;"
                                         onmouseover="this.style.background='rgba(255, 255, 255, 0.06)'"
                                         onmouseout="this.style.background='rgba(255, 255, 255, 0.03)'"
                                         draggable="true"
                                         ondragstart="handleDragStart(event, ${track.id})"
                                         ondragover="handleDragOver(event)"
                                         ondrop="handleDrop(event, ${track.id}, ${crateId})"
                                         ondragend="handleDragEnd(event)">
                                        <div style="display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0;">
                                            <div class="drag-handle" style="color: #a0aec0; cursor: grab; padding: 0.25rem;" title="${libraryTranslations.crates_drag_reorder}">
                                                <i class="fas fa-grip-vertical"></i>
                                            </div>
                                            <div style="width: 2.5rem; height: 2.5rem; border-radius: 8px; background: linear-gradient(135deg, #667eea, #764ba2); display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 0.9rem;">
                                                ${position}
                                            </div>
                                        </div>
                                        <div style="flex: 1; min-width: 0;">
                                            <div style="font-weight: 600; color: white; margin-bottom: 0.25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${escapeHtml(track.title || libraryTranslations.untitled_track)}</div>
                                            <div style="font-size: 0.9rem; color: #a0aec0; display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap;">
                                                <span>${minutes}:${String(seconds).padStart(2, '0')}</span>
                                                <span>•</span>
                                                <span><strong>BPM:</strong> ${bpmDisplay}</span>
                                                <span>•</span>
                                                <span><strong>Key:</strong> ${keyDisplay}${camelotDisplay ? ' <span style="color: #667eea; font-weight: 600;">(' + camelotDisplay + ')</span>' : ''}</span>
                                                <span>•</span>
                                                <span>${libraryTranslations.crates_set_duration}: ${setDuration.toFixed(1)} ${libraryTranslations.crates_min_set}</span>
                                            </div>
                                        </div>
                                        <div style="display: flex; gap: 0.5rem; flex-shrink: 0;">
                                            <button onclick="event.stopPropagation(); window.playCrateFromTrack(${index})" 
                                                    style="background: rgba(16, 185, 129, 0.2); color: #10b981; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                                    onmouseover="this.style.background='rgba(16, 185, 129, 0.3)'"
                                                    onmouseout="this.style.background='rgba(16, 185, 129, 0.2)'"
                                                    title="Play from here">
                                                <i class="fas fa-play"></i>
                                            </button>
                                            <button onclick="toggleCrateTrackVisibility(${crateId}, ${track.id}, this)" 
                                                    style="background: ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'rgba(102, 126, 234, 0.25)' : 'rgba(107, 114, 128, 0.25)'}; color: ${track.crate_track_public == 1 || track.crate_track_public === undefined ? '#667eea' : '#6b7280'}; border: 1px solid ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'rgba(102, 126, 234, 0.4)' : 'rgba(107, 114, 128, 0.4)'}; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                                    data-is-public="${track.crate_track_public == 1 || track.crate_track_public === undefined ? '1' : '0'}"
                                                    title="${track.crate_track_public == 1 || track.crate_track_public === undefined ? (libraryTranslations.crates_track_public || 'Track visible in public crate') : (libraryTranslations.crates_track_private || 'Track hidden from public crate')}">
                                                <i class="fas ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'fa-eye' : 'fa-eye-slash'}"></i>
                                            </button>
                                            ${(track.user_owns_track == 1 || track.user_purchased_track == 1) ? `
                                            <button onclick="window.downloadCrateTrack(${track.id}, ${crateId}, ${position})" 
                                                    style="background: rgba(102, 126, 234, 0.2); color: #667eea; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                                    onmouseover="this.style.background='rgba(102, 126, 234, 0.3)'"
                                                    onmouseout="this.style.background='rgba(102, 126, 234, 0.2)'"
                                                    title="${libraryTranslations.crates_download}: ${escapeHtml(data.crate.name)} - Track ${position}">
                                                <i class="fas fa-download"></i>
                                            </button>
                                            ` : `
                                            <button onclick="event.stopPropagation(); window.addToCartFromCrate(${track.id}, this)" 
                                                    data-track-id="${track.id}"
                                                    data-track-title="${escapeHtml(track.title || 'Untitled Track')}"
                                                    data-track-price="${track.price || 0}"
                                                    class="btn-cart"
                                                    style="background: rgba(245, 158, 11, 0.2); color: #f59e0b; border: none; padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.85rem; transition: all 0.3s ease; min-width: 36px; display: flex; align-items: center; justify-content: center;"
                                                    onmouseover="this.style.background='rgba(245, 158, 11, 0.3)'"
                                                    onmouseout="this.style.background='rgba(245, 158, 11, 0.2)'"
                                                    title="${libraryTranslations.crates_add_to_cart || 'Add to Cart'}${track.price && track.price > 0 ? ' ($' + track.price + ')' : ' (' + (libraryTranslations.free || 'Free') + ')'}">
                                                <i class="fas fa-shopping-cart"></i>
                                            </button>
                                            `}
                                            <button onclick="removeTrackFromCrate(${crateId}, ${track.id})" 
                                                    style="background: rgba(239, 68, 68, 0.2); color: #ef4444; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                                    onmouseover="this.style.background='rgba(239, 68, 68, 0.3)'"
                                                    onmouseout="this.style.background='rgba(239, 68, 68, 0.2)'"
                                                    title="${libraryTranslations.crates_remove}">
                                                <i class="fas fa-times"></i>
                                            </button>
                                        </div>
                                    </div>
                                `;
                            }).join('');
                            
                            // Initialize drag and drop
                            initCrateDragAndDrop();
                            
                            // Reset sort dropdowns
                            document.getElementById('crateBPMSort').value = '';
                            document.getElementById('crateKeySort').value = '';
                        }
                    } else {
                        const errorMsg = data.error || 'Unknown error occurred';
                        console.error('API returned error:', errorMsg);
                        tracksList.innerHTML = `
                            <div style="text-align: center; padding: 2rem; color: #ef4444;">
                                <div style="font-size: 2rem; margin-bottom: 0.5rem;">⚠️</div>
                                <div style="font-weight: 600; margin-bottom: 0.5rem;">${libraryTranslations.crates_error_loading_crate}</div>
                                <div style="font-size: 0.9rem; color: #a0aec0;">${escapeHtml(errorMsg)}</div>
                            </div>
                        `;
                        showNotification(libraryTranslations.crates_error_loading_crate + ': ' + errorMsg, 'error');
                    }
                })
                .catch(error => {
                    console.error('Error loading crate:', error);
                    const errorMsg = error.message || 'Failed to load crate. Please check your connection and try again.';
                    tracksList.innerHTML = `
                        <div style="text-align: center; padding: 2rem; color: #ef4444;">
                            <div style="font-size: 2rem; margin-bottom: 0.5rem;">⚠️</div>
                            <div style="font-weight: 600; margin-bottom: 0.5rem;">${libraryTranslations.crates_error_loading_crate}</div>
                            <div style="font-size: 0.9rem; color: #a0aec0;">${escapeHtml(errorMsg)}</div>
                            <div style="margin-top: 1rem; font-size: 0.85rem; color: #a0aec0;">${libraryTranslations.crates_error_loading_desc}</div>
                        </div>
                    `;
                    showNotification(libraryTranslations.crates_error_loading_crate + '. ' + libraryTranslations.crates_error_loading_desc, 'error');
                });
        }

        function closeViewCrateModal() {
            const modal = document.getElementById('viewCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'none', 'important');
            }
        }

        // Crate sorting functions
        function sortCrateTracks(sortType, sortOrder) {
            if (!window.currentCrateData || !window.currentCrateData.tracks) {
                return;
            }
            
            const tracks = [...window.currentCrateData.tracks]; // Copy array
            const tracksList = document.getElementById('crateTracksList');
            
            // Reset other sort dropdown
            if (sortType === 'bpm') {
                document.getElementById('crateKeySort').value = '';
            } else {
                document.getElementById('crateBPMSort').value = '';
            }
            
            let sortedTracks = tracks;
            
            if (sortType === 'bpm') {
                // Sort by BPM
                sortedTracks = tracks.sort((a, b) => {
                    const aBpm = parseFloat(a.bpm) || 0;
                    const bBpm = parseFloat(b.bpm) || 0;
                    if (sortOrder === 'asc') {
                        return aBpm - bBpm;
                    } else {
                        return bBpm - aBpm;
                    }
                });
            } else if (sortType === 'key') {
                // Camelot wheel order: 1A, 1B, 2A, 2B, ..., 12A, 12B
                const camelotOrder = {
                    '1A': 1, '1B': 2, '2A': 3, '2B': 4, '3A': 5, '3B': 6,
                    '4A': 7, '4B': 8, '5A': 9, '5B': 10, '6A': 11, '6B': 12,
                    '7A': 13, '7B': 14, '8A': 15, '8B': 16, '9A': 17, '9B': 18,
                    '10A': 19, '10B': 20, '11A': 21, '11B': 22, '12A': 23, '12B': 24
                };
                
                if (sortOrder === 'harmonic') {
                    // Harmonic Journey: 1A→12B then 12B→1A (round trip)
                    // First sort all tracks by key ascending (1A→12B)
                    sortedTracks = tracks.sort((a, b) => {
                        const aCamelot = (a.camelot || '').toUpperCase();
                        const bCamelot = (b.camelot || '').toUpperCase();
                        const aOrder = camelotOrder[aCamelot] || 999;
                        const bOrder = camelotOrder[bCamelot] || 999;
                        return aOrder - bOrder;
                    });
                    
                    // Split into two halves: first half ascending, second half descending
                    const midpoint = Math.ceil(sortedTracks.length / 2);
                    const firstHalf = sortedTracks.slice(0, midpoint);
                    const secondHalf = sortedTracks.slice(midpoint).sort((a, b) => {
                        const aCamelot = (a.camelot || '').toUpperCase();
                        const bCamelot = (b.camelot || '').toUpperCase();
                        const aOrder = camelotOrder[aCamelot] || 999;
                        const bOrder = camelotOrder[bCamelot] || 999;
                        return bOrder - aOrder; // Reverse order for second half
                    });
                    sortedTracks = [...firstHalf, ...secondHalf];
                } else {
                    // Standard key sorting (ascending or descending)
                    sortedTracks = tracks.sort((a, b) => {
                        const aCamelot = (a.camelot || '').toUpperCase();
                        const bCamelot = (b.camelot || '').toUpperCase();
                        const aOrder = camelotOrder[aCamelot] || 999;
                        const bOrder = camelotOrder[bCamelot] || 999;
                        
                        if (sortOrder === 'asc') {
                            return aOrder - bOrder;
                        } else {
                            return bOrder - aOrder;
                        }
                    });
                }
            }
            
            // Update currentCrateData with sorted tracks
            window.currentCrateData.tracks = sortedTracks;
            
            // Re-render tracks with new order
            const escapeHtml = (str) => {
                if (!str) return '';
                return String(str)
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;');
            };
            
            const escapeHtmlAttr = (str) => {
                if (!str) return '';
                return String(str)
                    .replace(/&/g, '&amp;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;');
            };
            
            const crateId = window.currentCrateData.id;
            tracksList.innerHTML = sortedTracks.map((track, index) => {
                const trackDuration = parseFloat(track.duration) || 0;
                const setDuration = parseFloat(track.set_duration_minutes) || (trackDuration >= 300 ? 2.5 : trackDuration * 0.5 / 60);
                const minutes = Math.floor(trackDuration / 60);
                const seconds = Math.floor(trackDuration % 60);
                const position = index + 1;
                
                const bpmDisplay = track.bpm ? track.bpm.toFixed(1) : '—';
                const keyDisplay = track.key ? track.key : '—';
                const camelotDisplay = track.camelot ? track.camelot : '';
                
                return `
                    <div class="crate-track-item" 
                         data-track-id="${track.id}" 
                         data-position="${position}"
                         data-bpm="${track.bpm || ''}"
                         data-camelot="${track.camelot || ''}"
                         style="display: flex; align-items: center; gap: 1rem; padding: 1rem; background: rgba(255, 255, 255, 0.03); border-radius: 10px; border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.3s ease; cursor: move;"
                         onmouseover="this.style.background='rgba(255, 255, 255, 0.06)'"
                         onmouseout="this.style.background='rgba(255, 255, 255, 0.03)'"
                         draggable="true"
                         ondragstart="handleDragStart(event, ${track.id})"
                         ondragover="handleDragOver(event)"
                         ondrop="handleDrop(event, ${track.id}, ${crateId})"
                         ondragend="handleDragEnd(event)">
                        <div style="display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0;">
                            <div class="drag-handle" style="color: #a0aec0; cursor: grab; padding: 0.25rem;" title="${libraryTranslations.crates_drag_reorder}">
                                <i class="fas fa-grip-vertical"></i>
                            </div>
                            <div style="width: 2.5rem; height: 2.5rem; border-radius: 8px; background: linear-gradient(135deg, #667eea, #764ba2); display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 0.9rem;">
                                ${position}
                            </div>
                        </div>
                        <div style="flex: 1; min-width: 0;">
                            <div style="font-weight: 600; color: white; margin-bottom: 0.25rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${escapeHtml(track.title || libraryTranslations.untitled_track)}</div>
                            <div style="font-size: 0.9rem; color: #a0aec0; display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap;">
                                <span>${minutes}:${String(seconds).padStart(2, '0')}</span>
                                <span>•</span>
                                <span><strong>BPM:</strong> ${bpmDisplay}</span>
                                <span>•</span>
                                <span><strong>Key:</strong> ${keyDisplay}${camelotDisplay ? ' <span style="color: #667eea; font-weight: 600;">(' + camelotDisplay + ')</span>' : ''}</span>
                                <span>•</span>
                                <span>${libraryTranslations.crates_set_duration}: ${setDuration.toFixed(1)} ${libraryTranslations.crates_min_set}</span>
                            </div>
                        </div>
                        <div style="display: flex; gap: 0.5rem; flex-shrink: 0;">
                            <button onclick="event.stopPropagation(); window.playCrateFromTrack(${index})" 
                                    style="background: rgba(16, 185, 129, 0.2); color: #10b981; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                    onmouseover="this.style.background='rgba(16, 185, 129, 0.3)'"
                                    onmouseout="this.style.background='rgba(16, 185, 129, 0.2)'"
                                    title="Play from here">
                                <i class="fas fa-play"></i>
                            </button>
                            <button onclick="toggleCrateTrackVisibility(${crateId}, ${track.id}, this)" 
                                    style="background: ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'rgba(102, 126, 234, 0.25)' : 'rgba(107, 114, 128, 0.25)'}; color: ${track.crate_track_public == 1 || track.crate_track_public === undefined ? '#667eea' : '#6b7280'}; border: 1px solid ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'rgba(102, 126, 234, 0.4)' : 'rgba(107, 114, 128, 0.4)'}; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                    data-is-public="${track.crate_track_public == 1 || track.crate_track_public === undefined ? '1' : '0'}"
                                    title="${track.crate_track_public == 1 || track.crate_track_public === undefined ? (libraryTranslations.crates_track_public || 'Track visible in public crate') : (libraryTranslations.crates_track_private || 'Track hidden from public crate')}">
                                <i class="fas ${track.crate_track_public == 1 || track.crate_track_public === undefined ? 'fa-eye' : 'fa-eye-slash'}"></i>
                            </button>
                            ${(track.user_owns_track == 1 || track.user_purchased_track == 1) ? `
                            <button onclick="window.downloadCrateTrack(${track.id}, ${crateId}, ${position})" 
                                    style="background: rgba(102, 126, 234, 0.2); color: #667eea; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                    onmouseover="this.style.background='rgba(102, 126, 234, 0.3)'"
                                    onmouseout="this.style.background='rgba(102, 126, 234, 0.2)'"
                                    title="${libraryTranslations.crates_download}: ${escapeHtml(window.currentCrateData.name)} - Track ${position}">
                                <i class="fas fa-download"></i>
                            </button>
                            ` : `
                            <button onclick="event.stopPropagation(); window.addToCartFromCrate(${track.id}, this)" 
                                    data-track-id="${track.id}"
                                    data-track-title="${escapeHtmlAttr(track.title || 'Untitled Track')}"
                                    data-track-price="${track.price || 0}"
                                    class="btn-cart"
                                    style="background: rgba(245, 158, 11, 0.2); color: #f59e0b; border: none; padding: 0.5rem; border-radius: 6px; cursor: pointer; font-size: 0.85rem; transition: all 0.3s ease; min-width: 36px; display: flex; align-items: center; justify-content: center;"
                                    onmouseover="this.style.background='rgba(245, 158, 11, 0.3)'"
                                    onmouseout="this.style.background='rgba(245, 158, 11, 0.2)'"
                                    title="${libraryTranslations.crates_add_to_cart || 'Add to Cart'}${track.price && track.price > 0 ? ' ($' + track.price + ')' : ' (' + (libraryTranslations.free || 'Free') + ')'}">
                                <i class="fas fa-shopping-cart"></i>
                            </button>
                            `}
                            <button onclick="removeTrackFromCrate(${crateId}, ${track.id})" 
                                    style="background: rgba(239, 68, 68, 0.2); color: #ef4444; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.9rem; transition: all 0.3s ease;"
                                    onmouseover="this.style.background='rgba(239, 68, 68, 0.3)'"
                                    onmouseout="this.style.background='rgba(239, 68, 68, 0.2)'"
                                    title="${libraryTranslations.crates_remove}">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>
                    </div>
                `;
            }).join('');
            
            // Re-initialize drag and drop
            initCrateDragAndDrop();
        }

        // Make crate modal draggable
        (function initDraggableModal() {
            let isDragging = false;
            let dragOffsetX = 0;
            let dragOffsetY = 0;
            
            const header = document.getElementById('crateModalHeader');
            const modal = document.getElementById('crateModalContent');
            
            if (!header || !modal) return;
            
            header.addEventListener('mousedown', function(e) {
                if (e.target.tagName === 'BUTTON' || e.target.tagName === 'I' && e.target.closest('button')) return;
                
                isDragging = true;
                const rect = modal.getBoundingClientRect();
                dragOffsetX = e.clientX - rect.left;
                dragOffsetY = e.clientY - rect.top;
                
                // Remove transform for proper positioning
                modal.style.transform = 'none';
                modal.style.left = rect.left + 'px';
                modal.style.top = rect.top + 'px';
                
                document.body.style.userSelect = 'none';
            });
            
            document.addEventListener('mousemove', function(e) {
                if (!isDragging) return;
                
                let newX = e.clientX - dragOffsetX;
                let newY = e.clientY - dragOffsetY;
                
                // Keep within viewport
                newX = Math.max(0, Math.min(newX, window.innerWidth - modal.offsetWidth));
                newY = Math.max(0, Math.min(newY, window.innerHeight - modal.offsetHeight));
                
                modal.style.left = newX + 'px';
                modal.style.top = newY + 'px';
            });
            
            document.addEventListener('mouseup', function() {
                isDragging = false;
                document.body.style.userSelect = '';
            });
        })();

        // Build playlist from crate data - includes BOTH variations for each track
        window.buildCratePlaylist = function(crateData) {
            const playlistTracks = [];

            crateData.tracks.forEach((track, index) => {
                const artistName = track.artist_name || 'Unknown Artist';
                const position = track.position || (index + 1);
                const baseTitle = track.title || 'Untitled';

                // Check if track has variations
                if (track.variations && track.variations.length > 0) {
                    // Add each variation as a separate playlist entry
                    track.variations.forEach((variation, varIndex) => {
                        if (variation.audio_url) {
                            const varLabel = variation.title || `Version ${varIndex + 1}`;
                            playlistTracks.push({
                                id: `${track.id}_v${variation.variation_index}`,
                                audio_url: variation.audio_url,
                                title: `${position}. ${baseTitle} - ${varLabel}`,
                                artist_name: artistName,
                                duration: variation.duration || track.duration,
                                trackId: track.id,
                                variationIndex: variation.variation_index
                            });
                        }
                    });
                } else if (track.audio_url) {
                    // No variations - just add the main track
                    playlistTracks.push({
                        id: track.id,
                        audio_url: track.audio_url,
                        title: `${position}. ${baseTitle}`,
                        artist_name: artistName,
                        duration: track.duration,
                        trackId: track.id,
                        variationIndex: 0
                    });
                }
            });

            return playlistTracks;
        };

        // Play crate as playlist with all variations
        window.playCrateAsPlaylist = function() {
            console.log('🎵 playCrateAsPlaylist called');
            console.log('🎵 currentCrateData:', window.currentCrateData);
            
            if (!window.currentCrateData || !window.currentCrateData.tracks || window.currentCrateData.tracks.length === 0) {
                console.error('🎵 No crate data available');
                if (typeof showNotification === 'function') {
                    showNotification('No tracks in this crate to play', 'error');
                } else {
                    alert('No tracks in this crate to play');
                }
                return;
            }

            const crateData = window.currentCrateData;
            const playlistTracks = window.buildCratePlaylist(crateData);
            console.log('🎵 Built playlist with', playlistTracks.length, 'tracks:', playlistTracks);

            if (playlistTracks.length === 0) {
                console.error('🎵 No playable tracks found');
                if (typeof showNotification === 'function') {
                    showNotification('No playable tracks found in this crate', 'error');
                }
                return;
            }

            // Load playlist into global player
            console.log('🎵 Checking for loadCratePlaylist function:', typeof window.loadCratePlaylist);
            if (typeof window.loadCratePlaylist === 'function') {
                console.log('🎵 Calling loadCratePlaylist...');
                window.loadCratePlaylist(playlistTracks, crateData.name);
            } else if (typeof window.enhancedGlobalPlayer !== 'undefined' && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                // Fallback: use enhanced global player
                console.log('🎵 Fallback: using enhancedGlobalPlayer');
                const firstTrack = playlistTracks[0];
                window.enhancedGlobalPlayer.playTrack(firstTrack.audio_url, firstTrack.title, firstTrack.artist_name);
                if (typeof showNotification === 'function') {
                    showNotification(`Playing: ${crateData.name} (${playlistTracks.length} tracks)`, 'success');
                }
            } else {
                console.error('🎵 No player available');
                alert('Player not available. Please refresh the page.');
            }

            // Keep modal open so user can see tracks while playing
        };

        // Play crate starting from a specific track index
        window.playCrateFromTrack = function(startIndex) {
            if (!window.currentCrateData || !window.currentCrateData.tracks) {
                showNotification('No crate data available', 'error');
                return;
            }

            const crateData = window.currentCrateData;
            const playlistTracks = buildCratePlaylist(crateData);

            if (playlistTracks.length === 0) {
                showNotification('No playable tracks found', 'error');
                return;
            }

            // Calculate start index accounting for variations
            let playlistStartIndex = 0;
            for (let i = 0; i < crateData.tracks.length && i < startIndex; i++) {
                const track = crateData.tracks[i];
                if (track.variations && track.variations.length > 0) {
                    playlistStartIndex += track.variations.length;
                } else {
                    playlistStartIndex += 1;
                }
            }
            playlistStartIndex = Math.min(playlistStartIndex, playlistTracks.length - 1);

            // Reorder playlist to start from the selected track
            if (typeof window.loadCratePlaylist === 'function') {
                const reorderedTracks = [
                    ...playlistTracks.slice(playlistStartIndex),
                    ...playlistTracks.slice(0, playlistStartIndex)
                ];
                window.loadCratePlaylist(reorderedTracks, crateData.name);
            }

            // Keep modal open so user can see tracks while playing
        };

        function showAddToCrateModal(trackId) {
            currentTrackIdForCrate = trackId;
            const cratesSelectList = document.getElementById('cratesSelectList');
            const modal = document.getElementById('addToCrateModal');
            
            // Show modal immediately with loading state
            modal.style.setProperty('display', 'flex', 'important');
            cratesSelectList.innerHTML = '<div style="text-align: center; padding: 2rem; color: #a0aec0;"><i class="fas fa-spinner fa-spin" style="font-size: 1.5rem; margin-bottom: 0.5rem;"></i><div>Loading crates...</div></div>';
            
            // Reload crates to ensure we have the latest list, including which crates already have this track
            fetch(`/api/get_user_crates.php?track_id=${trackId}`)
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        crates = data.crates;
                        
                        if (crates.length === 0) {
                            cratesSelectList.innerHTML = `
                                <div style="text-align: center; padding: 2rem; color: #a0aec0;">
                                    <div style="font-size: 2rem; margin-bottom: 0.5rem;">📦</div>
                                    <div style="margin-bottom: 1rem;">${libraryTranslations.crates_empty_desc}</div>
                                </div>
                            `;
                        } else {
                            cratesSelectList.innerHTML = crates.map(crate => {
                                const hasTrack = crate.has_track == 1 || crate.has_track === true;
                                const isDisabled = hasTrack;
                                
                                return `
                                    <button onclick="${isDisabled ? '' : `addTrackToCrate(${crate.id}, ${trackId})`}" 
                                            style="width: 100%; padding: 1rem; text-align: left; background: ${hasTrack ? 'rgba(16, 185, 129, 0.1)' : 'rgba(255, 255, 255, 0.05)'}; border: 1px solid ${hasTrack ? 'rgba(16, 185, 129, 0.3)' : 'rgba(255, 255, 255, 0.1)'}; border-radius: 8px; color: white; cursor: ${isDisabled ? 'default' : 'pointer'}; transition: all 0.3s ease; margin-bottom: 0.5rem; opacity: ${isDisabled ? '0.7' : '1'};"
                                            onmouseover="${!isDisabled ? `this.style.background='rgba(102, 126, 234, 0.2)'; this.style.borderColor='rgba(102, 126, 234, 0.5)'` : ''}"
                                            onmouseout="${!isDisabled ? `this.style.background='rgba(255, 255, 255, 0.05)'; this.style.borderColor='rgba(255, 255, 255, 0.1)'` : ''}"
                                            ${isDisabled ? 'disabled' : ''}>
                                        <div style="display: flex; align-items: center; gap: 0.75rem;">
                                            <div style="width: 2.5rem; height: 2.5rem; border-radius: 8px; background: ${hasTrack ? 'linear-gradient(135deg, #10b981, #059669)' : 'linear-gradient(135deg, #667eea, #764ba2)'}; display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 0.9rem;">
                                                <i class="fas ${hasTrack ? 'fa-check' : 'fa-folder'}"></i>
                                            </div>
                                            <div style="flex: 1;">
                                                <div style="font-weight: 600; margin-bottom: 0.25rem; color: white;">${escapeHtml(crate.name)} ${hasTrack ? `<span style="color: #10b981; font-size: 0.85rem;">${libraryTranslations.crates_already_added}</span>` : ''}</div>
                                                <div style="font-size: 0.85rem; color: #a0aec0;">${crate.track_count || 0} ${libraryTranslations.crates_tracks} • ${(crate.set_duration_minutes || 0).toFixed(1)} ${libraryTranslations.crates_min_set}</div>
                                            </div>
                                            <div style="color: ${hasTrack ? '#10b981' : '#667eea'};">
                                                <i class="fas ${hasTrack ? 'fa-check-circle' : 'fa-plus'}"></i>
                                            </div>
                                        </div>
                                    </button>
                                `;
                            }).join('');
                        }
                    } else {
                        cratesSelectList.innerHTML = `<div style="text-align: center; padding: 2rem; color: #ef4444;">${libraryTranslations.crates_error_loading}</div>`;
                    }
                })
                .catch(error => {
                    console.error('Error loading crates:', error);
                    cratesSelectList.innerHTML = '<div style="text-align: center; padding: 2rem; color: #ef4444;">Error loading crates. Please refresh the page.</div>';
                });
        }

        function closeAddToCrateModal() {
            const modal = document.getElementById('addToCrateModal');
            if (modal) {
                modal.style.setProperty('display', 'none', 'important');
            }
            currentTrackIdForCrate = null;
        }

        function addTrackToCrate(crateId, trackId) {
            // Find crate name for feedback
            const crate = crates.find(c => c.id === crateId);
            const crateName = crate ? crate.name : 'crate';
            
            // Show loading state on the button
            const buttons = document.querySelectorAll(`button[onclick*="addTrackToCrate(${crateId}, ${trackId})"]`);
            buttons.forEach(btn => {
                const originalHTML = btn.innerHTML;
                btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Adding...';
                btn.disabled = true;
                btn.style.opacity = '0.6';
                btn.style.cursor = 'not-allowed';
            });
            
            fetch('/api/add_track_to_crate.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    crate_id: crateId,
                    track_id: trackId
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Restore button state
                    buttons.forEach(btn => {
                        btn.innerHTML = '<i class="fas fa-check"></i> Added!';
                        btn.style.background = 'rgba(16, 185, 129, 0.2)';
                        btn.style.borderColor = '#10b981';
                        btn.style.color = '#10b981';
                    });
                    
                    // Close modal after short delay and show success
                    setTimeout(() => {
                        closeAddToCrateModal();
                        loadCrates();
                        showNotification(`${libraryTranslations.crates_track_added.replace('!', '')} "${crateName}"!`, 'success');
                    }, 500);
                } else {
                    // Restore button state
                    buttons.forEach(btn => {
                        btn.innerHTML = '<i class="fas fa-times"></i> Error';
                        btn.style.background = 'rgba(239, 68, 68, 0.2)';
                        btn.style.borderColor = '#ef4444';
                        btn.disabled = false;
                        btn.style.opacity = '1';
                        btn.style.cursor = 'pointer';
                    });
                    
                    showNotification('Error: ' + (data.error || 'Failed to add track'), 'error');
                }
            })
            .catch(error => {
                console.error('Error adding track to crate:', error);
                
                // Restore button state
                buttons.forEach(btn => {
                    btn.innerHTML = '<i class="fas fa-times"></i> Error';
                    btn.style.background = 'rgba(239, 68, 68, 0.2)';
                    btn.style.borderColor = '#ef4444';
                    btn.disabled = false;
                    btn.style.opacity = '1';
                    btn.style.cursor = 'pointer';
                });
                
                showNotification('Error adding track to crate. Please try again.', 'error');
            });
        }

        // Save crate description
        function saveCrateDescription() {
            const crateId = window.currentCrateData?.id;
            if (!crateId) return;
            
            const descInput = document.getElementById('crateDescriptionInput');
            const saveBtn = document.getElementById('saveDescriptionBtn');
            const descStatus = document.getElementById('descriptionSaveStatus');
            const description = descInput.value.trim();
            
            saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
            saveBtn.disabled = true;
            descStatus.style.display = 'none';
            
            fetch('/api/update_crate_description.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ crate_id: crateId, description: description })
            })
            .then(response => response.json())
            .then(data => {
                saveBtn.innerHTML = '<i class="fas fa-save"></i>';
                saveBtn.disabled = false;
                
                if (data.success) {
                    descStatus.textContent = libraryTranslations.crates_desc_saved || 'Description saved!';
                    descStatus.style.color = '#10b981';
                    descStatus.style.display = 'block';
                    setTimeout(() => { descStatus.style.display = 'none'; }, 2000);
                    
                    // Update crate data in memory
                    if (window.currentCrateData) {
                        window.currentCrateData.description = description;
                    }
                } else {
                    descStatus.textContent = data.error || 'Failed to save';
                    descStatus.style.color = '#ef4444';
                    descStatus.style.display = 'block';
                }
            })
            .catch(error => {
                saveBtn.innerHTML = '<i class="fas fa-save"></i>';
                saveBtn.disabled = false;
                descStatus.textContent = 'Error saving description';
                descStatus.style.color = '#ef4444';
                descStatus.style.display = 'block';
                console.error('Error:', error);
            });
        }

        // Update description visibility toggle button
        function updateDescriptionToggleButton(isPublic, crateIsPublic = null) {
            const btn = document.getElementById('toggleDescriptionVisibilityBtn');
            if (!btn) return;
            
            // Use stored crate public status if not provided
            if (crateIsPublic === null) {
                crateIsPublic = window.currentCrateIsPublic !== false;
            }
            
            // If crate is private, disable the toggle (description visibility only matters for public crates)
            if (!crateIsPublic) {
                btn.disabled = true;
                btn.style.opacity = '0.5';
                btn.style.cursor = 'not-allowed';
                btn.innerHTML = '<i class="fas fa-eye-slash"></i>';
                btn.style.color = '#6b7280';
                btn.style.borderColor = 'rgba(107, 114, 128, 0.2)';
                btn.title = libraryTranslations.crates_desc_private_crate || 'Description visibility only applies to public crates';
                return;
            }
            
            // Crate is public - enable the toggle
            btn.disabled = false;
            btn.style.opacity = '1';
            btn.style.cursor = 'pointer';
            
            if (isPublic) {
                btn.innerHTML = '<i class="fas fa-eye"></i>';
                btn.style.color = '#667eea';
                btn.style.borderColor = 'rgba(102, 126, 234, 0.4)';
                btn.title = libraryTranslations.crates_desc_public || 'Description visible to public';
            } else {
                btn.innerHTML = '<i class="fas fa-eye-slash"></i>';
                btn.style.color = '#6b7280';
                btn.style.borderColor = 'rgba(107, 114, 128, 0.4)';
                btn.title = libraryTranslations.crates_desc_private || 'Description hidden from public';
            }
        }
        
        // Toggle crate description visibility
        function toggleCrateDescriptionVisibility() {
            const crateId = window.currentCrateData?.id;
            if (!crateId) {
                showCrateNotification('No crate selected', 'error');
                return;
            }
            
            // Check if crate is public - description visibility only applies to public crates
            const crateIsPublic = window.currentCrateIsPublic !== false && (window.currentCrateData?.is_public == 1 || window.currentCrateData?.is_public === true);
            if (!crateIsPublic) {
                showCrateNotification('Description visibility only applies to public crates. Make the crate public first.', 'info');
                return;
            }
            
            const btn = document.getElementById('toggleDescriptionVisibilityBtn');
            if (!btn || btn.disabled) return;
            
            const originalHTML = btn.innerHTML;
            btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
            btn.disabled = true;
            
            fetch('/api/toggle_crate_description_visibility.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ crate_id: crateId })
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                return response.text().then(text => {
                    try {
                        return JSON.parse(text);
                    } catch (e) {
                        console.error('Invalid JSON response:', text);
                        throw new Error('Invalid response from server');
                    }
                });
            })
            .then(data => {
                btn.disabled = false;
                if (data && data.success) {
                    // Ensure boolean value
                    const isPublic = (data.is_description_public == 1 || data.is_description_public === true);
                    window.currentCrateDescriptionPublic = isPublic;
                    
                    // Update crate data if it exists
                    if (window.currentCrateData) {
                        window.currentCrateData.is_description_public = isPublic;
                    }
                    
                    updateDescriptionToggleButton(isPublic, window.currentCrateIsPublic);
                    showCrateNotification(data.message || 'Visibility updated successfully', 'success');
                } else {
                    btn.innerHTML = originalHTML;
                    const errorMsg = data?.error || 'Failed to update description visibility';
                    console.error('API error:', data);
                    showCrateNotification(errorMsg, 'error');
                }
            })
            .catch(error => {
                btn.disabled = false;
                btn.innerHTML = originalHTML;
                console.error('Error toggling description visibility:', error);
                showCrateNotification('Failed to update description visibility. Please try again.', 'error');
            });
        }

        // Toggle track visibility within a crate (public/private)
        function toggleCrateTrackVisibility(crateId, trackId, button) {
            const icon = button.querySelector('i');
            const originalIcon = icon.className;
            icon.className = 'fas fa-spinner fa-spin';
            button.disabled = true;
            
            fetch('/api/toggle_crate_track_visibility.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ crate_id: crateId, track_id: trackId })
            })
            .then(response => response.json())
            .then(data => {
                button.disabled = false;
                if (data.success) {
                    const isPublic = data.is_public;
                    button.setAttribute('data-is-public', isPublic ? '1' : '0');
                    button.style.background = isPublic ? 'rgba(102, 126, 234, 0.25)' : 'rgba(107, 114, 128, 0.25)';
                    button.style.color = isPublic ? '#667eea' : '#6b7280';
                    button.style.borderColor = isPublic ? 'rgba(102, 126, 234, 0.4)' : 'rgba(107, 114, 128, 0.4)';
                    button.title = isPublic 
                        ? (libraryTranslations.crates_track_public || 'Track visible in public crate') 
                        : (libraryTranslations.crates_track_private || 'Track hidden from public crate');
                    icon.className = isPublic ? 'fas fa-eye' : 'fas fa-eye-slash';
                    
                    showCrateNotification(data.message, 'success');
                } else {
                    icon.className = originalIcon;
                    showCrateNotification(data.error || 'Failed to update track visibility', 'error');
                }
            })
            .catch(error => {
                button.disabled = false;
                icon.className = originalIcon;
                console.error('Error toggling track visibility:', error);
                showCrateNotification('Error updating visibility. Please try again.', 'error');
            });
        }

        function removeTrackFromCrate(crateId, trackId) {
            if (!confirm(libraryTranslations.crates_remove_confirm)) {
                return;
            }
            
            fetch('/api/remove_track_from_crate.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    crate_id: crateId,
                    track_id: trackId
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    viewCrate(crateId); // Reload crate view
                    loadCrates(); // Reload crates list
                    showNotification(libraryTranslations.crates_track_removed, 'success');
                } else {
                    alert('Error removing track: ' + (data.error || 'Unknown error'));
                }
            })
            .catch(error => {
                console.error('Error removing track from crate:', error);
                alert('Error removing track from crate. Please try again.');
            });
        }

        function deleteCrate(crateId) {
            if (!confirm(libraryTranslations.crates_delete_confirm)) {
                return;
            }
            
            fetch('/api/delete_crate.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    crate_id: crateId
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    loadCrates();
                    showNotification(libraryTranslations.crates_crate_deleted, 'success');
                } else {
                    alert('Error deleting crate: ' + (data.error || 'Unknown error'));
                }
            })
            .catch(error => {
                console.error('Error deleting crate:', error);
                alert('Error deleting crate. Please try again.');
            });
        }

        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        function showNotification(message, type) {
            // Remove any existing notifications first
            const existing = document.querySelectorAll('.crate-notification');
            existing.forEach(n => n.remove());
            
            const notification = document.createElement('div');
            notification.className = 'crate-notification';
            notification.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                padding: 1rem 1.5rem;
                background: ${type === 'success' ? '#10b981' : '#ef4444'};
                color: white;
                border-radius: 12px;
                z-index: 10001;
                box-shadow: 0 8px 24px rgba(0,0,0,0.4);
                display: flex;
                align-items: center;
                gap: 0.75rem;
                font-weight: 600;
                font-size: 1rem;
                min-width: 250px;
                animation: slideInRight 0.3s ease;
                backdrop-filter: blur(10px);
            `;
            
            const icon = type === 'success' ? '<i class="fas fa-check-circle"></i>' : '<i class="fas fa-exclamation-circle"></i>';
            notification.innerHTML = `${icon} <span>${escapeHtml(message)}</span>`;
            document.body.appendChild(notification);
            
            setTimeout(() => {
                notification.style.animation = 'slideOutRight 0.3s ease';
                setTimeout(() => notification.remove(), 300);
            }, 4000);
        }
        
        // Add CSS animations for notifications
        if (!document.getElementById('crate-notification-styles')) {
            const style = document.createElement('style');
            style.id = 'crate-notification-styles';
            style.textContent = `
                @keyframes slideInRight {
                    from {
                        transform: translateX(400px);
                        opacity: 0;
                    }
                    to {
                        transform: translateX(0);
                        opacity: 1;
                    }
                }
                @keyframes slideOutRight {
                    from {
                        transform: translateX(0);
                        opacity: 1;
                    }
                    to {
                        transform: translateX(400px);
                        opacity: 0;
                    }
                }
            `;
            document.head.appendChild(style);
        }

        // Download crate track
        function downloadCrateTrack(trackId, crateId, position) {
            console.log('📥 Download crate track called:', { trackId, crateId, position });
            
            if (!trackId) {
                console.error('❌ Track ID is required');
                if (typeof showNotification === 'function') {
                    showNotification(libraryTranslations.crates_error_loading || 'Error: Track ID is required', 'error');
                } else {
                    alert('Error: Track ID is required');
                }
                return;
            }
            
            if (!crateId) {
                console.error('❌ Crate ID is required');
                if (typeof showNotification === 'function') {
                    showNotification(libraryTranslations.crates_error_loading || 'Error: Crate ID is required', 'error');
                } else {
                    alert('Error: Crate ID is required');
                }
                return;
            }
            
            const url = `/api/download_crate_track.php?track_id=${trackId}&crate_id=${crateId}`;
            console.log('📥 Download URL:', url);
            
            try {
                // Use window.open for better download handling
                const downloadWindow = window.open(url, '_blank');
                
                // If popup was blocked, try using a link element
                if (!downloadWindow || downloadWindow.closed || typeof downloadWindow.closed === 'undefined') {
                    console.log('📥 Popup blocked, using link element instead');
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = ''; // Let the server set the filename
                    link.style.display = 'none';
                    document.body.appendChild(link);
                    link.click();
                    setTimeout(() => {
                        document.body.removeChild(link);
                    }, 100);
                }
                
                console.log('📥 Download initiated');
            } catch (error) {
                console.error('❌ Download error:', error);
                if (typeof showNotification === 'function') {
                    showNotification('Error initiating download. Please try again.', 'error');
                } else {
                    alert('Error initiating download. Please try again.');
                }
            }
        }
        
        // Make function globally accessible
        window.downloadCrateTrack = downloadCrateTrack;
        
        // Download crate as ZIP
        function downloadCrateAsZip() {
            console.log('📦 Download crate as ZIP called');
            
            if (!window.currentCrateData || !window.currentCrateData.id) {
                console.error('❌ No crate data available');
                if (typeof showNotification === 'function') {
                    showNotification('No crate selected. Please open a crate first.', 'error');
                } else {
                    alert('No crate selected. Please open a crate first.');
                }
                return;
            }
            
            const crateId = window.currentCrateData.id;
            const url = `/api/download_crate_zip.php?crate_id=${crateId}`;
            console.log('📦 Download ZIP URL:', url);
            
            // Show loading state
            const downloadBtn = document.getElementById('downloadCrateBtn');
            if (downloadBtn) {
                const originalHTML = downloadBtn.innerHTML;
                downloadBtn.disabled = true;
                downloadBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Preparing...';
                
                // Reset button after 5 seconds (download should have started)
                setTimeout(() => {
                    downloadBtn.disabled = false;
                    downloadBtn.innerHTML = originalHTML;
                }, 5000);
            }
            
            try {
                // Use window.open for better download handling
                const downloadWindow = window.open(url, '_blank');
                
                // If popup was blocked, try using a link element
                if (!downloadWindow || downloadWindow.closed || typeof downloadWindow.closed === 'undefined') {
                    console.log('📦 Popup blocked, using link element instead');
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = ''; // Let the server set the filename
                    link.style.display = 'none';
                    document.body.appendChild(link);
                    link.click();
                    setTimeout(() => {
                        document.body.removeChild(link);
                    }, 100);
                }
                
                console.log('📦 ZIP download initiated');
                
                if (typeof showNotification === 'function') {
                    showNotification('Preparing ZIP download... This may take a moment.', 'info');
                }
            } catch (error) {
                console.error('❌ ZIP download error:', error);
                if (downloadBtn) {
                    downloadBtn.disabled = false;
                    downloadBtn.innerHTML = '<i class="fas fa-download"></i> ' + (libraryTranslations.crates_download_all || 'Download Crate');
                }
                if (typeof showNotification === 'function') {
                    showNotification('Error initiating ZIP download. Please try again.', 'error');
                } else {
                    alert('Error initiating ZIP download. Please try again.');
                }
            }
        }
        window.downloadCrateAsZip = downloadCrateAsZip;
        
        // Add to cart from crate (simplified version for crate tracks)
        // Define and assign to window immediately for global access
        window.addToCartFromCrate = function(trackId, buttonElement) {
            // Get title and price from data attributes
            const button = buttonElement || event.target.closest('.btn-cart');
            const title = button ? (button.getAttribute('data-track-title') || 'Untitled Track') : 'Untitled Track';
            const price = button ? parseFloat(button.getAttribute('data-track-price') || 0) : 0;
            
            console.log('🛒 Adding to cart from crate:', { trackId, title, price });
            
            if (!<?= $user_id ? 'true' : 'false' ?>) {
                if (typeof showNotification === 'function') {
                    showNotification('Please log in to add tracks to cart', 'warning');
                } else {
                    alert('Please log in to add tracks to cart');
                }
                setTimeout(() => {
                    window.location.href = '/auth/login.php?redirect=' + encodeURIComponent(window.location.pathname + window.location.search);
                }, 2000);
                return;
            }
            
            const originalHTML = button ? button.innerHTML : '';
            
            // Show loading state
            if (button) {
                button.disabled = true;
                button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
            }
            
            // Send to cart (default to 'free' artist plan)
            const formData = new FormData();
            formData.append('track_id', trackId);
            formData.append('action', 'add');
            formData.append('artist_plan', 'free');
            
            fetch('/cart.php', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                console.log('🛒 Response status:', response.status);
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                return response.json();
            })
            .then(data => {
                console.log('🛒 Cart response:', data);
                
                if (!data.success) {
                    throw new Error(data.message || 'Failed to add to cart');
                }
                
                // Show success notification
                if (price == 0 || !price) {
                    if (typeof showNotification === 'function') {
                        const message = (libraryTranslations.added_to_cart_free || `🎵 "${title}" added to cart for FREE! 🛒`).replace(':title', title);
                        showNotification(message, 'success');
                    }
                } else {
                    if (typeof showNotification === 'function') {
                        const message = (libraryTranslations.added_to_cart || `"${title}" added to cart! ($${price})`).replace(':title', title).replace(':price', price);
                        showNotification(message, 'success');
                    }
                }
                
                // Update cart counter in header - use querySelectorAll to update all instances
                const cartCounts = document.querySelectorAll('.cart-count, .cart-counter');
                if (cartCounts.length > 0 && data.cart_count !== undefined) {
                    cartCounts.forEach(count => {
                        count.textContent = data.cart_count;
                        // Show the badge if count > 0
                        if (data.cart_count > 0) {
                            count.style.display = 'flex';
                            if (count.classList.contains('cart-counter')) {
                                count.style.display = 'block';
                            }
                        } else {
                            count.style.display = 'none';
                        }
                    });
                } else if (cartCounts.length > 0) {
                    // Fallback: manually increment if API didn't return count
                    cartCounts.forEach(count => {
                        const currentCount = parseInt(count.textContent) || 0;
                        count.textContent = currentCount + 1;
                        count.style.display = 'flex';
                        if (count.classList.contains('cart-counter')) {
                            count.style.display = 'block';
                        }
                    });
                }
                
                // Show success state on button
                if (button) {
                    button.innerHTML = '<i class="fas fa-check"></i>';
                    button.style.background = 'rgba(16, 185, 129, 0.3)';
                    button.style.color = '#10b981';
                    
                    setTimeout(() => {
                        button.innerHTML = originalHTML;
                        button.style.background = '';
                        button.style.color = '';
                        button.disabled = false;
                    }, 2000);
                }
            })
            .catch(error => {
                console.error('🛒 Cart error:', error);
                if (typeof showNotification === 'function') {
                    showNotification('Failed to add to cart: ' + error.message, 'error');
                } else {
                    alert('Failed to add to cart: ' + error.message);
                }
                
                // Restore button
                if (button) {
                    button.innerHTML = originalHTML;
                    button.disabled = false;
                }
            });
        };
        
        // Drag and Drop for reordering tracks
        let draggedTrackId = null;
        let draggedElement = null;
        
        function handleDragStart(e, trackId) {
            draggedTrackId = trackId;
            draggedElement = e.currentTarget;
            e.currentTarget.style.opacity = '0.5';
            e.dataTransfer.effectAllowed = 'move';
        }
        
        function handleDragOver(e) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.dataTransfer.dropEffect = 'move';
            
            const trackItem = e.currentTarget.closest('.crate-track-item');
            if (trackItem && trackItem !== draggedElement) {
                trackItem.style.borderTop = '2px solid #667eea';
            }
            return false;
        }
        
        function handleDrop(e, targetTrackId, crateId) {
            if (e.stopPropagation) {
                e.stopPropagation();
            }
            
            if (draggedTrackId === targetTrackId) {
                return false;
            }
            
            const trackItem = e.currentTarget.closest('.crate-track-item');
            if (trackItem) {
                trackItem.style.borderTop = '';
            }
            
            // Get current order
            const trackItems = Array.from(document.querySelectorAll('.crate-track-item'));
            const currentOrder = trackItems.map(item => parseInt(item.dataset.trackId));
            
            // Find indices
            const draggedIndex = currentOrder.indexOf(draggedTrackId);
            const targetIndex = currentOrder.indexOf(targetTrackId);
            
            // Reorder array
            const newOrder = [...currentOrder];
            newOrder.splice(draggedIndex, 1);
            newOrder.splice(targetIndex, 0, draggedTrackId);
            
            // Update positions in UI
            updateTrackOrder(crateId, newOrder);
            
            return false;
        }
        
        function handleDragEnd(e) {
            e.currentTarget.style.opacity = '1';
            const trackItems = document.querySelectorAll('.crate-track-item');
            trackItems.forEach(item => {
                item.style.borderTop = '';
            });
            draggedTrackId = null;
            draggedElement = null;
        }
        
        function updateTrackOrder(crateId, trackOrder) {
            // Show loading state
            const tracksList = document.getElementById('crateTracksList');
            const originalHTML = tracksList.innerHTML;
            tracksList.innerHTML = `<div style="text-align: center; padding: 2rem; color: #a0aec0;"><i class="fas fa-spinner fa-spin" style="font-size: 1.5rem;"></i><div>${libraryTranslations.crates_updating_order}</div></div>`;
            
            fetch('/api/update_crate_track_order.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    crate_id: crateId,
                    track_order: trackOrder
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Reload crate view
                    viewCrate(crateId);
                    showNotification(libraryTranslations.crates_order_updated, 'success');
                } else {
                    tracksList.innerHTML = originalHTML;
                    showNotification('Error updating order: ' + (data.error || 'Unknown error'), 'error');
                }
            })
            .catch(error => {
                console.error('Error updating track order:', error);
                tracksList.innerHTML = originalHTML;
                showNotification('Error updating track order. Please try again.', 'error');
            });
        }
        
        function initCrateDragAndDrop() {
            // Add visual feedback for drag over
            const trackItems = document.querySelectorAll('.crate-track-item');
            trackItems.forEach(item => {
                item.addEventListener('dragover', function(e) {
                    if (e.preventDefault) {
                        e.preventDefault();
                    }
                    if (this !== draggedElement) {
                        this.style.borderTop = '2px solid #667eea';
                    }
                });
                
                item.addEventListener('dragleave', function(e) {
                    this.style.borderTop = '';
                });
            });
        }
        
        // Close modals when clicking outside
        document.addEventListener('click', function(e) {
            if (e.target.classList.contains('modal')) {
                e.target.style.display = 'none';
            }
        });
        
        // Track Image Download Handler
        function handleTrackImageDownload(e) {
            e.preventDefault();
            e.stopPropagation();
            
            const imageUrl = e.currentTarget.dataset.imageUrl;
            const trackTitle = e.currentTarget.dataset.trackTitle || 'track-image';
            
            if (!imageUrl) return;
            
            // Create a temporary anchor element to trigger download
            const link = document.createElement('a');
            link.href = imageUrl;
            
            // Extract filename from URL or create one from track title
            let filename = imageUrl.split('/').pop();
            if (!filename || filename === imageUrl) {
                // If no filename in URL, create one from track title
                const sanitizedTitle = trackTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase();
                const extension = imageUrl.match(/\.(jpg|jpeg|png|gif|webp)$/i);
                filename = sanitizedTitle + (extension ? extension[0] : '.jpg');
            }
            
            link.download = filename;
            link.target = '_blank';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
        
        // Track Image Upload Handler
        function handleTrackImageUpload(e) {
            const file = e.target.files[0];
            if (!file) return;
            
            const trackId = e.target.dataset.trackId;
            const container = e.target.closest('.track-image-container, .track-icon');
            const overlay = container ? container.querySelector('.track-image-upload-overlay') : null;
            
            if (!trackId || !container) return;
            
                    // Validate file type
                    const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
                    if (!allowedTypes.includes(file.type)) {
                        if (typeof showNotification === 'function') {
                            showNotification(libraryTranslations.image_invalid_file_type, 'error');
                        } else {
                            alert(libraryTranslations.image_invalid_file_type);
                        }
                        e.target.value = '';
                        return;
                    }
                    
                    // Validate file size (5MB max)
                    if (file.size > 5 * 1024 * 1024) {
                        if (typeof showNotification === 'function') {
                            showNotification(libraryTranslations.image_file_too_large, 'error');
                        } else {
                            alert(libraryTranslations.image_file_too_large);
                        }
                        e.target.value = '';
                        return;
                    }
            
            // Show uploading state
            if (overlay) {
                overlay.classList.add('uploading');
                const uploadIcon = overlay.querySelector('.track-image-upload-icon');
                if (uploadIcon) {
                    uploadIcon.className = 'fas fa-spinner track-image-upload-icon';
                }
            }
            
            // Create FormData
            const formData = new FormData();
            formData.append('cover_image', file);
            formData.append('track_id', trackId);
            
            // Upload image
            fetch('/api/upload_track_cover.php', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.success && data.data && data.data.image_url) {
                    const newImageUrl = data.data.image_url;
                    
                    // Update the image source
                    const img = container.querySelector('.track-image');
                    if (img) {
                        img.src = newImageUrl + '?t=' + Date.now(); // Add timestamp to prevent caching
                        // Update data attribute
                        container.setAttribute('data-image-url', newImageUrl);
                        // Update download button if it exists
                        const downloadBtn = container.querySelector('.track-image-download-btn');
                        if (downloadBtn) {
                            downloadBtn.setAttribute('data-image-url', newImageUrl);
                        }
                    } else {
                        // If no image exists, convert icon to image container
                        const iconContainer = container;
                        if (iconContainer.classList.contains('track-icon')) {
                            const trackTitle = iconContainer.closest('.track-card-modern')?.querySelector('.track-name')?.textContent?.trim() || 'track-image';
                            iconContainer.classList.remove('track-icon');
                            iconContainer.classList.add('track-image-container');
                            iconContainer.setAttribute('data-image-url', newImageUrl);
                            iconContainer.innerHTML = `
                                <img src="${newImageUrl}?t=${Date.now()}" alt="Track cover" class="track-image" loading="lazy">
                                <div class="track-image-upload-overlay">
                                    <button type="button" class="track-image-action-button track-image-download-btn" data-image-url="${newImageUrl}" data-track-title="${trackTitle.replace(/"/g, '&quot;')}" title="${libraryTranslations.image_download}">
                                        <i class="fas fa-download track-image-download-icon"></i>
                                    </button>
                                    <label class="track-image-action-button" for="track-image-upload-dynamic-${trackId}" title="${libraryTranslations.image_upload || 'Upload image'}">
                                        <i class="fas fa-camera track-image-upload-icon"></i>
                                        <input type="file" id="track-image-upload-dynamic-${trackId}" class="track-image-upload-input" accept="image/jpeg,image/jpg,image/png,image/gif,image/webp" data-track-id="${trackId}">
                                    </label>
                                </div>
                            `;
                            // Re-attach event listeners
                            const newInput = iconContainer.querySelector('.track-image-upload-input');
                            if (newInput) {
                                newInput.addEventListener('change', handleTrackImageUpload);
                            }
                            const newDownloadBtn = iconContainer.querySelector('.track-image-download-btn');
                            if (newDownloadBtn) {
                                newDownloadBtn.addEventListener('click', handleTrackImageDownload);
                            }
                        }
                    }
                    
                    if (typeof showNotification === 'function') {
                        showNotification('✅ ' + libraryTranslations.image_upload_success, 'success');
                    }
                } else {
                    throw new Error(data.error || libraryTranslations.image_upload_failed);
                }
            })
            .catch(error => {
                console.error('Error uploading track image:', error);
                if (typeof showNotification === 'function') {
                    const errorMsg = error.message ? libraryTranslations.image_upload_failed + ': ' + error.message : libraryTranslations.image_upload_failed_unknown;
                    showNotification('❌ ' + errorMsg, 'error');
                } else {
                    alert(libraryTranslations.image_upload_failed_retry);
                }
            })
            .finally(() => {
                // Reset uploading state
                if (overlay) {
                    overlay.classList.remove('uploading');
                    const uploadIcon = overlay.querySelector('.track-image-upload-icon');
                    if (uploadIcon) {
                        uploadIcon.className = 'fas fa-camera track-image-upload-icon';
                    }
                }
                // Reset input
                e.target.value = '';
            });
        }
        
        // Open stem separation modal for a specific track
        function openStemSeparationForTrack(trackId) {
            if (typeof openAdvancedFunctionsModal === 'function') {
                openAdvancedFunctionsModal('vocalRemoval', trackId);
            } else {
                // Fallback: redirect to studio
                if (window.ajaxNavigation) {
                    window.ajaxNavigation.navigateToPage('/studio.php');
                } else {
                    window.location.href = '/studio.php';
                }
            }
        }
        
        // Show stems modal for a track that has stems
        function showStemsModal(trackId) {
            // Fetch track data to get stems
            fetch(`/api/get_track_details.php?track_id=${trackId}`)
                .then(response => response.json())
                .then(data => {
                    if (data.success && data.track) {
                        const track = data.track;
                        const metadata = track.metadata || {};
                        
                        // Check both stem_files and stems arrays
                        let stemFiles = metadata.stem_files || [];
                        if (stemFiles.length === 0 && metadata.stems) {
                            // Convert stems format to stem_files format (legacy support)
                            stemFiles = metadata.stems.map(stem => ({
                                name: stem.title || stem.type || stem.stem_name || 'Stem',
                                url: stem.audio_url || stem.url || '',
                                type: stem.type || 'unknown',
                                index: stem.index || 0
                            }));
                        }
                        
                        // Normalize stem data structure
                        stemFiles = stemFiles.map((stem, idx) => ({
                            name: stem.name || stem.title || stem.stem_name || `Stem ${idx + 1}`,
                            url: stem.url || stem.audio_url || stem.original_url || '',
                            type: stem.type || 'unknown',
                            index: stem.index !== undefined ? stem.index : idx
                        })).filter(stem => stem.url); // Filter out stems without URLs
                        
                        if (stemFiles.length === 0) {
                            alert('No stems available for this track.');
                            return;
                        }
                        
                        // Populate stems grid
                        const stemsGrid = document.getElementById('stemsGrid');
                        if (!stemsGrid) {
                            console.error('Stems grid not found');
                            return;
                        }
                        
                        stemsGrid.innerHTML = '';
                        
                        stemFiles.forEach((stem, index) => {
                            const stemName = stem.name;
                            const stemUrl = stem.url;
                            const stemType = stem.type;
                            
                            // Escape for HTML/JavaScript
                            const safeStemName = stemName.replace(/'/g, "\\'").replace(/"/g, '&quot;');
                            const safeStemUrl = stemUrl.replace(/'/g, "\\'").replace(/"/g, '&quot;');
                            const safeFileName = stemName.replace(/[^a-z0-9]/gi, '_') + '.mp3';
                            
                            const stemCard = document.createElement('div');
                            stemCard.className = 'variation-card';
                            stemCard.innerHTML = `
                                <div class="variation-info">
                                    <h3>${stemName}</h3>
                                    <p style="color: #a0aec0; font-size: 0.9rem; margin-top: 0.5rem;">${stemType}</p>
                                    <div class="variation-actions">
                                        <button class="btn-play-variation" onclick="playStem('${safeStemUrl}', '${safeStemName}')">
                                            <i class="fas fa-play"></i> Play
                                        </button>
                                        <a href="${safeStemUrl}" download="${safeFileName}" class="btn-download-variation">
                                            <i class="fas fa-download"></i> Download
                                        </a>
                                    </div>
                                </div>
                            `;
                            stemsGrid.appendChild(stemCard);
                        });
                        
                        // Show modal
                        const modal = document.getElementById('stemsModal');
                        if (modal) {
                            modal.classList.add('active');
                        }
                    } else {
                        alert('Failed to load track stems.');
                    }
                })
                .catch(error => {
                    console.error('Error loading stems:', error);
                    alert('Error loading stems. Please try again.');
                });
        }
        
        // Close stems modal
        function closeStemsModal() {
            const modal = document.getElementById('stemsModal');
            if (modal) {
                modal.classList.remove('active');
            }
        }
        
        // Play a stem
        function playStem(stemUrl, stemName) {
            if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                window.enhancedGlobalPlayer.playTrack(stemUrl, stemName, 'SoundStudioPro');
            } else {
                // Fallback: create audio element
                const audio = new Audio(stemUrl);
                audio.play().catch(err => {
                    console.error('Error playing stem:', err);
                    alert('Error playing stem. Please try downloading it instead.');
                });
            }
        }
        
        // Analyze Single Track from Library
        let isAnalyzing = false;
        let currentAnalyzingTrackId = null;
        
        async function analyzeSingleTrack(trackId, trackTitle) {
            if (isAnalyzing) {
                showNotification('Analysis already in progress. Please wait.', 'warning');
                return;
            }
            
            isAnalyzing = true;
            currentAnalyzingTrackId = trackId;
            
            // Create analysis overlay
            const overlay = createAnalysisOverlay();
            setTimeout(() => overlay.classList.add('active'), 10);
            updateAnalysisStatus('loading', 10);
            
            try {
                // Get signed audio URL with proper authentication
                updateAnalysisStatus('loading', 15);
                const tokenResponse = await fetch(`/api/get_audio_token.php?track_id=${trackId}`);
                
                if (!tokenResponse.ok) {
                    throw new Error(`Failed to get audio token: HTTP ${tokenResponse.status}`);
                }
                
                const tokenData = await tokenResponse.json();
                
                if (!tokenData.success || !tokenData.url) {
                    throw new Error(tokenData.error || 'Failed to get valid audio URL');
                }
                
                let audioUrl = tokenData.url;
                
                // Make URL absolute if it's relative
                if (!audioUrl.startsWith('http')) {
                    audioUrl = window.location.origin + audioUrl;
                }
                
                if (!audioUrl || audioUrl.includes('error')) {
                    throw new Error('Invalid audio URL received');
                }
                
                // Load simple analyzer script if needed
                if (!window.simpleAudioAnalyzer) {
                    updateAnalysisStatus('loading', 20);
                    await loadSimpleAnalyzerScript();
                }
                
                if (!window.simpleAudioAnalyzer) {
                    throw new Error('Audio analyzer not loaded. Please refresh the page.');
                }
                
                updateAnalysisStatus('decoding', 30);
                
                // Analyze audio with simple, lightweight analyzer
                const result = await window.simpleAudioAnalyzer.analyzeAudio(audioUrl, (stage, progress) => {
                    if (stage === 'loading') {
                        updateAnalysisStatus('loading', progress);
                    } else if (stage === 'decoding') {
                        updateAnalysisStatus('decoding', progress);
                    } else if (stage === 'detecting_bpm' || stage === 'bpm') {
                        updateAnalysisStatus('bpm', progress);
                    } else if (stage === 'detecting_key' || stage === 'key') {
                        updateAnalysisStatus('key', progress);
                    } else if (stage === 'complete') {
                        updateAnalysisStatus('complete', 100);
                    }
                });
                
                if (!result || !result.bpm || !result.key) {
                    throw new Error('Analysis returned incomplete results');
                }
                
                // Show completion
                updateAnalysisStatus('complete', 100);
                await new Promise(resolve => setTimeout(resolve, 500));
                overlay.classList.remove('active');
                setTimeout(() => overlay.remove(), 300);
                
                // Update UI
                const roundedBPM = Math.round(result.bpm * 10) / 10;
                updateTrackCardBPM(trackId, roundedBPM);
                updateTrackCardKey(trackId, result.key, result.camelot || '');
                
                // Save to server
                const saveResponse = await fetch('/api/save_audio_analysis.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        track_id: trackId,
                        bpm: roundedBPM,
                        key: result.key,
                        camelot: result.camelot || '',
                        energy: result.energy || 'Medium',
                        confidence: result.confidence || 50
                    })
                });
                
                const saveData = await saveResponse.json();
                if (saveData.success) {
                    showNotification(`Analysis complete for "${trackTitle}"`, 'success');
                    // Reload page to show updated values
                    setTimeout(() => window.location.reload(), 1000);
                } else {
                    throw new Error(saveData.error || 'Failed to save analysis');
                }
                
            } catch (error) {
                console.error('Analysis error:', error);
                overlay.classList.remove('active');
                setTimeout(() => overlay.remove(), 300);
                showNotification('Analysis failed: ' + error.message, 'error');
            } finally {
                isAnalyzing = false;
                currentAnalyzingTrackId = null;
            }
        }
        
        // Helper functions
        function createAnalysisOverlay() {
            const overlay = document.createElement('div');
            overlay.className = 'analysis-overlay';
            overlay.innerHTML = `
                <div class="analysis-modal">
                    <div class="analysis-modal-header">
                        <h3>Analyzing Audio</h3>
                        <p>Detecting BPM and musical key...</p>
                    </div>
                    <div class="analysis-spinner"></div>
                    <div class="analysis-progress">
                        <div class="analysis-progress-bar" id="analysisProgressBar"></div>
                    </div>
                    <div class="analysis-status" id="analysisStatus">
                        <div class="analysis-status-item">
                            <span class="analysis-status-label">Loading audio...</span>
                            <span class="analysis-status-value">
                                <i class="fas fa-spinner fa-spin"></i>
                            </span>
                        </div>
                    </div>
                </div>
            `;
            document.body.appendChild(overlay);
            return overlay;
        }
        
        function updateAnalysisStatus(stage, progress) {
            const statusEl = document.getElementById('analysisStatus');
            const progressBar = document.getElementById('analysisProgressBar');
            
            if (progressBar) {
                progressBar.style.width = progress + '%';
            }
            
            if (statusEl) {
                const stages = {
                    'loading': { label: 'Loading audio file...', icon: 'fa-spinner' },
                    'decoding': { label: 'Decoding audio data...', icon: 'fa-spinner' },
                    'bpm': { label: 'Detecting BPM...', icon: 'fa-spinner' },
                    'key': { label: 'Detecting musical key...', icon: 'fa-spinner' },
                    'complete': { label: 'Analysis complete!', icon: 'fa-check' }
                };
                
                const currentStage = stages[stage] || { label: stage, icon: 'fa-spinner' };
                
                statusEl.innerHTML = `
                    <div class="analysis-status-item">
                        <span class="analysis-status-label">${currentStage.label}</span>
                        <span class="analysis-status-value">
                            <i class="fas ${currentStage.icon} ${stage !== 'complete' ? 'fa-spin' : ''}"></i>
                        </span>
                    </div>
                `;
            }
        }
        
        async function loadSimpleAnalyzerScript() {
            if (window.simpleAnalyzerScriptLoaded) {
                return Promise.resolve();
            }
            
            return new Promise((resolve, reject) => {
                const script = document.createElement('script');
                script.src = '/js/audio_analyzer_simple.js';
                script.async = true;
                script.onload = () => {
                    window.simpleAnalyzerScriptLoaded = true;
                    setTimeout(() => {
                        try {
                            const analyzer = window.simpleAudioAnalyzer;
                            if (analyzer) {
                                resolve();
                            } else {
                                reject(new Error('Analyzer failed to initialize'));
                            }
                        } catch (e) {
                            reject(new Error('Analyzer initialization error: ' + e.message));
                        }
                    }, 100);
                };
                script.onerror = () => reject(new Error('Failed to load analyzer script'));
                document.head.appendChild(script);
            });
        }
        
        function updateTrackCardBPM(trackId, bpm) {
            const bpmMeta = document.getElementById(`bpm-meta-${trackId}`);
            if (bpmMeta) {
                const bpmDisplay = bpmMeta.querySelector('.bpm-value-display');
                if (bpmDisplay) {
                    bpmDisplay.textContent = bpm;
                }
                // Add edit button if it doesn't exist
                if (!bpmMeta.querySelector('.bpm-edit-btn')) {
                    const editBtn = document.createElement('button');
                    editBtn.className = 'bpm-edit-btn';
                    editBtn.onclick = () => openBPMCorrectionModal(trackId, bpm);
                    editBtn.title = 'Edit BPM';
                    editBtn.style.cssText = 'background: none; border: none; color: #667eea; cursor: pointer; margin-left: 4px; padding: 2px 4px;';
                    editBtn.innerHTML = '<i class="fas fa-edit" style="font-size: 0.75rem;"></i>';
                    bpmMeta.appendChild(editBtn);
                }
            }
        }
        
        function updateTrackCardKey(trackId, key, camelot) {
            const keyMeta = document.getElementById(`key-meta-${trackId}`);
            if (keyMeta) {
                const keyDisplay = keyMeta.querySelector('.key-value-display');
                if (keyDisplay) {
                    keyDisplay.textContent = key;
                }
                if (camelot) {
                    let camelotDisplay = keyMeta.querySelector('.camelot-value-display');
                    if (!camelotDisplay) {
                        camelotDisplay = document.createElement('span');
                        camelotDisplay.className = 'camelot-value-display';
                        keyDisplay.parentNode.insertBefore(camelotDisplay, keyDisplay.nextSibling);
                    }
                    camelotDisplay.textContent = `(${camelot})`;
                }
                // Add edit button if it doesn't exist
                if (!keyMeta.querySelector('.key-edit-btn')) {
                    const editBtn = document.createElement('button');
                    editBtn.className = 'key-edit-btn';
                    editBtn.onclick = () => openKeyCorrectionModal(trackId, key, camelot);
                    editBtn.title = 'Edit Key';
                    editBtn.style.cssText = 'background: none; border: none; color: #667eea; cursor: pointer; margin-left: 4px; padding: 2px 4px;';
                    editBtn.innerHTML = '<i class="fas fa-edit" style="font-size: 0.75rem;"></i>';
                    keyMeta.appendChild(editBtn);
                }
            }
        }
        
        // Batch Analyze Tracks
        async function batchAnalyzeTracks() {
            if (!confirm('This will analyze all tracks that need BPM and key detection. This may take a while. Continue?')) {
                return;
            }
            
            // Get tracks needing analysis
            const response = await fetch('/api/get_analysis_status.php?user_id=<?= $_SESSION['user_id'] ?>');
            const data = await response.json();
            
            if (!data.success || !data.tracks || data.tracks.length === 0) {
                alert('No tracks need analysis!');
                return;
            }
            
            const tracks = data.tracks;
            let analyzed = 0;
            let failed = 0;
            let current = 0;
            
            // Create progress modal
            const modal = document.createElement('div');
            modal.style.cssText = 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.8); z-index: 10000; display: flex; align-items: center; justify-content: center;';
            modal.innerHTML = `
                <div style="background: #1a1a2e; padding: 2rem; border-radius: 16px; max-width: 500px; width: 90%;">
                    <h3 style="color: white; margin: 0 0 1rem 0;">Batch Analysis</h3>
                    <div style="color: rgba(255,255,255,0.8); margin-bottom: 1rem;">
                        <div>Progress: <span id="batchProgress">0</span> / ${tracks.length}</div>
                        <div>Analyzed: <span id="batchAnalyzed">0</span></div>
                        <div>Failed: <span id="batchFailed">0</span></div>
                    </div>
                    <div style="background: rgba(255,255,255,0.1); height: 8px; border-radius: 4px; overflow: hidden; margin-bottom: 1rem;">
                        <div id="batchProgressBar" style="background: #667eea; height: 100%; width: 0%; transition: width 0.3s;"></div>
                    </div>
                    <div id="batchCurrentTrack" style="color: rgba(255,255,255,0.6); font-size: 0.9rem; margin-bottom: 1rem;"></div>
                    <button onclick="this.closest('div[style*=\"position: fixed\"]').remove()" style="background: #667eea; color: white; border: none; padding: 0.75rem 1.5rem; border-radius: 8px; cursor: pointer;">Close</button>
                </div>
            `;
            document.body.appendChild(modal);
            
            // Load simple analyzer script
            if (!window.simpleAudioAnalyzer) {
                const script = document.createElement('script');
                script.src = '/js/audio_analyzer_simple.js';
                await new Promise((resolve, reject) => {
                    script.onload = resolve;
                    script.onerror = reject;
                    document.head.appendChild(script);
                });
                await new Promise(resolve => setTimeout(resolve, 200));
            }
            
            // Analyze each track
            for (const track of tracks) {
                current++;
                document.getElementById('batchCurrentTrack').textContent = `Analyzing: ${track.title}`;
                document.getElementById('batchProgress').textContent = current;
                document.getElementById('batchProgressBar').style.width = (current / tracks.length * 100) + '%';
                
                try {
                    // Get signed audio URL via API
                    const tokenResponse = await fetch(`/api/get_audio_token.php?track_id=${track.id}`);
                    if (!tokenResponse.ok) {
                        throw new Error('Failed to get audio token');
                    }
                    
                    const tokenData = await tokenResponse.json();
                    if (!tokenData.success || !tokenData.url) {
                        throw new Error(tokenData.error || 'Invalid audio URL');
                    }
                    
                    let audioUrl = tokenData.url;
                    if (!audioUrl.startsWith('http')) {
                        audioUrl = window.location.origin + audioUrl;
                    }
                    
                    // Analyze with simple, lightweight analyzer
                    const result = await window.simpleAudioAnalyzer.analyzeAudio(audioUrl);
                    
                    if (!result || !result.bpm || !result.key) {
                        throw new Error('Analysis returned incomplete results');
                    }
                    
                    // Save to server
                    const saveResponse = await fetch('/api/save_audio_analysis.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            track_id: track.id,
                            bpm: result.bpm,
                            key: result.key,
                            camelot: result.camelot || '',
                            energy: result.energy || 'Medium',
                            confidence: result.confidence || 50
                        })
                    });
                    
                    const saveData = await saveResponse.json();
                    if (saveData.success) {
                        analyzed++;
                        document.getElementById('batchAnalyzed').textContent = analyzed;
                        console.log(`✅ Track ${track.id} (${track.title}): BPM=${saveData.data?.bpm || result.bpm}, Key=${saveData.data?.key || result.key}, Saved=${saveData.success}`);
                    } else {
                        console.error(`❌ Save failed for track ${track.id}:`, saveData.error);
                        throw new Error(saveData.error || 'Save failed');
                    }
                } catch (error) {
                    console.error(`Failed to analyze track ${track.id}:`, error);
                    failed++;
                    document.getElementById('batchFailed').textContent = failed;
                }
                
                // Delay between tracks to prevent browser blocking
                await new Promise(resolve => setTimeout(resolve, 500));
            }
            
            // Show completion
            document.getElementById('batchCurrentTrack').textContent = `Complete! Analyzed ${analyzed}, Failed ${failed}. Reloading page...`;
            
            // Force a small delay to ensure all saves are complete
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            // Reload page to refresh analysis status
            setTimeout(() => {
                window.location.reload();
            }, 2000);
        }
        
        // Handle mastered version upload
        function handleMasteredUpload(event) {
            const input = event.target;
            const trackId = input.getAttribute('data-track-id');
            const file = input.files[0];
            
            if (!file) return;
            
            // Validate file type - MP3 only
            const allowedTypes = ['audio/mpeg', 'audio/mp3'];
            if (!allowedTypes.includes(file.type) && !file.name.match(/\.mp3$/i)) {
                alert('Please upload an MP3 file only');
                input.value = '';
                return;
            }
            
            // Validate file size (max 50MB)
            if (file.size > 50 * 1024 * 1024) {
                alert('File size must be less than 50MB');
                input.value = '';
                return;
            }
            
            // Show loading state
            const button = input.closest('.action-icon-btn');
            const originalHTML = button.innerHTML;
            button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
            button.style.pointerEvents = 'none';
            
            // Create FormData
            const formData = new FormData();
            formData.append('track_id', trackId);
            formData.append('mastered_file', file);
            formData.append('action', 'upload_mastered');
            
            // Upload file
            fetch('/api/upload_mastered.php', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('Mastered version uploaded successfully!');
                    // Reload page to show updated version
                    location.reload();
                } else {
                    alert('Error: ' + (data.error || 'Failed to upload mastered version'));
                    button.innerHTML = originalHTML;
                    button.style.pointerEvents = '';
                }
            })
            .catch(error => {
                console.error('Upload error:', error);
                alert('Error uploading mastered version. Please try again.');
                button.innerHTML = originalHTML;
                button.style.pointerEvents = '';
            })
            .finally(() => {
                input.value = '';
            });
        }
        
        document.addEventListener('DOMContentLoaded', function() {
            // Handle track image uploads
            const uploadInputs = document.querySelectorAll('.track-image-upload-input');
            uploadInputs.forEach(input => {
                input.addEventListener('change', handleTrackImageUpload);
            });
            
            // Handle track image downloads
            const downloadButtons = document.querySelectorAll('.track-image-download-btn');
            downloadButtons.forEach(btn => {
                btn.addEventListener('click', handleTrackImageDownload);
            });
            
            // Handle mastered version uploads
            const masteredInputs = document.querySelectorAll('.mastered-upload-input');
            masteredInputs.forEach(input => {
                input.addEventListener('change', handleMasteredUpload);
            });
        });
        
        // BPM Correction Modal
        let currentBPMTrackId = null;
        function openBPMCorrectionModal(trackId, currentBPM) {
            currentBPMTrackId = trackId;
            const modal = document.getElementById('bpmCorrectionModal');
            const input = document.getElementById('bpmInput');
            
            if (input) {
                input.value = currentBPM || '';
            }
            
            if (modal) {
                modal.style.display = 'flex';
                document.body.style.overflow = 'hidden';
                setTimeout(() => {
                    if (input) {
                        input.focus();
                        input.select();
                    }
                }, 100);
            }
        }
        
        function closeBPMCorrectionModal() {
            const modal = document.getElementById('bpmCorrectionModal');
            if (modal) {
                modal.style.display = 'none';
                document.body.style.overflow = '';
            }
            currentBPMTrackId = null;
        }
        
        async function saveBPMCorrection() {
            const input = document.getElementById('bpmInput');
            if (!input || !currentBPMTrackId) return;
            
            const bpmValue = parseFloat(input.value);
            
            if (isNaN(bpmValue) || bpmValue < 40 || bpmValue > 300) {
                alert('Please enter a valid BPM between 40 and 300');
                return;
            }
            
            const roundedBPM = Math.round(bpmValue * 10) / 10;
            
            // Update UI
            updateTrackCardBPM(currentBPMTrackId, roundedBPM);
            
            // Get current track data first
            const keyMeta = document.getElementById(`key-meta-${currentBPMTrackId}`);
            let currentKey = 'C major';
            let currentCamelot = '8B';
            if (keyMeta) {
                const keyDisplay = keyMeta.querySelector('.key-value-display');
                const camelotDisplay = keyMeta.querySelector('.camelot-value-display');
                if (keyDisplay && keyDisplay.textContent.trim() !== 'Not analyzed') {
                    currentKey = keyDisplay.textContent.trim();
                }
                if (camelotDisplay) {
                    currentCamelot = camelotDisplay.textContent.replace(/[()]/g, '').trim();
                }
            }
            
            // Save to server
            try {
                const response = await fetch('/api/save_audio_analysis.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        track_id: currentBPMTrackId,
                        bpm: roundedBPM,
                        key: currentKey,
                        camelot: currentCamelot,
                        energy: 'Medium',
                        confidence: 100
                    })
                });
                
                const data = await response.json();
                if (data.success) {
                    showNotification('BPM updated to ' + roundedBPM, 'success');
                    setTimeout(() => window.location.reload(), 1000);
                } else {
                    throw new Error(data.error || 'Failed to save');
                }
            } catch (error) {
                console.error('Error saving BPM:', error);
                showNotification('Failed to save BPM: ' + error.message, 'error');
            }
            
            closeBPMCorrectionModal();
        }
        
        // Key Correction Modal
        const camelotKeys = [
            { key: 'A♭ minor', camelot: '1A', note: 'Abm' },
            { key: 'B major', camelot: '1B', note: 'B' },
            { key: 'E♭ minor', camelot: '2A', note: 'Ebm' },
            { key: 'F# major', camelot: '2B', note: 'F#' },
            { key: 'B♭ minor', camelot: '3A', note: 'Bbm' },
            { key: 'D♭ major', camelot: '3B', note: 'Db' },
            { key: 'F minor', camelot: '4A', note: 'Fm' },
            { key: 'A♭ major', camelot: '4B', note: 'Ab' },
            { key: 'C minor', camelot: '5A', note: 'Cm' },
            { key: 'E♭ major', camelot: '5B', note: 'Eb' },
            { key: 'G minor', camelot: '6A', note: 'Gm' },
            { key: 'B♭ major', camelot: '6B', note: 'Bb' },
            { key: 'D minor', camelot: '7A', note: 'Dm' },
            { key: 'F major', camelot: '7B', note: 'F' },
            { key: 'A minor', camelot: '8A', note: 'Am' },
            { key: 'C major', camelot: '8B', note: 'C' },
            { key: 'E minor', camelot: '9A', note: 'Em' },
            { key: 'G major', camelot: '9B', note: 'G' },
            { key: 'B minor', camelot: '10A', note: 'Bm' },
            { key: 'D major', camelot: '10B', note: 'D' },
            { key: 'F# minor', camelot: '11A', note: 'F#m' },
            { key: 'A major', camelot: '11B', note: 'A' },
            { key: 'D♭ minor', camelot: '12A', note: 'Dbm' },
            { key: 'E major', camelot: '12B', note: 'E' }
        ];
        
        let currentKeyTrackId = null;
        let selectedKeyForCorrection = null;
        
        function openKeyCorrectionModal(trackId, currentKey, currentCamelot) {
            currentKeyTrackId = trackId;
            const modal = document.getElementById('keyCorrectionModal');
            const grid = document.getElementById('keySelectGrid');
            
            if (!modal || !grid) return;
            
            // Populate grid
            grid.innerHTML = camelotKeys.map(k => {
                const escapedKey = k.key.replace(/'/g, "\\'").replace(/"/g, '&quot;');
                return `
                    <div class="key-option" data-key="${k.key.replace(/"/g, '&quot;')}" data-camelot="${k.camelot}" onclick="selectKey('${escapedKey}', '${k.camelot}')">
                        <div class="key-name">${k.note}</div>
                        <div class="camelot">${k.camelot}</div>
                        <div style="font-size: 0.7rem; color: #888; margin-top: 2px;">${k.key}</div>
                    </div>
                `;
            }).join('');
            
            // Highlight current key
            if (currentKey || currentCamelot) {
                const normalizeKey = (key) => {
                    if (!key) return '';
                    return key.replace(/♯/g, '#').replace(/♭/g, 'b')
                              .replace(/G#/gi, 'Ab').replace(/D#/gi, 'Eb')
                              .replace(/A#/gi, 'Bb').replace(/C#/gi, 'Db')
                              .replace(/F#/gi, 'Gb')
                              .trim();
                };
                
                const normalizedCurrentKey = normalizeKey(currentKey);
                let currentOption = Array.from(grid.children).find(el => 
                    el.getAttribute('data-key') === currentKey
                );
                
                if (!currentOption) {
                    currentOption = Array.from(grid.children).find(el => {
                        const dataKey = el.getAttribute('data-key');
                        return normalizeKey(dataKey) === normalizedCurrentKey;
                    });
                }
                
                if (!currentOption && currentCamelot) {
                    currentOption = Array.from(grid.children).find(el => 
                        el.getAttribute('data-camelot') === currentCamelot
                    );
                }
                
                if (currentOption) {
                    currentOption.classList.add('selected');
                    const matchedKey = currentOption.getAttribute('data-key');
                    const matchedCamelot = currentOption.getAttribute('data-camelot');
                    selectedKeyForCorrection = { key: matchedKey, camelot: matchedCamelot };
                }
            }
            
            modal.style.display = 'flex';
            document.body.style.overflow = 'hidden';
        }
        
        function closeKeyCorrectionModal() {
            const modal = document.getElementById('keyCorrectionModal');
            if (modal) {
                modal.style.display = 'none';
                document.body.style.overflow = '';
            }
            currentKeyTrackId = null;
            selectedKeyForCorrection = null;
        }
        
        function selectKey(key, camelot) {
            selectedKeyForCorrection = { key, camelot };
            
            const options = document.querySelectorAll('.key-option');
            options.forEach(opt => opt.classList.remove('selected'));
            
            if (event && event.currentTarget) {
                event.currentTarget.classList.add('selected');
            } else {
                const clickedOption = Array.from(options).find(opt => 
                    opt.getAttribute('data-key') === key && opt.getAttribute('data-camelot') === camelot
                );
                if (clickedOption) {
                    clickedOption.classList.add('selected');
                }
            }
        }
        
        async function saveKeyCorrection() {
            if (!selectedKeyForCorrection || !currentKeyTrackId) {
                alert('Please select a key');
                return;
            }
            
            // Update UI
            updateTrackCardKey(currentKeyTrackId, selectedKeyForCorrection.key, selectedKeyForCorrection.camelot);
            
            // Get current BPM first
            const bpmMeta = document.getElementById(`bpm-meta-${currentKeyTrackId}`);
            let currentBPM = 120; // Default fallback
            if (bpmMeta) {
                const bpmDisplay = bpmMeta.querySelector('.bpm-value-display');
                if (bpmDisplay) {
                    const bpmText = bpmDisplay.textContent.trim();
                    if (bpmText && bpmText !== 'Not analyzed') {
                        const parsed = parseFloat(bpmText);
                        if (!isNaN(parsed) && parsed > 0) {
                            currentBPM = parsed;
                        }
                    }
                }
            }
            
            // Save to server
            try {
                const response = await fetch('/api/save_audio_analysis.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        track_id: currentKeyTrackId,
                        bpm: currentBPM,
                        key: selectedKeyForCorrection.key,
                        camelot: selectedKeyForCorrection.camelot,
                        energy: 'Medium',
                        confidence: 100
                    })
                });
                
                const data = await response.json();
                if (data.success) {
                    showNotification('Key updated to ' + selectedKeyForCorrection.key + ' (' + selectedKeyForCorrection.camelot + ')', 'success');
                    setTimeout(() => window.location.reload(), 1000);
                } else {
                    throw new Error(data.error || 'Failed to save');
                }
            } catch (error) {
                console.error('Error saving key:', error);
                showNotification('Failed to save key: ' + error.message, 'error');
            }
            
            closeKeyCorrectionModal();
        }
    </script>
    
    <!-- BPM Correction Modal -->
    <div id="bpmCorrectionModal" class="bpm-correction-modal">
        <div class="bpm-correction-content">
            <h3><i class="fas fa-tachometer-alt"></i> Correct BPM</h3>
            <div class="bpm-input-wrapper">
                <label for="bpmInput">Enter the correct BPM:</label>
                <input type="number" id="bpmInput" min="40" max="300" step="0.1" placeholder="120" />
                <div class="bpm-hint">Valid range: 40-300 BPM (decimals allowed, e.g., 104.2)</div>
            </div>
            <div style="display: flex; gap: 1rem; justify-content: flex-end;">
                <button class="btn btn-secondary" onclick="closeBPMCorrectionModal()">Cancel</button>
                <button class="btn btn-primary" onclick="saveBPMCorrection()">Save</button>
            </div>
        </div>
    </div>
    
    <!-- Key Correction Modal -->
    <div id="keyCorrectionModal" class="key-correction-modal">
        <div class="key-correction-content">
            <h3><i class="fas fa-music"></i> Correct Musical Key</h3>
            <p style="color: #888; margin-bottom: 0.5rem; font-size: 0.9rem;">Select the correct key for this track:</p>
            <p style="color: #667eea; margin-bottom: 1rem; font-size: 0.85rem; font-style: italic;">
                <i class="fas fa-info-circle"></i> Format: Key Name (Camelot Code) - e.g., A♭ major (4B), B major (1B)
            </p>
            <div class="key-select-grid" id="keySelectGrid"></div>
            <div style="display: flex; gap: 1rem; justify-content: flex-end; margin-top: 1.5rem;">
                <button class="btn btn-secondary" onclick="closeKeyCorrectionModal()">Cancel</button>
                <button class="btn btn-primary" onclick="saveKeyCorrection()">Save</button>
            </div>
        </div>
    </div>
    
    <style>
        /* Analysis Overlay */
        .analysis-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.7);
            backdrop-filter: blur(4px);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10000;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
        }
        
        .analysis-overlay.active {
            opacity: 1;
            pointer-events: all;
        }
        
        .analysis-modal {
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            border-radius: 16px;
            padding: 2rem;
            max-width: 400px;
            width: 90%;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            transform: scale(0.9);
            transition: transform 0.3s ease;
        }
        
        .analysis-overlay.active .analysis-modal {
            transform: scale(1);
        }
        
        .analysis-modal-header {
            text-align: center;
            margin-bottom: 1.5rem;
        }
        
        .analysis-modal-header h3 {
            color: white;
            margin: 0 0 0.5rem 0;
            font-size: 1.2rem;
            font-weight: 600;
        }
        
        .analysis-modal-header p {
            color: rgba(255, 255, 255, 0.6);
            margin: 0;
            font-size: 0.9rem;
        }
        
        .analysis-spinner {
            width: 60px;
            height: 60px;
            margin: 0 auto 1.5rem;
            position: relative;
        }
        
        .analysis-spinner::before {
            content: '';
            position: absolute;
            width: 100%;
            height: 100%;
            border: 4px solid rgba(102, 126, 234, 0.2);
            border-top-color: #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        
        .analysis-progress {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            height: 6px;
            overflow: hidden;
            margin-bottom: 1rem;
        }
        
        .analysis-progress-bar {
            background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
            height: 100%;
            width: 0%;
            transition: width 0.3s ease;
            border-radius: 8px;
        }
        
        .analysis-status {
            text-align: center;
            color: rgba(255, 255, 255, 0.8);
            font-size: 0.9rem;
            min-height: 24px;
        }
        
        .analysis-status-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0.5rem 0;
        }
        
        .analysis-status-label {
            color: rgba(255, 255, 255, 0.6);
            font-size: 0.85rem;
        }
        
        .analysis-status-value {
            color: white;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        
        .analysis-status-value .fa-check {
            color: #4ade80;
        }
        
        .analysis-status-value .fa-spinner {
            color: #667eea;
            animation: spin 1s linear infinite;
        }
        
        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        /* BPM Correction Modal */
        .bpm-correction-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.85);
            backdrop-filter: blur(10px);
            z-index: 10002;
            display: none;
            align-items: center;
            justify-content: center;
        }
        
        .bpm-correction-content {
            background: #2a2a2a;
            border-radius: 20px;
            padding: 2rem;
            max-width: 400px;
            width: 90%;
            border: 2px solid #667eea;
        }
        
        .bpm-correction-content h3 {
            margin-bottom: 1.5rem;
            color: #667eea;
        }
        
        .bpm-input-wrapper {
            margin-bottom: 1.5rem;
        }
        
        .bpm-input-wrapper label {
            display: block;
            margin-bottom: 0.5rem;
            color: #888;
            font-size: 0.9rem;
        }
        
        .bpm-input-wrapper input {
            width: 100%;
            padding: 12px;
            background: rgba(255, 255, 255, 0.05);
            border: 2px solid rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            color: white;
            font-size: 1.2rem;
            text-align: center;
        }
        
        .bpm-input-wrapper input:focus {
            outline: none;
            border-color: #667eea;
        }
        
        .bpm-hint {
            font-size: 0.85rem;
            color: #888;
            margin-top: 0.5rem;
            text-align: center;
        }
        
        /* Key Correction Modal */
        .key-correction-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.85);
            backdrop-filter: blur(10px);
            z-index: 10002;
            display: none;
            align-items: center;
            justify-content: center;
        }
        
        .key-correction-content {
            background: #2a2a2a;
            border-radius: 20px;
            padding: 2rem;
            max-width: 500px;
            width: 90%;
            border: 2px solid #667eea;
        }
        
        .key-correction-content h3 {
            margin-bottom: 1.5rem;
            color: #667eea;
        }
        
        .key-select-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 0.5rem;
            margin-bottom: 1rem;
        }
        
        .key-option {
            background: rgba(255, 255, 255, 0.05);
            border: 2px solid rgba(255, 255, 255, 0.1);
            padding: 0.75rem;
            border-radius: 8px;
            text-align: center;
            cursor: pointer;
            transition: all 0.2s;
        }
        
        .key-option:hover {
            background: rgba(102, 126, 234, 0.2);
            border-color: #667eea;
        }
        
        .key-option.selected {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-color: #667eea;
        }
        
        .key-option .key-name {
            font-weight: 600;
            margin-bottom: 0.25rem;
        }
        
        .key-option .camelot {
            font-size: 0.75rem;
            opacity: 0.8;
        }
    </style>

<?php include 'includes/footer.php'; ?>

CasperSecurity Mini