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/private_html/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/community_fixed.php(backup)
<?php
session_start();

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

require_once 'config/database.php';

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

// Prevent caching of this page to ensure deleted tracks don't show
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');

// Set page variables
$current_page = 'community_fixed';
$page_title = t('community.page_title');
$page_description = t('community.page_description');

// Include header
include 'includes/header.php';

$pdo = getDBConnection();

// Ensure wishlist table exists for queries on this page
try {
    $pdo->exec("
        CREATE TABLE IF NOT EXISTS user_wishlist (
            id INT AUTO_INCREMENT PRIMARY KEY,
            user_id INT NOT NULL,
            track_id INT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY unique_wishlist (user_id, track_id),
            FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
            FOREIGN KEY (track_id) REFERENCES music_tracks(id) ON DELETE CASCADE
        )
    ");
} catch (Exception $e) {
    error_log('Wishlist ensure failed: ' . $e->getMessage());
}

// Get current user info
$user_id = $_SESSION['user_id'] ?? null;
$user_name = 'Guest';

if ($user_id) {
    $stmt = $pdo->prepare("SELECT name FROM users WHERE id = ?");
    $stmt->execute([$user_id]);
    $user = $stmt->fetch();
    $user_name = $user['name'] ?? 'User';
}

// Get filter parameters
$sort = $_GET['sort'] ?? 'latest'; // latest, trending, popular, random
$genre = $_GET['genre'] ?? 'all';
// Decode and clean genre parameter (remove quotes if present, decode URL encoding)
if ($genre !== 'all') {
    $genre = urldecode($genre);
    $genre = trim($genre, '"\'');
    $genre = trim($genre);
}
$time_filter = $_GET['time'] ?? 'all'; // all, today, week, month
$search = $_GET['search'] ?? ''; // search keyword
// Decode and clean search parameter (remove quotes if present, decode URL encoding)
if (!empty($search)) {
    $search = urldecode($search);
    $search = trim($search, '"\'');
    $search = trim($search);
}
$page = max(1, intval($_GET['page'] ?? 1));
$per_page = 24; // Efficient grid layout
$offset = ($page - 1) * $per_page;

// Build time filter
$time_condition = '';
switch ($time_filter) {
    case 'today':
        $time_condition = 'AND mt.created_at >= CURDATE()';
        break;
    case 'week':
        $time_condition = 'AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 WEEK)';
        break;
    case 'month':
        $time_condition = 'AND mt.created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)';
        break;
}

// Build sort order
$order_by = 'mt.created_at DESC';
switch ($sort) {
    case 'trending':
        $order_by = '(mt.likes_count * 2 + mt.plays_count + mt.comments_count) DESC, mt.created_at DESC';
        break;
    case 'popular':
        $order_by = 'mt.likes_count DESC, mt.plays_count DESC';
        break;
    case 'random':
        $order_by = 'RAND()';
        break;
    default:
        $order_by = 'mt.created_at DESC';
}

// Build genre filter - check genre column, tags, and metadata JSON
// Use case-insensitive LIKE for all conditions to match partial words (e.g., "deep" in "Deep House")
$genre_condition = '';
if ($genre !== 'all' && !empty($genre)) {
    // Normalize genre parameter to lowercase for consistent matching
    $genre_lower = strtolower(trim($genre));
    $genre_like = '%' . $genre_lower . '%';
    
    // Check genre column, tags, and metadata JSON fields (genre and style)
    // All use case-insensitive LIKE to match partial words in compound genres
    $genre_condition = "AND (
        LOWER(mt.genre) LIKE ?
        OR LOWER(mt.tags) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
    )";
}

// Build comprehensive search filter - industry-leading search across ALL fields
// Searches: title, artist, genre (all locations), tags (all locations), mood, style, instruments, prompt, lyrics
// This ensures "deep" finds "Deep House", "rap" finds all rap tracks, etc.
$search_condition = '';
if (!empty($search)) {
    // Use EXACT same pattern as genre filter for genre fields, then add other fields
    $search_condition = "AND (
        LOWER(mt.title) LIKE ? 
        OR LOWER(u.name) LIKE ?
        OR LOWER(COALESCE(mt.prompt, '')) LIKE ?
        OR LOWER(COALESCE(mt.lyrics, '')) LIKE ?
        OR LOWER(mt.genre) LIKE ?
        OR LOWER(mt.tags) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
        OR LOWER(mt.style) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proGenre') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proGenre'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proSubGenre') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proSubGenre'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.tags') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.tags'))) LIKE ?
        OR LOWER(COALESCE(mt.mood, '')) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.mood') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.mood'))) LIKE ?
        OR LOWER(COALESCE(mt.instruments, '')) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.instruments') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.instruments'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument'))) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proRhythmSection') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proRhythmSection'))) LIKE ?
        OR LOWER(COALESCE(mt.energy, '')) LIKE ?
        OR LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.energy') AS CHAR)) LIKE ?
        OR LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.energy'))) LIKE ?
    )";
}

// Get total count for pagination FIRST (before main query) to validate page number
    $count_sql = "
        SELECT COUNT(*) as total
        FROM music_tracks mt
        INNER JOIN users u ON mt.user_id = u.id
        WHERE mt.status = 'complete'
        AND (mt.audio_url IS NOT NULL AND mt.audio_url != '' OR mt.variations_count > 0)
        AND mt.user_id IS NOT NULL
        AND u.id IS NOT NULL
        AND (mt.is_public = 1 OR mt.is_public IS NULL)
        $time_condition
        $genre_condition
        $search_condition
    ";
$count_stmt = $pdo->prepare($count_sql);
$count_params = [];
if ($genre !== 'all' && !empty($genre)) {
    // Normalize genre parameter to lowercase for consistent case-insensitive matching
    $genre_lower = strtolower(trim($genre));
    $genre_like = '%' . $genre_lower . '%';
    
    // All conditions use case-insensitive LIKE for partial word matching
    $count_params = array_merge($count_params, [
        $genre_like,  // LOWER(mt.genre) LIKE ?
        $genre_like,  // LOWER(mt.tags) LIKE ?
        $genre_like,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.genre'))) LIKE ?
        $genre_like,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.style'))) LIKE ?
        $genre_like,  // LOWER(CAST(JSON_EXTRACT(metadata, '$.genre') AS CHAR)) LIKE ?
        $genre_like   // LOWER(CAST(JSON_EXTRACT(metadata, '$.style') AS CHAR)) LIKE ?
    ]);
}
if (!empty($search)) {
    // Use lowercase search parameter for case-insensitive matching
    $search_lower = strtolower(trim($search));
    $search_param = '%' . $search_lower . '%';
    // Add search parameters for count query - match SQL placeholders exactly (30 total)
    $count_params = array_merge($count_params, [
        $search_param,  // LOWER(mt.title) LIKE ?
        $search_param,  // LOWER(u.name) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.prompt, '')) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.lyrics, '')) LIKE ?
        $search_param,  // LOWER(mt.genre) LIKE ?
        $search_param,  // LOWER(mt.tags) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
        $search_param,  // LOWER(mt.style) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proGenre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proGenre'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proSubGenre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proSubGenre'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.tags') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.tags'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.mood, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.mood') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.mood'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.instruments, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.instruments') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.instruments'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proRhythmSection') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proRhythmSection'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.energy, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.energy') AS CHAR)) LIKE ?
        $search_param   // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.energy'))) LIKE ?
    ]);
}
    $count_stmt->execute($count_params);
$total_tracks = $count_stmt->fetchColumn();
    $total_pages = $total_tracks > 0 ? ceil($total_tracks / $per_page) : 0; // 0 pages if no tracks
    
    // Validate page number - redirect if invalid (BEFORE main query)
    if ($total_tracks == 0) {
        // No tracks found - redirect to page 1 and clear genre filter if it's active
        if ($genre !== 'all' && !empty($genre)) {
            $redirect_url = "?page=1&sort=" . urlencode($sort) . "&time=" . urlencode($time_filter) . "&genre=all";
        } else {
            $redirect_url = "?page=1&sort=" . urlencode($sort) . "&time=" . urlencode($time_filter) . "&genre=" . urlencode($genre);
        }
        if (!empty($search)) {
            $redirect_url .= "&search=" . urlencode($search);
        }
        header("Location: " . $redirect_url);
        exit;
    } elseif ($page > $total_pages) {
        // Page exceeds total pages - redirect to last valid page
        $redirect_url = "?page=" . $total_pages . "&sort=" . urlencode($sort) . "&time=" . urlencode($time_filter) . "&genre=" . urlencode($genre);
        if (!empty($search)) {
            $redirect_url .= "&search=" . urlencode($search);
        }
        header("Location: " . $redirect_url);
        exit;
    }

// Efficient query - get tracks with all needed data
// IMPORTANT: Only show tracks that actually exist and are complete
$sql = "
        SELECT 
            mt.id,
            mt.title,
            mt.audio_url,
            mt.duration,
            mt.created_at,
            mt.user_id,
        mt.genre,
        mt.tags,
        mt.image_url,
        mt.task_id,
        mt.metadata,
        mt.variations_count,
        mt.price,
            u.name as artist_name,
        u.id as artist_id,
            u.profile_image,
            COALESCE((SELECT COUNT(*) FROM track_likes WHERE track_id = mt.id), 0) as like_count,
            COALESCE((SELECT COUNT(*) FROM track_comments WHERE track_id = mt.id), 0) as comment_count,
            COALESCE((SELECT COUNT(*) FROM track_plays WHERE track_id = mt.id), 0) as play_count,
        COALESCE((SELECT COUNT(*) FROM track_shares WHERE track_id = mt.id), 0) as share_count,
            COALESCE((SELECT COUNT(*) FROM track_likes WHERE track_id = mt.id AND user_id = ?), 0) as user_liked,
        COALESCE((SELECT COUNT(*) FROM user_follows WHERE follower_id = ? AND following_id = mt.user_id), 0) as is_following,
        COALESCE((SELECT COUNT(*) FROM user_wishlist WHERE user_id = ? AND track_id = mt.id), 0) as is_in_wishlist
        FROM music_tracks mt
        INNER JOIN users u ON mt.user_id = u.id
        WHERE mt.status = 'complete'
        AND (mt.audio_url IS NOT NULL AND mt.audio_url != '' OR mt.variations_count > 0)
        AND mt.user_id IS NOT NULL
        AND u.id IS NOT NULL
        AND (mt.is_public = 1 OR mt.is_public IS NULL)
        $time_condition
        $genre_condition
        $search_condition
    ORDER BY $order_by
        LIMIT $per_page OFFSET $offset
";

$stmt = $pdo->prepare($sql);
$params = [$user_id ?? 0, $user_id ?? 0, $user_id ?? 0];
if ($genre !== 'all' && !empty($genre)) {
    // Normalize genre parameter to lowercase for consistent case-insensitive matching
    $genre_lower = strtolower(trim($genre));
    $genre_like = '%' . $genre_lower . '%';
    
    // All conditions use case-insensitive LIKE for partial word matching
    $params = array_merge($params, [
        $genre_like,  // LOWER(mt.genre) LIKE ?
        $genre_like,  // LOWER(mt.tags) LIKE ?
        $genre_like,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.genre'))) LIKE ?
        $genre_like,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(metadata, '$.style'))) LIKE ?
        $genre_like,  // LOWER(CAST(JSON_EXTRACT(metadata, '$.genre') AS CHAR)) LIKE ?
        $genre_like   // LOWER(CAST(JSON_EXTRACT(metadata, '$.style') AS CHAR)) LIKE ?
    ]);
}
if (!empty($search)) {
    // Use lowercase search parameter for case-insensitive matching
    // This ensures "deep" matches "Deep House", "rap" matches "Rap", etc.
    $search_lower = strtolower(trim($search));
    $search_param = '%' . $search_lower . '%';
    // Add search parameters - match SQL placeholders exactly (30 total)
    // Order matches the SQL query above
    $params = array_merge($params, [
        $search_param,  // LOWER(mt.title) LIKE ?
        $search_param,  // LOWER(u.name) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.prompt, '')) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.lyrics, '')) LIKE ?
        $search_param,  // LOWER(mt.genre) LIKE ?
        $search_param,  // LOWER(mt.tags) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.genre'))) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.style'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.genre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.style') AS CHAR)) LIKE ?
        $search_param,  // LOWER(mt.style) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proGenre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proGenre'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proSubGenre') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proSubGenre'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.tags') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.tags'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.mood, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.mood') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.mood'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.instruments, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.instruments') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.instruments'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proLeadInstrument'))) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.proRhythmSection') AS CHAR)) LIKE ?
        $search_param,  // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.proRhythmSection'))) LIKE ?
        $search_param,  // LOWER(COALESCE(mt.energy, '')) LIKE ?
        $search_param,  // LOWER(CAST(JSON_EXTRACT(mt.metadata, '$.energy') AS CHAR)) LIKE ?
        $search_param   // LOWER(JSON_UNQUOTE(JSON_EXTRACT(mt.metadata, '$.energy'))) LIKE ?
    ]);
}
    $stmt->execute($params);
$tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Double-check: Filter out any tracks that don't actually exist (safety check)
// This ensures deleted tracks never show up, even if there's a race condition
if (!empty($tracks)) {
    $track_ids = array_column($tracks, 'id');
    if (!empty($track_ids)) {
        $placeholders = implode(',', array_fill(0, count($track_ids), '?'));
        $verify_stmt = $pdo->prepare("SELECT id FROM music_tracks WHERE id IN ($placeholders)");
        $verify_stmt->execute($track_ids);
        $valid_track_ids = array_column($verify_stmt->fetchAll(PDO::FETCH_ASSOC), 'id');
        
        // Filter tracks to only include those that still exist
        $tracks = array_filter($tracks, function($track) use ($valid_track_ids) {
            return in_array($track['id'], $valid_track_ids);
        });
        // Re-index array
        $tracks = array_values($tracks);
    }
}

// Get variations for each track
foreach ($tracks as &$track) {
    $track['variations'] = [];
    if ($track['variations_count'] > 0) {
        try {
            $var_stmt = $pdo->prepare("
        SELECT 
                    variation_index,
                    audio_url,
                    duration,
                    title,
                    tags,
                    image_url
                FROM audio_variations 
                WHERE track_id = ? 
                ORDER BY variation_index ASC
            ");
            $var_stmt->execute([$track['id']]);
            $track['variations'] = $var_stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
            $track['variations'] = [];
        }
    }
    
}
unset($track);

// Get community stats
$stats_stmt = $pdo->prepare("
    SELECT 
        COUNT(DISTINCT mt.id) as total_tracks,
        COUNT(DISTINCT mt.user_id) as total_artists,
        COALESCE(SUM(mt.duration), 0) as total_duration
    FROM music_tracks mt
    INNER JOIN users u ON mt.user_id = u.id
    WHERE mt.status = 'complete'
    AND (mt.audio_url IS NOT NULL AND mt.audio_url != '' OR mt.variations_count > 0)
    AND mt.user_id IS NOT NULL
    AND u.id IS NOT NULL
    AND (mt.is_public = 1 OR mt.is_public IS NULL)
");
$stats_stmt->execute();
$stats = $stats_stmt->fetch(PDO::FETCH_ASSOC);
?>

<div class="community-page">
    <!-- Hero Section -->
    <div class="community-hero">
            <div class="container">
            <div class="hero-header">
                <div class="hero-title-section">
                    <h1><?= t('community.hero_title') ?></h1>
                    <p class="subtitle"><?= t('community.hero_subtitle') ?></p>
                </div>
                <button class="share-community-btn" onclick="shareCommunityFeed()" title="Share Community Feed">
                    <i class="fas fa-share-alt"></i>
                    <span>Share Feed</span>
                </button>
            </div>
            
            <!-- Quick Stats -->
            <div class="quick-stats">
                <div class="stat-item">
                    <span class="stat-number"><?= number_format($stats['total_tracks']) ?></span>
                    <span class="stat-label"><?= t('community.tracks') ?></span>
                </div>
                <div class="stat-item">
                    <span class="stat-number"><?= number_format($stats['total_artists']) ?></span>
                    <span class="stat-label"><?= t('community.artists') ?></span>
            </div>
                <div class="stat-item">
                    <span class="stat-number"><?= gmdate('H:i:s', $stats['total_duration']) ?></span>
                    <span class="stat-label"><?= t('community.total_music') ?></span>
                </div>
            </div>
                    </div>
                </div>
                
    <!-- Filters & Controls -->
    <div class="community-filters">
        <div class="container">
            <div class="filters-row">
                <!-- Search Input -->
                <div class="filter-group search-group">
                    <label><?= t('community.search') ?>:</label>
                    <input type="text" 
                           id="searchInput" 
                           class="search-input" 
                           placeholder="<?= t('community.search_placeholder') ?>" 
                           value="<?= htmlspecialchars($search) ?>"
                           onkeypress="if(event.key === 'Enter') updateFilters()">
                    <button class="search-btn" onclick="updateFilters()" title="<?= t('community.search') ?>">
                        <i class="fas fa-search"></i>
                    </button>
                </div>
                
                <!-- Sort Options -->
                    <div class="filter-group">
                    <label><?= t('community.sort') ?>:</label>
                    <select id="sortSelect" onchange="updateFilters()">
                        <option value="latest" <?= $sort === 'latest' ? 'selected' : '' ?>><?= t('community.latest') ?></option>
                        <option value="trending" <?= $sort === 'trending' ? 'selected' : '' ?>><?= t('community.trending') ?></option>
                        <option value="popular" <?= $sort === 'popular' ? 'selected' : '' ?>><?= t('community.popular') ?></option>
                        <option value="random" <?= $sort === 'random' ? 'selected' : '' ?>><?= t('community.random') ?></option>
                        </select>
                    </div>
                    
                <!-- Time Filter -->
                    <div class="filter-group">
                    <label><?= t('community.time') ?>:</label>
                    <select id="timeSelect" onchange="updateFilters()">
                            <option value="all" <?= $time_filter === 'all' ? 'selected' : '' ?>><?= t('community.all_time') ?></option>
                            <option value="today" <?= $time_filter === 'today' ? 'selected' : '' ?>><?= t('community.today') ?></option>
                            <option value="week" <?= $time_filter === 'week' ? 'selected' : '' ?>><?= t('community.this_week') ?></option>
                            <option value="month" <?= $time_filter === 'month' ? 'selected' : '' ?>><?= t('community.this_month') ?></option>
                        </select>
                    </div>
                    
                <!-- Genre Filter -->
                    <div class="filter-group">
                    <label><?= t('community.genre') ?>:</label>
                    <select id="genreSelect" onchange="updateFilters()">
                        <option value="all" <?= $genre === 'all' ? 'selected' : '' ?>><?= t('community.all_genres') ?></option>
                        <option value="Electronic" <?= $genre === 'Electronic' ? 'selected' : '' ?>>Electronic</option>
                        <option value="Pop" <?= $genre === 'Pop' ? 'selected' : '' ?>>Pop</option>
                        <option value="Hip Hop" <?= $genre === 'Hip Hop' ? 'selected' : '' ?>>Hip Hop</option>
                        <option value="Rock" <?= $genre === 'Rock' ? 'selected' : '' ?>>Rock</option>
                        <option value="Jazz" <?= $genre === 'Jazz' ? 'selected' : '' ?>>Jazz</option>
                        <option value="Classical" <?= $genre === 'Classical' ? 'selected' : '' ?>>Classical</option>
                        <option value="Ambient" <?= $genre === 'Ambient' ? 'selected' : '' ?>>Ambient</option>
                        </select>
                    </div>
                </div>
                    </div>
                </div>
            
    <!-- Tracks Grid -->
    <div class="container">
        <?php if (empty($tracks)): ?>
            <div class="empty-state">
                <i class="fas fa-music"></i>
                <h2><?= t('community.no_tracks_found') ?></h2>
                <p><?= t('community.no_tracks_desc') ?></p>
            </div>
        <?php else: ?>
            <div class="tracks-grid" id="tracksGrid" data-current-page="1" data-has-more="<?= $page < $total_pages ? 'true' : 'false' ?>">
                <?php foreach ($tracks as $track): 
                    $displayTitle = !empty($track['title']) ? htmlspecialchars($track['title']) : t('community.untitled_track');
                    $duration = $track['duration'] ? gmdate('i:s', $track['duration']) : '0:00';
                    $isWishlisted = !empty($track['is_in_wishlist']);
                    
                    // Handle track image - use original image_url from database (should always be local path)
                    $imageUrl = $track['image_url'] ?? null;
                    
                    // Trim whitespace and check for empty/null values
                    if ($imageUrl !== null) {
                        $imageUrl = trim($imageUrl);
                        if ($imageUrl === '' || $imageUrl === 'null' || $imageUrl === 'NULL') {
                            $imageUrl = null;
                        }
                    }
                    
                    // If image_url exists and is not empty/null, normalize and use it
                    if (!empty($imageUrl)) {
                        // Normalize local paths (add leading / if missing)
                        if (!str_starts_with($imageUrl, '/')) {
                            $imageUrl = '/' . ltrim($imageUrl, '/');
                        }
                    } else {
                        // Only if image_url is empty/null, try fallback sources
                        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'];
                                // Only use if it's a local path (metadata might have external URLs)
                                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'];
                                // Only use if it's a local path (metadata might have external URLs)
                                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 only if no image found
                        if (empty($imageUrl)) {
                            $imageUrl = '/assets/images/default-track.jpg';
                        }
                    }
                    
                    // CRITICAL: Check for selected variation and use its audio URL if available
                    $selectedVariationIndex = null;
                    $selectedVariation = null;
                    
                    // Parse metadata to get selected_variation
                    if (!empty($track['metadata'])) {
                        $trackMetadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
                        if (isset($trackMetadata['selected_variation'])) {
                            $selectedVariationIndex = (int)$trackMetadata['selected_variation'];
                        }
                    }
                    
                    // Also check the selected_variation column if it exists
                    if ($selectedVariationIndex === null && isset($track['selected_variation'])) {
                        $selectedVariationIndex = (int)$track['selected_variation'];
                    }
                    
                    // Normalize variation audio URLs first
                    if (!empty($track['variations'])) {
                        foreach ($track['variations'] as &$var) {
                            $varAudioUrl = $var['audio_url'] ?? '';
                            if ($varAudioUrl && !preg_match('/^https?:\/\//', $varAudioUrl) && !str_starts_with($varAudioUrl, '/')) {
                                // Fix malformed URLs like "audio_files=filename.mp3" to "/audio_files/filename.mp3"
                                if (strpos($varAudioUrl, 'audio_files=') === 0) {
                                    $var['audio_url'] = '/' . str_replace('audio_files=', 'audio_files/', $varAudioUrl);
                                } else {
                                    $var['audio_url'] = '/' . ltrim($varAudioUrl, '/');
                                }
                            } else {
                                $var['audio_url'] = $varAudioUrl;
                            }
                            
                            // Find the selected variation
                            if ($selectedVariationIndex !== null && isset($var['variation_index']) && $var['variation_index'] == $selectedVariationIndex) {
                                $selectedVariation = $var;
                            }
                        }
                        unset($var); // Break reference
                        
                        // Fallback: if selected variation not found by index, try array position
                        if (!$selectedVariation && $selectedVariationIndex !== null && isset($track['variations'][$selectedVariationIndex])) {
                            $selectedVariation = $track['variations'][$selectedVariationIndex];
                        }
                    }
                    
                    // Use selected variation's audio URL if available, otherwise use main track's audio URL
                    $mainAudioUrl = '';
                    if ($selectedVariation && !empty($selectedVariation['audio_url'])) {
                        $mainAudioUrl = $selectedVariation['audio_url'];
                        // Also update duration if available
                        if (!empty($selectedVariation['duration'])) {
                            $duration = gmdate('i:s', $selectedVariation['duration']);
                        }
                    } else {
                        $mainAudioUrl = $track['audio_url'] ?? '';
                        // If main track URL is empty/invalid and we have variations, use first variation as fallback
                        if (empty($mainAudioUrl) && !empty($track['variations']) && is_array($track['variations'])) {
                            $firstVariation = reset($track['variations']);
                            if (!empty($firstVariation['audio_url'])) {
                                $mainAudioUrl = $firstVariation['audio_url'];
                                if (!empty($firstVariation['duration'])) {
                                    $duration = gmdate('i:s', $firstVariation['duration']);
                                }
                            }
                        }
                    }
                    
                    // Use signed proxy URL to hide actual MP3 file paths and prevent URL sharing
                    // Include variation index if a selected variation exists
                    if ($selectedVariationIndex !== null) {
                        $mainAudioUrl = getSignedAudioUrl($track['id'], $selectedVariationIndex);
                    } else {
                        $mainAudioUrl = getSignedAudioUrl($track['id']);
                    }
                ?>
                    <div class="track-card" 
                         data-track-id="<?= $track['id'] ?>"
                         itemscope 
                         itemtype="http://schema.org/MusicRecording">
                        <!-- Track Image -->
                        <div class="track-image-wrapper">
                            <img src="<?= htmlspecialchars($imageUrl) ?>" alt="<?= $displayTitle ?>" class="track-image" loading="lazy">
                            <div class="track-overlay">
                                <button class="play-btn" 
                                        data-track-id="<?= $track['id'] ?>"
                                        data-audio-url="<?= htmlspecialchars($mainAudioUrl ?? '', ENT_QUOTES) ?>"
                                        data-title="<?= htmlspecialchars($displayTitle ?? '', ENT_QUOTES) ?>"
                                        data-artist="<?= htmlspecialchars($track['artist_name'] ?? '', ENT_QUOTES) ?>">
                                    <i class="fas fa-play"></i>
                                </button>
                                <div class="track-duration"><?= $duration ?></div>
                            </div>
                        </div>
                        
                        <!-- Track Info -->
                        <div class="track-info">
                            <div class="track-title-row">
                                <a href="/track.php?id=<?= $track['id'] ?>" 
                                   class="track-title" 
                                   title="<?= $displayTitle ?>"
                                   itemprop="name"><?= $displayTitle ?></a>
                                <?php if (isset($track['price']) && $track['price'] > 0): ?>
                                    <span class="for-sale-badge" title="<?= t('community.available_for_purchase') ?>">
                                        <i class="fas fa-tag"></i>
                                        <span><?= t('community.for_sale') ?></span>
                                    </span>
                                <?php endif; ?>
                            </div>
                            <a href="/artist_profile.php?id=<?= $track['artist_id'] ?>" 
                               class="track-artist"
                               itemprop="byArtist"
                               itemscope
                               itemtype="http://schema.org/MusicGroup">
                                <span itemprop="name"><?= htmlspecialchars($track['artist_name']) ?></span>
                            </a>
                            <?php 
                            // Extract genre and mood like artist_profile.php
                            $genre = 'Electronic'; // default
                            $mood = null;
                            
                            // Try to extract genre/mood from metadata if available
                            if (!empty($track['metadata'])) {
                                $metadata = is_string($track['metadata']) ? json_decode($track['metadata'], true) : $track['metadata'];
                                if ($metadata) {
                                    // Check metadata.genre first, then metadata.style (some tracks store genre in style)
                                    if (!empty($metadata['genre'])) {
                                        $genre = trim($metadata['genre']);
                                    } elseif (!empty($metadata['style'])) {
                                        $genre = trim($metadata['style']);
                                    }
                                    if (!empty($metadata['mood'])) {
                                        $mood = trim($metadata['mood']);
                                    }
                                }
                            }
                            
                            // Use track genre if metadata doesn't have it
                            if (($genre === 'Electronic' || empty($genre)) && !empty($track['genre'])) {
                                $genre = trim($track['genre']);
                            }
                            
                            // Ensure genre is not empty
                            if (empty($genre)) {
                                $genre = 'Electronic';
                            }
                            ?>
                            <div class="track-genre">
                                <a href="?genre=<?= urlencode($genre) ?>" class="genre-tag-link"><?= htmlspecialchars($genre) ?></a>
                                <?php if ($mood && $mood !== $genre && strtolower($mood) !== 'neutral'): ?>
                                    <a href="?genre=<?= urlencode($mood) ?>" class="genre-tag-link"><?= htmlspecialchars($mood) ?></a>
                                <?php endif; ?>
                            </div>
                            <?php if (!empty($track['created_at'])): ?>
                                <div class="track-date">
                                    <i class="fas fa-calendar-alt"></i>
                                    <span><?= date('M j, Y', strtotime($track['created_at'])) ?></span>
                                </div>
                            <?php endif; ?>
                            </div>
                            
                        <!-- Track Stats -->
                        <div class="track-stats">
                            <button class="stat-btn" title="Plays">
                                <i class="fas fa-headphones-alt"></i>
                                <span><?= number_format($track['play_count']) ?></span>
                            </button>
                            <button class="stat-btn like-btn <?= $track['user_liked'] ? 'liked' : '' ?>" onclick="toggleLike(<?= $track['id'] ?>, this)">
                                    <i class="fas fa-heart"></i>
                                <span><?= number_format($track['like_count']) ?></span>
                                </button>
                            <button class="stat-btn" onclick="showComments(<?= $track['id'] ?>)">
                                    <i class="fas fa-comment"></i>
                                <span><?= number_format($track['comment_count']) ?></span>
                                </button>
                            <button class="stat-btn" onclick="shareTrack(<?= $track['id'] ?>)">
                                <i class="fas fa-share"></i>
                                <span><?= number_format($track['share_count'] ?? 0) ?></span>
                                </button>
                            <?php if (!empty($track['variations'])): ?>
                                <button class="stat-btn variations-btn" onclick="showVariations(<?= $track['id'] ?>, this)" title="<?= count($track['variations']) ?> <?= t('community.variations') ?>">
                                    <i class="fas fa-layer-group"></i>
                                    <span><?= count($track['variations']) ?></span>
                                </button>
                            <?php endif; ?>
                            <?php if ($user_id && $user_id != $track['user_id']): ?>
                                <button class="stat-btn follow-btn <?= $track['is_following'] ? 'following' : '' ?>" onclick="toggleFollow(<?= $track['user_id'] ?>, this)">
                                    <i class="fas fa-user-plus"></i>
                                </button>
                            <?php endif; ?>
                        </div>
                        
                        <!-- Add to Cart Button -->
                        <div class="track-cart-section">
                            <button class="add-to-cart-btn" 
                                    type="button"
                                    data-track-id="<?= $track['id'] ?>"
                                    data-track-title="<?= htmlspecialchars($displayTitle, ENT_QUOTES | ENT_HTML5, 'UTF-8') ?>"
                                    data-track-price="<?= isset($track['price']) && $track['price'] !== null ? (float)$track['price'] : 1.99 ?>"
                                    onclick="addToCart(<?= $track['id'] ?>, '<?= htmlspecialchars($displayTitle) ?>', <?= isset($track['price']) && $track['price'] !== null ? (float)$track['price'] : 1.99 ?>, this)">
                                <i class="fas fa-shopping-cart"></i>
                                <span><?= t('community.add_to_cart') ?></span>
                                <?php 
                                // Handle price display: null/not set = 1.99, 0 = free, > 0 = actual price
                                $displayPrice = 1.99; // default
                                if (isset($track['price']) && $track['price'] !== null && $track['price'] !== '') {
                                    $displayPrice = (float)$track['price'];
                                }
                                ?>
                                <span class="cart-price"><?= $displayPrice > 0 ? '$' . number_format($displayPrice, 2) : t('common.free') ?></span>
                            </button>
                            <button class="wishlist-inline-btn <?= $isWishlisted ? 'active' : '' ?>" 
                                    onclick="toggleWishlist(<?= $track['id'] ?>, this)" 
                                    aria-pressed="<?= $isWishlisted ? 'true' : 'false' ?>">
                                <i class="<?= $isWishlisted ? 'fas' : 'far' ?> fa-heart"></i>
                            </button>
                        </div>
                        
                        <!-- Variations Container (hidden by default) -->
                        <?php if (!empty($track['variations'])): ?>
                            <div class="variations-container" id="variations-<?= $track['id'] ?>" style="display: none;">
                                <div class="variations-header">
                                    <span><?= t('community.audio_variations') ?> (<?= count($track['variations']) ?>)</span>
                            </div>
                                <div class="variations-grid">
                                    <?php foreach ($track['variations'] as $var): 
                                        // Use main track title with variation number for consistency
                                        $variationDisplayTitle = $displayTitle . ' - ' . t('community.variation') . ' ' . ($var['variation_index'] + 1);
                                    ?>
                                        <div class="variation-item">
                                            <div class="variation-info">
                                                <span class="variation-title"><?= htmlspecialchars($variationDisplayTitle) ?></span>
                                                <span class="variation-duration"><?= $var['duration'] ? gmdate('i:s', $var['duration']) : '0:00' ?></span>
                        </div>
                                            <button class="variation-play-btn"
                                                    data-track-id="<?= $track['id'] ?>"
                                                    data-audio-url="<?= htmlspecialchars(getSignedAudioUrl($track['id'], $var['variation_index'])) ?>"
                                                    data-title="<?= htmlspecialchars($variationDisplayTitle) ?>"
                                                    data-artist="<?= htmlspecialchars($track['artist_name'] ?? '', ENT_QUOTES) ?>">
                                                <i class="fas fa-play"></i>
                                            </button>
                    </div>
                 <?php endforeach; ?>
                                </div>
                            </div>
                        <?php endif; ?>
                    </div>
                <?php endforeach; ?>
            </div>

            <!-- Infinite Scroll Loading Indicator -->
            <div id="infiniteScrollLoader" style="display: none; text-align: center; padding: 40px 20px; color: white;">
                <div class="loading-spinner" style="font-size: 2rem; margin-bottom: 1rem;">âŗ</div>
                <p style="font-size: 1.1rem; font-weight: 600;"><?= t('community.loading_more') ?></p>
            </div>
            
            <!-- End of Results Message -->
            <div id="endOfResults" style="display: none; text-align: center; padding: 40px 20px; color: white;">
                <p style="font-size: 1.1rem; font-weight: 600; opacity: 0.8;"><?= t('community.no_more_tracks') ?></p>
            </div>
        <?php endif; ?>
    </div>
    </div>

<style>
/* Animated gradient background */
@keyframes gradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

.community-page {
    min-height: 100vh;
    background: linear-gradient(-45deg, #667eea, #764ba2, #f093fb, #4facfe);
    background-size: 400% 400%;
    animation: gradientShift 15s ease infinite;
    padding-bottom: 100px;
    position: relative;
    overflow-x: hidden;
}

/* Floating particles effect */
.community-page::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: 
        radial-gradient(circle at 20% 50%, rgba(255,255,255,0.1) 0%, transparent 50%),
        radial-gradient(circle at 80% 80%, rgba(255,255,255,0.1) 0%, transparent 50%),
        radial-gradient(circle at 40% 20%, rgba(255,255,255,0.1) 0%, transparent 50%);
    pointer-events: none;
    z-index: 0;
}

.community-hero {
    position: relative;
    z-index: 1;
    background: rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(20px);
    padding: 80px 20px;
    text-align: center;
    color: white;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.hero-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.hero-title-section {
    flex: 1;
    min-width: 300px;
}

.community-hero h1 {
    font-size: 3.5rem;
    margin: 0 0 15px 0;
    font-weight: 700;
    text-shadow: 0 4px 20px rgba(0,0,0,0.3);
    animation: fadeInUp 0.8s ease;
}

.community-hero .subtitle {
    font-size: 1.2rem;
    opacity: 0.95;
    margin-bottom: 40px;
    font-weight: 400;
    animation: fadeInUp 0.8s ease 0.2s both;
}

.share-community-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 32px;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.9), rgba(118, 75, 162, 0.9));
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 30px;
    color: white;
    font-size: 1.2rem;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.3s ease;
    backdrop-filter: blur(10px);
    white-space: nowrap;
    animation: fadeInUp 0.8s ease 0.3s both;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
    min-height: 50px;
}

.share-community-btn:hover {
    background: linear-gradient(135deg, rgba(102, 126, 234, 1), rgba(118, 75, 162, 1));
    border-color: rgba(255, 255, 255, 0.5);
    transform: translateY(-3px);
    box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
}

.share-community-btn:active {
    transform: translateY(-1px);
}

.share-community-btn i {
    font-size: 1.3rem;
}

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

.quick-stats {
    display: flex;
    justify-content: center;
    gap: 50px;
    margin-top: 40px;
    flex-wrap: wrap;
    animation: fadeInUp 0.8s ease 0.4s both;
}

.stat-item {
    text-align: center;
    padding: 20px 30px;
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 15px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    transition: all 0.3s ease;
    cursor: default;
}

.stat-item:hover {
    transform: translateY(-5px) scale(1.05);
    background: rgba(255, 255, 255, 0.15);
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}

.stat-number {
    display: block;
    font-size: 2.5rem;
    font-weight: 800;
    margin-bottom: 8px;
    color: white;
}

.stat-label {
    font-size: 0.85rem;
    opacity: 0.9;
    text-transform: uppercase;
    letter-spacing: 2px;
    font-weight: 600;
}

.community-filters {
    position: relative;
    z-index: 1;
    background: rgba(255, 255, 255, 0.08);
    backdrop-filter: blur(20px);
    padding: 25px;
    margin-bottom: 40px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.filters-row {
    display: flex;
    gap: 25px;
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

.filter-group {
    display: flex;
    align-items: center;
    gap: 12px;
}

.filter-group label {
    color: white;
    font-weight: 600;
    font-size: 0.95rem;
    text-shadow: 0 2px 10px rgba(0,0,0,0.2);
}

.filter-group select {
    padding: 10px 18px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    color: white;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.3s ease;
    outline: none;
}

.search-group {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    max-width: 400px;
}

.search-input {
    flex: 1;
    padding: 10px 18px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    color: white;
    font-size: 0.95rem;
    font-weight: 500;
    transition: all 0.3s ease;
    outline: none;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.search-input::placeholder {
    color: rgba(255, 255, 255, 0.5);
}

.search-input:focus {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.6);
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}

.search-btn {
    padding: 10px 18px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 12px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
}

.search-btn:hover {
    background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
}

.filter-group select:hover {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.5);
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}

.filter-group select:focus {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.6);
}

.filter-group select option {
    background: #667eea;
    color: white;
    padding: 10px;
}

.container {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 20px;
    position: relative;
    z-index: 1;
}

.tracks-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 30px;
    margin-top: 40px;
}

.track-card {
    background: rgba(255, 255, 255, 0.98);
    border-radius: 20px;
    overflow: hidden;
    transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    cursor: pointer;
    box-shadow: 0 8px 25px rgba(0,0,0,0.15);
    border: 1px solid rgba(255, 255, 255, 0.3);
    animation: cardFadeIn 0.6s ease both;
}

@keyframes cardFadeIn {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.track-card:nth-child(1) { animation-delay: 0.1s; }
.track-card:nth-child(2) { animation-delay: 0.15s; }
.track-card:nth-child(3) { animation-delay: 0.2s; }
.track-card:nth-child(4) { animation-delay: 0.25s; }
.track-card:nth-child(5) { animation-delay: 0.3s; }
.track-card:nth-child(6) { animation-delay: 0.35s; }

.track-card:hover {
    transform: translateY(-10px) scale(1.02);
    box-shadow: 0 20px 40px rgba(0,0,0,0.3);
    border-color: rgba(255, 255, 255, 0.5);
}

.track-image-wrapper {
    position: relative;
    width: 100%;
    padding-top: 100%;
    overflow: hidden;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
}

.track-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.track-card:hover .track-image {
    transform: scale(1.1) rotate(2deg);
}

.track-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, rgba(102, 126, 234, 0.8) 0%, rgba(118, 75, 162, 0.8) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: all 0.4s ease;
}

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

.play-btn {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.95);
    border: 3px solid rgba(255, 255, 255, 0.5);
    color: #667eea;
    font-size: 1.8rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
    transform: scale(0.9);
}

.track-card:hover .play-btn {
    transform: scale(1);
}

.play-btn:hover {
    transform: scale(1.15);
    box-shadow: 0 15px 40px rgba(0,0,0,0.4);
    background: white;
}

.play-btn:active {
    transform: scale(0.95);
}

.track-duration {
    position: absolute;
    bottom: 12px;
    right: 12px;
    background: rgba(0, 0, 0, 0.75);
    backdrop-filter: blur(10px);
    color: white;
    padding: 6px 12px;
    border-radius: 20px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.5px;
}

.track-info {
    padding: 18px 20px 20px;
    background: white;
}

.track-title-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    min-height: 48px;
}

.track-title {
    font-size: 1.3rem;
    font-weight: 700;
    margin: 0;
    color: #0f172a;
    line-height: 1.4;
    text-decoration: none;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.3s ease;
    flex: 1;
    min-width: 0;
    letter-spacing: -0.02em;
    word-break: break-word;
}

.for-sale-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    background: rgba(46, 204, 113, 0.1);
    color: #2ecc71;
    border-radius: 12px;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid rgba(46, 204, 113, 0.2);
    transition: all 0.2s ease;
}

.for-sale-badge:hover {
    background: rgba(46, 204, 113, 0.15);
    border-color: rgba(46, 204, 113, 0.3);
}

.for-sale-badge i {
    font-size: 0.7rem;
}

.track-title:hover {
    color: #667eea;
    text-decoration: none;
    transform: translateX(2px);
}

.track-artist {
    color: #475569;
    text-decoration: none;
    font-size: 1rem;
    font-weight: 600;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    letter-spacing: 0.01em;
}

.track-artist::before {
    content: 'by';
    font-size: 0.85rem;
    font-weight: 500;
    color: #94a3b8;
    opacity: 0.7;
}

.track-artist span {
    color: inherit;
}

.track-artist:hover {
    color: #667eea;
    transform: translateX(3px);
}

.track-artist:hover::before {
    color: #a5b4fc;
    opacity: 1;
}

.track-genre {
    margin-top: 6px;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.genre-tag-link {
    background: rgba(102, 126, 234, 0.15);
    color: #a5b4fc;
    padding: 6px 12px;
    text-decoration: none;
    border-radius: 12px;
    font-size: 0.85rem;
    font-weight: 600;
    border: 1px solid rgba(102, 126, 234, 0.2);
    display: inline-block;
    transition: all 0.2s ease;
    text-transform: capitalize;
    letter-spacing: 0.3px;
}

.genre-tag-link:hover {
    background: rgba(102, 126, 234, 0.25);
    color: #8b9aff;
    border-color: rgba(102, 126, 234, 0.4);
    transform: translateY(-1px);
}

.track-date {
    display: flex;
    align-items: center;
    gap: 6px;
    color: #999;
    font-size: 0.8rem;
    margin-top: 6px;
    font-weight: 400;
}

.track-date i {
    font-size: 0.75rem;
    opacity: 0.7;
}

.track-stats {
    display: flex;
    padding: 12px 20px;
    border-top: 1px solid #f0f0f0;
    gap: 8px;
    background: #fafafa;
}

.stat-btn {
    flex: 1;
    padding: 10px;
    border: none;
    background: transparent;
    color: #666;
    cursor: pointer;
    border-radius: 10px;
    transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 600;
}

.stat-btn:hover {
    background: linear-gradient(135deg, #667eea15, #764ba215);
    color: #667eea;
    transform: translateY(-2px);
}

.stat-btn.liked {
    color: #e74c3c;
    background: rgba(231, 76, 60, 0.1);
}

.stat-btn.following {
    color: #667eea;
    background: rgba(102, 126, 234, 0.1);
}

.stat-btn.variations-btn {
    color: #764ba2;
}

.stat-btn.variations-btn:hover {
    background: rgba(118, 75, 162, 0.1);
    color: #764ba2;
}

.track-cart-section {
    padding: 12px 20px;
    border-top: 1px solid #f0f0f0;
    background: white;
    display: flex;
    align-items: center;
    gap: 12px;
}

.add-to-cart-btn {
    width: 100%;
    padding: 12px 20px;
    border: none;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border-radius: 10px;
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.add-to-cart-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
    background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
}

.add-to-cart-btn:active {
    transform: translateY(0);
}

.add-to-cart-btn i {
    font-size: 1rem;
}

.add-to-cart-btn .cart-price {
    margin-left: auto;
    font-weight: 700;
    opacity: 0.95;
}

.track-cart-section .add-to-cart-btn {
    flex: 1;
}

.add-to-cart-btn.added {
    background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
    box-shadow: 0 4px 15px rgba(72, 187, 120, 0.3);
}

.add-to-cart-btn.added:hover {
    background: linear-gradient(135deg, #38a169 0%, #2f855a 100%);
    box-shadow: 0 6px 20px rgba(72, 187, 120, 0.4);
}

.wishlist-inline-btn {
    margin-left: 12px;
    width: 48px;
    height: 48px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.08);
    color: #ff7aa2;
    font-size: 1.2rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}

.wishlist-inline-btn:hover {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.4);
}

.wishlist-inline-btn.active {
    background: rgba(255, 99, 132, 0.2);
    border-color: rgba(255, 99, 132, 0.4);
    color: #ff6384;
}

.variations-container {
    padding: 15px 20px;
    background: #f8f9fa;
    border-top: 1px solid #e9ecef;
}

.variations-header {
    font-weight: 600;
    color: #333;
    margin-bottom: 12px;
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.variations-grid {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.variation-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    background: white;
    border-radius: 8px;
    border: 1px solid #e9ecef;
    transition: all 0.2s;
}

.variation-item:hover {
    background: #f8f9fa;
    border-color: #667eea;
}

.variation-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
}

.variation-title {
    font-size: 0.9rem;
    font-weight: 500;
    color: #333;
}

.variation-duration {
    font-size: 0.75rem;
    color: #666;
}

.variation-play-btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: #667eea;
    color: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    font-size: 0.9rem;
}

.variation-play-btn:hover {
    background: #764ba2;
    transform: scale(1.1);
}

.empty-state {
    text-align: center;
    padding: 100px 20px;
    color: white;
}

.empty-state i {
    font-size: 5rem;
    opacity: 0.6;
    margin-bottom: 25px;
    animation: float 3s ease-in-out infinite;
}

@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-20px); }
}

.empty-state h2 {
    margin: 0 0 15px 0;
    font-size: 2rem;
    font-weight: 700;
}

.pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 25px;
    margin-top: 60px;
    padding: 30px 20px;
}

.pagination-btn {
    padding: 12px 25px;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    color: white;
    text-decoration: none;
    border-radius: 12px;
    transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 600;
    border: 1px solid rgba(255, 255, 255, 0.2);
}

.pagination-btn:hover {
    background: rgba(255, 255, 255, 0.25);
    transform: translateY(-3px);
    box-shadow: 0 10px 25px rgba(0,0,0,0.2);
}

.pagination-info {
    color: white;
    font-weight: 700;
    font-size: 1.1rem;
    text-shadow: 0 2px 10px rgba(0,0,0,0.2);
}

@media (max-width: 768px) {
    .hero-header {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
    
    .hero-title-section {
        width: 100%;
        min-width: auto;
    }
    
    .share-community-btn {
        width: 100%;
        max-width: 300px;
        justify-content: center;
        padding: 18px 32px;
        font-size: 1.1rem;
    }
    
    .tracks-grid {
        grid-template-columns: 1fr !important;
        gap: 20px;
    }
    
    .track-card {
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }
    
    .community-hero h1 {
        font-size: 2.2rem;
    }
    
    .quick-stats {
        gap: 15px;
    }
    
    .stat-item {
        padding: 15px 20px;
    }
    
    .stat-number {
        font-size: 1.8rem;
    }
    
    .filters-row {
        gap: 15px;
    }
    
    .genre-tag-link {
        font-size: 0.8rem;
        padding: 5px 10px;
    }
}

@media (max-width: 480px) {
    .hero-header {
        padding: 1rem;
    }
    
    .community-hero h1 {
        font-size: 1.8rem;
    }
    
    .tracks-grid {
        grid-template-columns: 1fr !important;
        gap: 15px;
    }
    
    .track-card {
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }
    
    .track-info {
        padding: 14px 16px 16px;
    }
    
    .track-title-row {
        min-height: 40px;
        margin-bottom: 6px;
        gap: 8px;
    }
    
    .track-title {
        font-size: 1.1rem;
        line-height: 1.3;
        -webkit-line-clamp: 2;
    }
    
    .track-artist {
        font-size: 0.9rem;
        margin-top: 0;
    }
    
    .track-artist::before {
        font-size: 0.75rem;
    }
    
    .quick-stats {
        gap: 10px;
    }
    
    .stat-item {
        padding: 12px 15px;
    }
    
    .stat-number {
        font-size: 1.5rem;
    }
    
    .filters-row {
        flex-direction: column;
        gap: 10px;
    }
    
    .track-genre {
        margin-top: 4px;
    }
    
    .genre-tag-link {
        font-size: 0.75rem;
        padding: 5px 10px;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        display: inline-block;
    }
    
    .track-info {
        padding: 16px 18px 18px;
    }
    
    .track-title-row {
        min-height: 44px;
        margin-bottom: 8px;
    }
    
    .track-title {
        font-size: 1.2rem;
        line-height: 1.35;
        -webkit-line-clamp: 2;
    }
    
    .track-artist {
        font-size: 0.95rem;
    }
    
    .track-artist::before {
        font-size: 0.8rem;
    }
}
</style>

<script>
function updateFilters() {
    const sort = document.getElementById('sortSelect').value;
    const time = document.getElementById('timeSelect').value;
    const genre = document.getElementById('genreSelect').value;
    const search = document.getElementById('searchInput').value.trim();
    
    let url = `?sort=${sort}&time=${time}&genre=${genre}&page=1`;
    if (search) {
        url += `&search=${encodeURIComponent(search)}`;
    }
    
    window.location.href = url;
}

// NOTE: playTrack function is now defined AFTER footer.php loads global_player.php (see bottom of file)
// This ensures the global player is loaded before we try to use it

// Record track play count
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);
        });
    }
}

function toggleLike(trackId, button) {
    fetch('/api/toggle_like.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        credentials: 'include',
        body: JSON.stringify({track_id: trackId})
    })
    .then(response => response.json())
    .then(data => {
        if (!data.success) {
            if (typeof showNotification === 'function') {
                showNotification(data.error || 'Unable to like this track right now.', 'error');
            } else {
                alert(data.error || 'Unable to like this track right now.');
            }
            return;
        }
        button.classList.toggle('liked', !!data.liked);
        const countSpan = button.querySelector('span');
        if (countSpan) {
            countSpan.textContent = (data.like_count || 0).toLocaleString();
        }
    })
    .catch(error => {
        console.error('toggleLike error', error);
        if (typeof showNotification === 'function') {
            showNotification('Network error while liking track. Please try again.', 'error');
        } else {
            alert('Network error while liking track. Please try again.');
        }
    });
}
    
function toggleFollow(userId, button) {
    fetch('/api/toggle_follow.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({user_id: userId})
    })
    .then(r => r.json())
            .then(data => {
                if (data.success) {
            button.classList.toggle('following');
        }
    });
}

function showComments(trackId) {
    window.location.href = `/track.php?id=${trackId}#comments`;
}

function shareTrack(trackId) {
    // Find the track card to get title and artist
    const trackCard = document.querySelector(`.track-card[data-track-id="${trackId}"]`);
    const trackTitleElement = trackCard?.querySelector('.track-title');
    const trackArtistElement = trackCard?.querySelector('.track-artist');
    
    const trackTitle = trackTitleElement?.textContent?.trim() || 'Track';
    const artistName = trackArtistElement?.textContent?.trim() || 'Artist';
    const url = `${window.location.origin}/track.php?id=${trackId}`;
    const shareText = `Check out "${trackTitle}" by ${artistName} on SoundStudioPro! đŸŽĩ`;
    
    const shareData = {
        title: `${trackTitle} by ${artistName}`,
        text: shareText,
        url: url
    };
    
    // Record the share in the database (don't wait for it)
    const platform = 'web';
    fetch('/api_social.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            action: 'share', 
            track_id: trackId, 
            platform: platform 
        })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        if (data.success) {
            console.log('🚀 Share recorded for track:', trackId, 'New count:', data.share_count);
            // Update share count in UI - use the count from server
            const shareButtons = document.querySelectorAll(`button[onclick*="shareTrack(${trackId})"]`);
            shareButtons.forEach(button => {
                const countSpan = button.querySelector('span');
                if (countSpan) {
                    // Use the count from server if available, otherwise increment
                    if (data.share_count !== undefined) {
                        countSpan.textContent = parseInt(data.share_count).toLocaleString();
                    } else {
                        const currentCount = parseInt(countSpan.textContent.replace(/,/g, '')) || 0;
                        countSpan.textContent = (currentCount + 1).toLocaleString();
                    }
                }
            });
        } else {
            console.warn('🚀 Share recording failed:', data.message || 'Unknown error');
        }
    })
    .catch(error => {
        console.error('🚀 Share recording error:', error);
    });
    
    // Try native share API first (mobile devices, especially Android)
    if (navigator.share) {
        // Check if we can share this data (Android requirement)
        if (navigator.canShare && navigator.canShare(shareData)) {
            navigator.share(shareData)
            .then(() => {
                console.log('🚀 Track shared successfully via native API');
                if (typeof showNotification === 'function') {
                    showNotification('✅ Track shared successfully!', 'success');
                }
            })
            .catch((error) => {
                // User cancelled or error - fallback to clipboard
                if (error.name !== 'AbortError') {
                    console.log('🚀 Share API failed, using clipboard:', error);
                    copyTrackUrlToClipboard(url, shareText);
                }
            });
        } else if (!navigator.canShare) {
            // canShare not available, try share anyway
            navigator.share(shareData)
            .then(() => {
                console.log('🚀 Track shared successfully via Web Share API');
                if (typeof showNotification === 'function') {
                    showNotification('✅ Track shared successfully!', 'success');
                }
            })
            .catch((error) => {
                // User cancelled or error - fallback to clipboard
                if (error.name !== 'AbortError') {
                    console.log('🚀 Share API failed, using clipboard:', error);
                    copyTrackUrlToClipboard(url, shareText);
                }
            });
        } else {
            // canShare returned false, use clipboard
            console.log('🚀 Share not available, using clipboard');
            copyTrackUrlToClipboard(url, shareText);
        }
    } else {
        // Use clipboard for desktop
        copyTrackUrlToClipboard(url, shareText);
    }
}

// Copy track URL to clipboard
function copyTrackUrlToClipboard(url, shareText) {
    const shareData = `${shareText}\n${url}`;
    
    // Check if we're in a secure context (HTTPS or localhost)
    const isSecureContext = window.isSecureContext || location.protocol === 'https:' || location.hostname === 'localhost' || location.hostname === '127.0.0.1';
    
    // Try modern clipboard API first (requires secure context)
    if (isSecureContext && navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(shareData)
            .then(() => {
                console.log('🚀 Clipboard copy successful');
                if (typeof showNotification === 'function') {
                    showNotification('🔗 Track link copied to clipboard!', 'success');
                } else {
                    alert('Track link copied to clipboard!\n\n' + shareData);
                }
            })
            .catch((error) => {
                console.error('🚀 Clipboard API failed:', error);
                // Fallback to execCommand method
                fallbackCopyTrack(shareData);
            });
    } else {
        // Not in secure context or clipboard API not available, use fallback
        console.log('🚀 Clipboard API not available, using fallback');
        fallbackCopyTrack(shareData);
    }
}

// Fallback copy method for track sharing
function fallbackCopyTrack(shareData) {
    console.log('🚀 Using fallback copy method for track');
    
    // Use textarea for better mobile compatibility
    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', '');
    textarea.setAttribute('aria-hidden', 'true');
    document.body.appendChild(textarea);
    
    // For Android, we need to ensure the element is visible and focused
    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';
    }
    
    // Select the text
    textarea.focus();
    textarea.select();
    textarea.setSelectionRange(0, shareData.length);
    
    try {
        const successful = document.execCommand('copy');
        // Clean up
        setTimeout(() => {
            document.body.removeChild(textarea);
        }, 100);
        
        if (successful) {
            console.log('🚀 Fallback copy successful');
            if (typeof showNotification === 'function') {
                showNotification('🔗 Track link copied to clipboard!', 'success');
            } else {
                alert('Track link copied to clipboard!\n\n' + shareData);
            }
        } else {
            console.log('🚀 Fallback copy failed, showing prompt');
            // Show a more user-friendly prompt
            const userCopied = confirm('Please copy this link:\n\n' + shareData + '\n\nClick OK if you copied it.');
            if (userCopied && typeof showNotification === 'function') {
                showNotification('🔗 Link copied!', 'success');
            }
        }
    } catch (error) {
        console.error('🚀 Fallback copy error:', error);
        document.body.removeChild(textarea);
        // Show a more user-friendly prompt
        const userCopied = confirm('Please copy this link:\n\n' + shareData + '\n\nClick OK if you copied it.');
        if (userCopied && typeof showNotification === 'function') {
            showNotification('🔗 Link copied!', 'success');
        }
    }
}

// Share Community Feed
function shareCommunityFeed() {
    console.log('Share Community Feed button clicked');
    const urlToCopy = window.location.href;
    console.log('URL to copy:', urlToCopy);
    
    // Try native share API first (mobile devices)
    if (navigator.share) {
        navigator.share({
            title: 'Community Feed - SoundStudioPro',
            text: 'Check out the community feed on SoundStudioPro!',
            url: urlToCopy
        })
        .then(() => {
            console.log('Share successful');
            if (typeof showNotification === 'function') {
                showNotification('✅ Shared successfully!', 'success');
            }
        })
        .catch((error) => {
            // User cancelled or error - fallback to clipboard
            if (error.name !== 'AbortError') {
                console.log('Share API failed, using clipboard:', error);
                copyCommunityUrlToClipboard(urlToCopy);
            }
        });
    } else {
        // Use clipboard for desktop
        copyCommunityUrlToClipboard(urlToCopy);
    }
}

// Copy community URL to clipboard
function copyCommunityUrlToClipboard(urlToCopy) {
    // Try modern clipboard API first
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(urlToCopy)
            .then(() => {
                console.log('Clipboard copy successful');
                if (typeof showNotification === 'function') {
                    showNotification('🔗 Community Feed link copied to clipboard!', 'success');
                } else {
                    alert('Link copied to clipboard: ' + urlToCopy);
                }
            })
            .catch((error) => {
                console.error('Clipboard API failed:', error);
                fallbackShareCommunity(urlToCopy);
            });
    } else {
        fallbackShareCommunity(urlToCopy);
    }
}

// Fallback share method for community feed
function fallbackShareCommunity(urlToCopy) {
    console.log('Using fallback share method');
    const input = document.createElement('input');
    input.style.position = 'fixed';
    input.style.left = '-9999px';
    input.style.top = '-9999px';
    input.value = urlToCopy;
    document.body.appendChild(input);
    input.focus();
    input.select();
    input.setSelectionRange(0, 99999); // For mobile devices
    
    try {
        const successful = document.execCommand('copy');
        document.body.removeChild(input);
        if (successful) {
            console.log('Fallback copy successful');
            if (typeof showNotification === 'function') {
                showNotification('🔗 Community Feed link copied to clipboard!', 'success');
            } else {
                alert('Link copied to clipboard: ' + urlToCopy);
            }
        } else {
            console.log('Fallback copy failed, showing prompt');
            prompt('Copy this link:', urlToCopy);
        }
    } catch (error) {
        console.error('Fallback copy error:', error);
        document.body.removeChild(input);
        prompt('Copy this link:', urlToCopy);
    }
}

function showVariations(trackId, button) {
    const container = document.getElementById(`variations-${trackId}`);
    if (!container) return;
    
    const isVisible = container.style.display !== 'none';
    container.style.display = isVisible ? 'none' : 'block';
    
    if (button) {
        button.classList.toggle('active');
    }
}

function addToCart(trackId, title, price, button) {
    console.log('🛒 Adding to cart:', { trackId, title, price, button });
    
    // Store original button HTML and disable button to prevent double-clicks
    let originalHTML = null;
    if (button) {
        originalHTML = button.innerHTML;
        button.disabled = true;
        button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <span>Adding...</span>';
    }
    
    // Use FormData to match cart.php expectations
    const formData = new FormData();
    formData.append('track_id', trackId);
    formData.append('action', 'add');
    formData.append('artist_plan', 'free'); // Default to free plan
    
    fetch('/cart.php', {
        method: 'POST',
        body: formData
    })
    .then(response => {
        console.log('🛒 Response status:', response.status, response.statusText);
        console.log('🛒 Response headers:', response.headers.get('content-type'));
        
        // Check if response is OK
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        // Check if response is JSON
        const contentType = response.headers.get('content-type');
        if (!contentType || !contentType.includes('application/json')) {
            return response.text().then(text => {
                console.error('🛒 Non-JSON response:', text);
                throw new Error('Server returned non-JSON response');
            });
        }
        
        return response.json();
    })
    .then(data => {
        console.log('🛒 Cart response data:', data);
        
        if (data.success) {
            // Visual feedback
            if (button) {
                button.classList.add('added');
                button.innerHTML = '<i class="fas fa-check"></i> <span>Added!</span>';
                
                setTimeout(() => {
                    button.classList.remove('added');
                    if (originalHTML) {
                        button.innerHTML = originalHTML;
                    }
                    button.disabled = false;
                }, 2000);
            }
            
            // Show notification if available
            if (typeof showNotification === 'function') {
                showNotification('🛒 "' + title + '" added to cart!', 'success');
            }
            
            // Update cart counter if it exists
            const cartCounts = document.querySelectorAll('.cart-count, .cart-counter');
            if (cartCounts.length > 0 && data.cart_count !== undefined) {
                cartCounts.forEach(count => {
                    count.textContent = data.cart_count;
                    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 {
            // Re-enable button on error
            if (button && originalHTML) {
                button.disabled = false;
                button.innerHTML = originalHTML;
            }
            
            // Special handling for "already in cart" - show as warning, not error
            const errorMsg = data.message || data.error || 'Failed to add to cart. Please try again.';
            if (data.already_in_cart) {
                if (typeof showNotification === 'function') {
                    showNotification('â„šī¸ ' + errorMsg, 'warning');
                } else {
                    alert(errorMsg);
                }
            } else {
                if (typeof showNotification === 'function') {
                    showNotification('❌ Error: ' + errorMsg, 'error');
                } else {
                    alert('Error: ' + errorMsg);
                }
            }
        }
    })
    .catch(error => {
        console.error('❌ Cart error:', error);
        
        // Re-enable button on error
        if (button && originalHTML) {
            button.disabled = false;
            button.innerHTML = originalHTML;
        }
        
        const errorMsg = 'An error occurred while adding to cart. Please try again.';
        if (typeof showNotification === 'function') {
            showNotification(errorMsg, 'error');
        } else {
            alert(errorMsg);
        }
    });
}

function downloadTrack(trackId) {
    window.location.href = `/api/download_track.php?id=${trackId}`;
}

// Store our playTrack function before footer overwrites it
const communityFixedPlayTrack = window.playTrack;

// Ensure playTrack function works after AJAX page loads and restore it after footer loads
document.addEventListener('DOMContentLoaded', function() {
    console.log('đŸŽĩ Community Fixed page loaded - playTrack function ready');
    console.log('đŸŽĩ Checking global player availability...');
    console.log('window.waitForGlobalPlayer:', typeof window.waitForGlobalPlayer);
    console.log('window.enhancedGlobalPlayer:', typeof window.enhancedGlobalPlayer);
    console.log('window.globalPlayerReady:', window.globalPlayerReady);
    
    // Restore our function after footer loads (footer loads at end of body)
    setTimeout(function() {
        if (communityFixedPlayTrack) {
            window.playTrack = communityFixedPlayTrack;
            console.log('đŸŽĩ Restored community_fixed playTrack function after footer load');
        }
        
        // Verify global player is ready
        if (window.waitForGlobalPlayer) {
            window.waitForGlobalPlayer(function() {
                console.log('✅ Global player confirmed ready on page load');
            });
        } else {
            console.error('❌ waitForGlobalPlayer still not available after footer load');
        }
    }, 200);
});

// Listen for AJAX page loads
document.addEventListener('ajaxPageLoaded', function() {
    console.log('đŸŽĩ Community Fixed page loaded via AJAX - playTrack function ready');
    // Ensure global player is available
    if (window.waitForGlobalPlayer) {
        window.waitForGlobalPlayer(function() {
            console.log('đŸŽĩ Global player ready after AJAX load');
        });
    }
});
</script>

<!-- Infinite Scroll Implementation -->
<script>
(function() {
    let isLoading = false;
    let currentPage = 1;
    let hasMore = true;
    const currentUserId = <?= $user_id ?? 0 ?>;
    const tracksGrid = document.getElementById('tracksGrid');
    const loader = document.getElementById('infiniteScrollLoader');
    const endOfResults = document.getElementById('endOfResults');
    
    if (!tracksGrid) return;
    
    // Get initial state from data attributes
    currentPage = parseInt(tracksGrid.getAttribute('data-current-page')) || 1;
    hasMore = tracksGrid.getAttribute('data-has-more') === 'true';
    
    // Build community playlist from all visible tracks on the page
    function buildCommunityPlaylist() {
        const playlist = [];
        const grid = document.getElementById('tracksGrid');
        if (!grid) {
            console.warn('đŸŽĩ tracksGrid not found');
            return playlist;
        }
        
        const trackCards = grid.querySelectorAll('.track-card[data-track-id]');
        
        trackCards.forEach(card => {
            const trackId = parseInt(card.getAttribute('data-track-id'));
            const playBtn = card.querySelector('.play-btn');
            
            if (playBtn) {
                const audioUrl = playBtn.getAttribute('data-audio-url');
                const title = playBtn.getAttribute('data-title');
                const artist = playBtn.getAttribute('data-artist');
                
                // Only add if we have valid data
                if (audioUrl && audioUrl !== 'null' && audioUrl !== '' && title) {
                    // Convert relative URL to absolute if needed
                    let finalAudioUrl = audioUrl;
                    if (audioUrl && !audioUrl.startsWith('http') && !audioUrl.startsWith('//')) {
                        if (audioUrl.startsWith('/')) {
                            finalAudioUrl = window.location.origin + audioUrl;
                        } else {
                            finalAudioUrl = window.location.origin + '/' + audioUrl;
                        }
                    }
                    
                    playlist.push({
                        id: trackId,
                        audio_url: finalAudioUrl,
                        title: title,
                        artist_name: artist || 'Unknown Artist',
                        user_id: currentUserId || 0
                    });
                }
            }
        });
        
        console.log('đŸŽĩ Built community playlist:', playlist.length, 'tracks');
        return playlist;
    }
    
    // Make function globally accessible
    window.buildCommunityPlaylist = buildCommunityPlaylist;
    
    // Get current filter values
    function getFilterParams() {
        return {
            sort: document.getElementById('sortSelect')?.value || '<?= $sort ?>',
            time: document.getElementById('timeSelect')?.value || '<?= $time_filter ?>',
            genre: document.getElementById('genreSelect')?.value || '<?= $genre ?>',
            search: document.getElementById('searchInput')?.value.trim() || '<?= htmlspecialchars($search, ENT_QUOTES) ?>'
        };
    }
    
    // Load more tracks
    async function loadMoreTracks() {
        if (isLoading || !hasMore) return;
        
        isLoading = true;
        loader.style.display = 'block';
        
        const params = getFilterParams();
        const queryParams = new URLSearchParams({
            page: currentPage + 1,
            per_page: 24,
            sort: params.sort,
            time: params.time,
            genre: params.genre,
            ...(params.search ? { search: params.search } : {})
        });
        
        try {
            const response = await fetch(`/api/get_community_fixed_tracks.php?${queryParams}`);
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            
            const data = await response.json();
            
            if (!data.success) {
                console.error('API returned error:', data);
                throw new Error(data.error || data.message || 'Failed to load tracks');
            }
            
            if (data.success && data.tracks && data.tracks.length > 0) {
                // Render new tracks
                const fragment = document.createDocumentFragment();
                data.tracks.forEach(track => {
                    const trackCard = createTrackCard(track);
                    fragment.appendChild(trackCard);
                });
                
                tracksGrid.appendChild(fragment);
                
                // Update state
                currentPage = data.pagination.page;
                hasMore = data.pagination.has_more;
                tracksGrid.setAttribute('data-current-page', currentPage);
                tracksGrid.setAttribute('data-has-more', hasMore ? 'true' : 'false');
                
                // Re-attach play button listeners for new tracks
                attachPlayButtonListeners();
                
                // Update playlist if one is currently active (so new tracks are included)
                if (window.waitForGlobalPlayer) {
                    window.waitForGlobalPlayer(function() {
                        if (window.enhancedGlobalPlayer && window._communityPlaylistType === 'community_fixed') {
                            const buildFn = window.buildCommunityPlaylist || buildCommunityPlaylist;
                            const updatedPlaylist = buildFn ? buildFn() : [];
                            if (updatedPlaylist.length > 0) {
                                const currentIndex = window._communityTrackIndex || 0;
                                if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                                    window.enhancedGlobalPlayer.loadPagePlaylist(updatedPlaylist, 'community_fixed', currentIndex);
                                    console.log('đŸŽĩ Updated playlist with new tracks, total:', updatedPlaylist.length);
                                } else {
                                    window._communityPlaylist = updatedPlaylist;
                                    console.log('đŸŽĩ Updated window playlist with new tracks, total:', updatedPlaylist.length);
                                }
                            }
                        }
                    });
                }
                
                // Show end message if no more tracks
                if (!hasMore) {
                    endOfResults.style.display = 'block';
                }
            } else {
                hasMore = false;
                endOfResults.style.display = 'block';
            }
        } catch (error) {
            console.error('Error loading more tracks:', error);
            console.error('Error details:', {
                message: error.message,
                stack: error.stack,
                response: error.response
            });
            
            // Try to get more details from response if available
            if (error.response) {
                error.response.json().then(data => {
                    console.error('API Error Response:', data);
                }).catch(() => {});
            }
            
            if (typeof showNotification === 'function') {
                showNotification('Error loading more tracks. Please try again.', 'error');
            } else {
                alert('Error loading more tracks. Please try again.');
            }
        } finally {
            isLoading = false;
            loader.style.display = 'none';
        }
    }
    
    // Create track card HTML (simplified version matching the PHP template)
    function createTrackCard(track) {
        const card = document.createElement('div');
        card.className = 'track-card';
        card.setAttribute('data-track-id', track.id);
        card.setAttribute('itemscope', '');
        card.setAttribute('itemtype', 'http://schema.org/MusicRecording');
        
        const displayTitle = track.title || 'Untitled Track';
        const duration = track.duration ? formatDuration(track.duration) : '0:00';
        // Use resolved_image_url from API (which handles all fallbacks) or fallback to default
        const imageUrl = track.resolved_image_url || track.image_url || '/assets/images/default-track.jpg';
        const audioUrl = track.signed_audio_url || '';
        const isWishlisted = track.is_in_wishlist > 0;
        const displayPrice = track.price && track.price > 0 ? track.price : 1.99;
        
        // Extract genre from metadata
        let genre = 'Electronic';
        let mood = null;
        if (track.metadata) {
            const metadata = typeof track.metadata === 'string' ? JSON.parse(track.metadata) : track.metadata;
            if (metadata.genre) genre = metadata.genre;
            else if (metadata.style) genre = metadata.style;
            if (metadata.mood) mood = metadata.mood;
        }
        if ((genre === 'Electronic' || !genre) && track.genre) {
            genre = track.genre;
        }
        
        const createdDate = track.created_at ? new Date(track.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '';
        
        card.innerHTML = `
            <div class="track-image-wrapper">
                <img src="${escapeHtml(imageUrl)}" alt="${escapeHtml(displayTitle)}" class="track-image" loading="lazy">
                <div class="track-overlay">
                    <button class="play-btn" 
                            data-track-id="${track.id}"
                            data-audio-url="${escapeHtml(audioUrl)}"
                            data-title="${escapeHtml(displayTitle)}"
                            data-artist="${escapeHtml(track.artist_name || '')}">
                        <i class="fas fa-play"></i>
                    </button>
                    <div class="track-duration">${duration}</div>
                </div>
            </div>
            <div class="track-info">
                <div class="track-title-row">
                    <a href="/track.php?id=${track.id}" class="track-title" title="${escapeHtml(displayTitle)}" itemprop="name">${escapeHtml(displayTitle)}</a>
                    ${track.price > 0 ? `<span class="for-sale-badge" title="Available for purchase"><i class="fas fa-tag"></i><span>For Sale</span></span>` : ''}
                </div>
                <a href="/artist_profile.php?id=${track.artist_id}" class="track-artist" itemprop="byArtist" itemscope itemtype="http://schema.org/MusicGroup">
                    <span itemprop="name">${escapeHtml(track.artist_name || 'Unknown Artist')}</span>
                </a>
                <div class="track-genre">
                    <a href="?genre=${encodeURIComponent(genre)}" class="genre-tag-link">${escapeHtml(genre)}</a>
                    ${mood && mood !== genre && mood.toLowerCase() !== 'neutral' ? `<a href="?genre=${encodeURIComponent(mood)}" class="genre-tag-link">${escapeHtml(mood)}</a>` : ''}
                </div>
                ${createdDate ? `<div class="track-date"><i class="fas fa-calendar-alt"></i><span>${createdDate}</span></div>` : ''}
            </div>
            <div class="track-stats">
                <button class="stat-btn" title="Plays">
                    <i class="fas fa-headphones-alt"></i>
                    <span>${formatNumber(track.play_count || 0)}</span>
                </button>
                <button class="stat-btn like-btn ${track.user_liked > 0 ? 'liked' : ''}" onclick="toggleLike(${track.id}, this)">
                    <i class="fas fa-heart"></i>
                    <span>${formatNumber(track.like_count || 0)}</span>
                </button>
                <button class="stat-btn" onclick="showComments(${track.id})">
                    <i class="fas fa-comment"></i>
                    <span>${formatNumber(track.comment_count || 0)}</span>
                </button>
                <button class="stat-btn" onclick="shareTrack(${track.id})">
                    <i class="fas fa-share"></i>
                    <span>${formatNumber(track.share_count || 0)}</span>
                </button>
                ${track.variations && track.variations.length > 0 ? `
                <button class="stat-btn variations-btn" onclick="showVariations(${track.id}, this)" title="${track.variations.length} variations">
                    <i class="fas fa-layer-group"></i>
                    <span>${track.variations.length}</span>
                </button>
                ` : ''}
                ${track.user_id && track.user_id != currentUserId ? `
                <button class="stat-btn follow-btn ${track.is_following > 0 ? 'following' : ''}" onclick="toggleFollow(${track.user_id}, this)">
                    <i class="fas fa-user-plus"></i>
                </button>
                ` : ''}
            </div>
            <div class="track-cart-section">
                <button class="add-to-cart-btn" type="button" data-track-id="${track.id}" data-track-title="${escapeHtml(displayTitle)}" data-track-price="${displayPrice}" onclick="addToCart(${track.id}, '${escapeHtml(displayTitle)}', ${displayPrice}, this)">
                    <i class="fas fa-shopping-cart"></i>
                    <span>Add to Cart</span>
                    <span class="cart-price">${displayPrice > 0 ? '$' + displayPrice.toFixed(2) : 'Free'}</span>
                </button>
                <button class="wishlist-inline-btn ${isWishlisted ? 'active' : ''}" onclick="toggleWishlist(${track.id}, this)" aria-pressed="${isWishlisted}">
                    <i class="${isWishlisted ? 'fas' : 'far'} fa-heart"></i>
                </button>
            </div>
        `;
        
        return card;
    }
    
    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    function formatDuration(seconds) {
        const mins = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        return `${mins}:${secs.toString().padStart(2, '0')}`;
    }
    
    function formatNumber(num) {
        return parseInt(num).toLocaleString();
    }
    
    // Attach play button listeners (matches original behavior with pause support)
    function attachPlayButtonListeners() {
        const playButtons = tracksGrid.querySelectorAll('.play-btn:not([data-listener-attached])');
        playButtons.forEach(button => {
            button.setAttribute('data-listener-attached', 'true');
            button.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();
                
                const trackId = this.getAttribute('data-track-id');
                const audioUrl = this.getAttribute('data-audio-url');
                const title = this.getAttribute('data-title');
                const artist = this.getAttribute('data-artist');
                const isCurrentlyPlaying = this.classList.contains('playing');
                
                console.log('đŸŽĩ Infinite scroll play button clicked:', { trackId, audioUrl, title, artist, isCurrentlyPlaying });
                
                // Validate audio URL
                if (!audioUrl || audioUrl === 'null' || audioUrl === 'NULL' || audioUrl === '') {
                    console.error('❌ Invalid audio URL:', audioUrl);
                    alert('This track is not available for playback.');
                    return;
                }
                
                // If button is already in playing state, pause instead
                if (isCurrentlyPlaying) {
                    if (window.waitForGlobalPlayer) {
                        window.waitForGlobalPlayer(function() {
                            if (window.enhancedGlobalPlayer) {
                                // Check if global player has togglePlayPause or pause method
                                if (typeof window.enhancedGlobalPlayer.togglePlayPause === 'function') {
                                    console.log('đŸŽĩ Pausing via togglePlayPause');
                                    window.enhancedGlobalPlayer.togglePlayPause();
                                } else if (typeof window.enhancedGlobalPlayer.pause === 'function') {
                                    console.log('đŸŽĩ Pausing via pause method');
                                    window.enhancedGlobalPlayer.pause();
                                }
                                
                                // Update button state
                                button.classList.remove('playing');
                                const icon = button.querySelector('i');
                                if (icon) icon.className = 'fas fa-play';
                                
                                // Clear other playing states
                                document.querySelectorAll('.play-btn').forEach(btn => {
                                    if (btn !== button) {
                                        btn.classList.remove('playing');
                                        const btnIcon = btn.querySelector('i');
                                        if (btnIcon) btnIcon.className = 'fas fa-play';
                                    }
                                });
                            }
                        });
                    }
                    return;
                }
                
                // Clear other playing states
                document.querySelectorAll('.play-btn').forEach(btn => {
                    btn.classList.remove('playing');
                    const icon = btn.querySelector('i');
                    if (icon) icon.className = 'fas fa-play';
                });
                
                // Set this button as playing
                this.classList.add('playing');
                const icon = this.querySelector('i');
                if (icon) icon.className = 'fas fa-pause';
                
                // Play track using global player
                // 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!');
                    alert('Audio file not available.');
                    button.classList.remove('playing');
                    if (icon) icon.className = 'fas fa-play';
                    return;
                }
                
                if (window.waitForGlobalPlayer) {
                    window.waitForGlobalPlayer(function() {
                        if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                            try {
                                // Build and load playlist before playing
                                const buildFn = window.buildCommunityPlaylist || buildCommunityPlaylist;
                                const communityPlaylist = buildFn ? buildFn() : [];
                                if (communityPlaylist.length > 0) {
                                    // Find the index of the clicked track
                                    const clickedTrackId = parseInt(trackId);
                                    const trackIndex = communityPlaylist.findIndex(t => t.id === clickedTrackId);
                                    const startIndex = trackIndex !== -1 ? trackIndex : 0;
                                    
                                    // Load playlist into global player
                                    if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                                        window.enhancedGlobalPlayer.loadPagePlaylist(communityPlaylist, 'community_fixed', startIndex);
                                        console.log('đŸŽĩ Community: Playlist loaded via loadPagePlaylist, index:', startIndex, 'of', communityPlaylist.length);
                                    } else {
                                        // Fallback to window storage
                                        window._communityPlaylist = communityPlaylist;
                                        window._communityPlaylistType = 'community_fixed';
                                        window._communityTrackIndex = startIndex;
                                        console.log('đŸŽĩ Community: Playlist stored on window, index:', startIndex, 'of', communityPlaylist.length);
                                    }
                                }
                                
                                console.log('đŸŽĩ Playing track:', { finalAudioUrl, title, artist, trackId });
                                const success = window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist, trackId);
                                
                                if (success) {
                                    console.log('✅ Track playing successfully');
                                    if (trackId) recordTrackPlay(trackId);
                                } else {
                                    console.error('❌ playTrack returned false');
                                    alert('Failed to play track.');
                                    // Reset button
                                    button.classList.remove('playing');
                                    if (icon) icon.className = 'fas fa-play';
                                }
                            } catch (error) {
                                console.error('❌ Error:', error);
                                alert('Error: ' + error.message);
                                // Reset button
                                button.classList.remove('playing');
                                if (icon) icon.className = 'fas fa-play';
                            }
                        } else {
                            console.error('❌ Global player not available');
                            alert('Player not ready. Please refresh.');
                            // Reset button
                            button.classList.remove('playing');
                            if (icon) icon.className = 'fas fa-play';
                        }
                    });
                } else {
                    // Fallback
                    setTimeout(function() {
                        if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                            // Build and load playlist
                            const communityPlaylist = buildCommunityPlaylist();
                            if (communityPlaylist.length > 0) {
                                const clickedTrackId = parseInt(trackId);
                                const trackIndex = communityPlaylist.findIndex(t => t.id === clickedTrackId);
                                const startIndex = trackIndex !== -1 ? trackIndex : 0;
                                
                                if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                                    window.enhancedGlobalPlayer.loadPagePlaylist(communityPlaylist, 'community_fixed', startIndex);
                                } else {
                                    window._communityPlaylist = communityPlaylist;
                                    window._communityPlaylistType = 'community_fixed';
                                    window._communityTrackIndex = startIndex;
                                }
                            }
                            
                            window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist, trackId);
                            if (trackId) recordTrackPlay(trackId);
                        } else {
                            alert('Audio player not ready. Please refresh the page.');
                            button.classList.remove('playing');
                            if (icon) icon.className = 'fas fa-play';
                        }
                    }, 500);
                }
            });
        });
    }
    
    // Scroll detection
    function handleScroll() {
        if (isLoading || !hasMore) return;
        
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        const windowHeight = window.innerHeight;
        const documentHeight = document.documentElement.scrollHeight;
        
        // Load more when user is 300px from bottom
        if (scrollTop + windowHeight >= documentHeight - 300) {
            loadMoreTracks();
        }
    }
    
    // Throttle scroll events
    let scrollTimeout;
    window.addEventListener('scroll', function() {
        if (scrollTimeout) {
            clearTimeout(scrollTimeout);
        }
        scrollTimeout = setTimeout(handleScroll, 100);
    });
    
    // Reset on filter change
    const originalUpdateFilters = window.updateFilters;
    window.updateFilters = function() {
        // Reset infinite scroll state
        currentPage = 1;
        hasMore = true;
        tracksGrid.setAttribute('data-current-page', '1');
        tracksGrid.setAttribute('data-has-more', 'true');
        loader.style.display = 'none';
        endOfResults.style.display = 'none';
        
        // Call original function
        if (originalUpdateFilters) {
            originalUpdateFilters();
        }
    };
})();
</script>

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

<!-- Play button event listeners - like other working pages -->
<script>
// Setup play button event listeners
document.addEventListener('DOMContentLoaded', function() {
    console.log('đŸŽĩ Setting up play button listeners');
    
    // Main track play buttons
    const playButtons = document.querySelectorAll('.play-btn, .variation-play-btn');
    console.log('đŸŽĩ Found', playButtons.length, 'play buttons');
    
    playButtons.forEach(button => {
        button.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            
            const trackId = this.getAttribute('data-track-id');
            const audioUrl = this.getAttribute('data-audio-url');
            const title = this.getAttribute('data-title');
            const artist = this.getAttribute('data-artist');
            const isCurrentlyPlaying = this.classList.contains('playing');
            
            console.log('đŸŽĩ Play button clicked:', { trackId, audioUrl, title, artist, isCurrentlyPlaying });
            
            // Validate
            if (!audioUrl || audioUrl === 'null' || audioUrl === 'NULL' || audioUrl === '') {
                console.error('❌ Invalid audio URL:', audioUrl);
                alert('This track is not available for playback.');
                return;
            }
            
            // If button is already in playing state, pause instead
            if (isCurrentlyPlaying) {
                if (window.waitForGlobalPlayer) {
                    window.waitForGlobalPlayer(function() {
                        if (window.enhancedGlobalPlayer) {
                            // Check if global player has togglePlayPause or pause method
                            if (typeof window.enhancedGlobalPlayer.togglePlayPause === 'function') {
                                console.log('đŸŽĩ Pausing via togglePlayPause');
                                window.enhancedGlobalPlayer.togglePlayPause();
                            } else if (typeof window.enhancedGlobalPlayer.pause === 'function') {
                                console.log('đŸŽĩ Pausing via pause method');
                                window.enhancedGlobalPlayer.pause();
                            }
                            
                            // Update button state
                            button.classList.remove('playing');
                            const icon = button.querySelector('i');
                            if (icon) icon.className = 'fas fa-play';
                            
                            // Clear other playing states
                            playButtons.forEach(btn => {
                                if (btn !== button) {
                                    btn.classList.remove('playing');
                                    const btnIcon = btn.querySelector('i');
                                    if (btnIcon) btnIcon.className = 'fas fa-play';
                                }
                            });
                        }
                    });
                }
                return;
            }
            
            // Clear other playing states
            playButtons.forEach(btn => {
                btn.classList.remove('playing');
                const icon = btn.querySelector('i');
                if (icon) icon.className = 'fas fa-play';
            });
            
            // Set this button as playing
            this.classList.add('playing');
            const icon = this.querySelector('i');
            if (icon) icon.className = 'fas fa-pause';
            
            // Play track using global player
            // 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!');
                alert('Audio file not available.');
                button.classList.remove('playing');
                if (icon) icon.className = 'fas fa-play';
                return;
            }
            
            if (window.waitForGlobalPlayer) {
                window.waitForGlobalPlayer(function() {
                    if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                        try {
                            // Build and load playlist before playing
                            const buildFn = window.buildCommunityPlaylist || buildCommunityPlaylist;
                            const communityPlaylist = buildFn ? buildFn() : [];
                            if (communityPlaylist.length > 0) {
                                // Find the index of the clicked track
                                const clickedTrackId = parseInt(trackId);
                                const trackIndex = communityPlaylist.findIndex(t => t.id === clickedTrackId);
                                const startIndex = trackIndex !== -1 ? trackIndex : 0;
                                
                                // Load playlist into global player
                                if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                                    window.enhancedGlobalPlayer.loadPagePlaylist(communityPlaylist, 'community_fixed', startIndex);
                                    console.log('đŸŽĩ Community: Playlist loaded via loadPagePlaylist, index:', startIndex, 'of', communityPlaylist.length);
                                } else {
                                    // Fallback to window storage
                                    window._communityPlaylist = communityPlaylist;
                                    window._communityPlaylistType = 'community_fixed';
                                    window._communityTrackIndex = startIndex;
                                    console.log('đŸŽĩ Community: Playlist stored on window, index:', startIndex, 'of', communityPlaylist.length);
                                }
                            }
                            
                            console.log('đŸŽĩ Playing track:', { finalAudioUrl, title, artist, trackId });
                            const success = window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist, trackId);
                            
                            if (success) {
                                console.log('✅ Track playing successfully');
                                if (trackId) recordTrackPlay(trackId);
                            } else {
                                console.error('❌ playTrack returned false');
                                alert('Failed to play track.');
                                // Reset button
                                button.classList.remove('playing');
                                if (icon) icon.className = 'fas fa-play';
                            }
                        } catch (error) {
                            console.error('❌ Error:', error);
                            alert('Error: ' + error.message);
                            // Reset button
                            button.classList.remove('playing');
                            if (icon) icon.className = 'fas fa-play';
                        }
                    } else {
                        console.error('❌ Global player not available');
                        alert('Player not ready. Please refresh.');
                        // Reset button
                        button.classList.remove('playing');
                        if (icon) icon.className = 'fas fa-play';
                    }
                });
            } else {
                // Fallback
                setTimeout(function() {
                    if (window.enhancedGlobalPlayer && typeof window.enhancedGlobalPlayer.playTrack === 'function') {
                        // Build and load playlist
                        const buildFn = window.buildCommunityPlaylist || buildCommunityPlaylist;
                        const communityPlaylist = buildFn();
                        if (communityPlaylist.length > 0) {
                            const clickedTrackId = parseInt(trackId);
                            const trackIndex = communityPlaylist.findIndex(t => t.id === clickedTrackId);
                            const startIndex = trackIndex !== -1 ? trackIndex : 0;
                            
                            if (typeof window.enhancedGlobalPlayer.loadPagePlaylist === 'function') {
                                window.enhancedGlobalPlayer.loadPagePlaylist(communityPlaylist, 'community_fixed', startIndex);
                            } else {
                                window._communityPlaylist = communityPlaylist;
                                window._communityPlaylistType = 'community_fixed';
                                window._communityTrackIndex = startIndex;
                            }
                        }
                        
                        window.enhancedGlobalPlayer.playTrack(finalAudioUrl, title, artist, trackId);
                        if (trackId) recordTrackPlay(trackId);
                    } else {
                        alert('Audio player not ready. Please refresh the page.');
                        button.classList.remove('playing');
                        if (icon) icon.className = 'fas fa-play';
                    }
                }, 500);
            }
        });
    });
    
    console.log('✅ Play button listeners setup complete');
});
</script>



CasperSecurity Mini