<?php
/**
 * Video Processing Dashboard & HLS Converter
 * 
 * تحويل الفيديوهات إلى HLS مع واجهة عرض HTML وشريط تقدم
 */

set_time_limit(0);
ini_set('max_execution_time', 0);
error_reporting(E_ALL);
ini_set('display_errors', 1);

$logFile = __DIR__ . '/process_videos_debug.log';
file_put_contents($logFile, date('Y-m-d H:i:s') . " - Script started (PID: " . getmypid() . ")\n", FILE_APPEND);


// الاتصال بقاعدة البيانات
include dirname(__DIR__) . "/inc/con.php";

// ============================================
// الإعدادات
// ============================================

$media_dir = dirname(__DIR__) . '/upload_media/';

// Check if exec() is enabled
if (!function_exists('exec') || !is_callable('exec')) {
    die("<div style='color:red; font-weight:bold; padding:20px;'>Error: The 'exec' function is disabled in php.ini. This script requires exec() to run FFmpeg.</div>");
}

// Ensure processing_percentage column exists
try {
    $db->exec("ALTER TABLE social_media_content ADD COLUMN processing_percentage TINYINT(3) DEFAULT 0");
} catch (PDOException $e) {
    // Column likely exists, ignore
}

// Dynamic FFmpeg Path Detection
$ffmpeg_path = null;
$possible_paths = [
    '/opt/homebrew/bin/ffmpeg', // Mac Homebrew
    '/usr/bin/ffmpeg',          // Linux default
    '/usr/local/bin/ffmpeg',    // Linux local
    '/bin/ffmpeg'               // Linux bin
];

foreach ($possible_paths as $path) {
    if (file_exists($path) && is_executable($path)) {
        $ffmpeg_path = $path;
        break;
    }
}

if (!$ffmpeg_path && function_exists('exec')) {
    $output = [];
    $return_var = 0;
    exec('which ffmpeg', $output, $return_var);
    if ($return_var === 0 && !empty($output[0])) {
        $ffmpeg_path = trim($output[0]);
    }
}

if (!$ffmpeg_path) {
    $ffmpeg_path = 'ffmpeg'; // Fallback
}

// الجودات المطلوبة
$qualities = [
    '360p' => ['resolution' => '640:360', 'video_bitrate' => '800k', 'audio_bitrate' => '96k'],
    '480p' => ['resolution' => '854:480', 'video_bitrate' => '1400k', 'audio_bitrate' => '128k'],
    '720p' => ['resolution' => '1280:720', 'video_bitrate' => '2800k', 'audio_bitrate' => '128k'],
    '1080p' => ['resolution' => '1920:1080', 'video_bitrate' => '5000k', 'audio_bitrate' => '192k']
];

// ============================================
// HTML Helper Functions
// ============================================

function printHeader()
{
    echo '<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>نظام معالجة الفيديو | Video Processing with Progress</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700&display=swap" rel="stylesheet">
    <style>
        body { font-family: "Cairo", sans-serif; background-color: #f4f6f9; }
        .container { max-width: 1200px; margin-top: 30px; }
        .card { border: none; box-shadow: 0 4px 6px rgba(0,0,0,0.1); margin-bottom: 20px; }
        .card-header { background-color: #2c3e50; color: white; font-weight: bold; padding: 15px; }
        .status-badge { font-size: 0.9em; padding: 5px 10px; border-radius: 20px; }
        .log-console { background: #1e1e1e; color: #00ff00; padding: 15px; border-radius: 5px; height: 300px; overflow-y: auto; font-family: monospace; font-size: 14px; }
        .table th { background-color: #e9ecef; }
        .progress { height: 25px; background-color: #e9ecef; border-radius: 5px; overflow: hidden; margin-top: 5px; }
        .progress-bar { transition: width 0.5s ease; font-weight: bold; }
    </style>
</head>
<body>
<div class="container">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h2>🎥 نظام معالجة الفيديوهات</h2>
        <span class="badge bg-primary fs-6">الإصدار 2.1 (Live Progress)</span>
    </div>';
}

function printFooter()
{
    echo '</div>
    <script>
        // Auto-scroll log
        var logConsole = document.querySelector(".log-console");
        if(logConsole) logConsole.scrollTop = logConsole.scrollHeight;
    </script>
</body>
</html>';
}

function flushOutput()
{
    if (ob_get_level() > 0) {
        ob_end_flush();
    }
    flush();
}

// ============================================
// Logic Functions
// ============================================

function checkFFmpeg($ffmpeg_path)
{
    $output = [];
    $return_var = 0;
    exec("$ffmpeg_path -version 2>&1", $output, $return_var);
    return $return_var === 0;
}

function updateProcessingStatus($db, $id, $status, $percentage = null)
{
    try {
        $sql = "UPDATE social_media_content SET video_processing = ?";
        $params = [$status];

        if ($percentage !== null) {
            $sql .= ", processing_percentage = ?";
            $params[] = $percentage;
        }

        $sql .= " WHERE id = ?";
        $params[] = $id;

        $stmt = $db->prepare($sql);
        return $stmt->execute($params);
    } catch (PDOException $e) {
        echo "<div style='color:red;'>SQL Error: " . $e->getMessage() . "</div>";
        return false;
    }
}

/**
 * Get video duration in seconds using ffprobe/ffmpeg
 */
function getVideoDuration($ffmpeg_path, $inputFile)
{
    $cmd = sprintf('%s -i %s 2>&1', escapeshellarg($ffmpeg_path), escapeshellarg($inputFile));
    $output = [];
    exec($cmd, $output);
    $outputStr = implode("\n", $output);

    // Search for "Duration: HH:MM:SS.ms"
    if (preg_match('/Duration: (\d{2}):(\d{2}):(\d{2}\.\d{2})/', $outputStr, $matches)) {
        $hours = intval($matches[1]);
        $minutes = intval($matches[2]);
        $seconds = floatval($matches[3]);
        return ($hours * 3600) + ($minutes * 60) + $seconds;
    }
    return 0;
}

/**
 * Convert HH:MM:SS.ms to seconds
 */
function timeToSeconds($timeStr)
{
    $parts = explode(':', $timeStr);
    if (count($parts) === 3) {
        return ($parts[0] * 3600) + ($parts[1] * 60) + floatval($parts[2]);
    }
    return 0;
}

function processVideoToHLS($ffmpeg_path, $inputFile, $outputDir, $qualities, $db, $videoId, &$logBuffer)
{
    if (!file_exists($inputFile)) {
        $logBuffer .= "❌ خطأ: الملف غير موجود: " . basename($inputFile) . "<br>";
        return false;
    }

    if (!is_dir($outputDir)) {
        mkdir($outputDir, 0755, true);
    }

    $totalDuration = getVideoDuration($ffmpeg_path, $inputFile);
    if ($totalDuration <= 0) {
        $logBuffer .= "⚠️ لم يتم تحديد مدة الفيديو، لن يظهر شريط التقدم.<br>";
    }

    $success = true;
    $generatedPlaylists = [];
    $totalSteps = count($qualities);
    $currentStep = 0;

    foreach ($qualities as $quality => $settings) {
        $currentStep++;
        $qualityDir = $outputDir . $quality . '/';
        if (!is_dir($qualityDir)) {
            mkdir($qualityDir, 0755, true);
        }

        $playlistFile = $qualityDir . 'playlist.m3u8';
        $segmentPattern = $qualityDir . 'segment_%03d.ts';

        // FFmpeg command showing progress
        $cmd = sprintf(
            '%s -i %s -vf scale=%s -c:v libx264 -b:v %s -preset fast -c:a aac -b:a %s -hls_time 10 -hls_playlist_type vod -hls_segment_filename %s %s 2>&1',
            escapeshellarg($ffmpeg_path),
            escapeshellarg($inputFile),
            $settings['resolution'],
            $settings['video_bitrate'],
            $settings['audio_bitrate'],
            escapeshellarg($segmentPattern),
            escapeshellarg($playlistFile)
        );

        // Run with proc_open to capture output in real-time
        $descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; // Using pipes

        // Note: ffmpeg outputs progress to stderr (index 2)
        $process = proc_open($cmd, $descriptors, $pipes);

        if (is_resource($process)) {
            $lastUpdate = 0;

            // Allow parsing output
            while ($line = fgets($pipes[2])) { // Read stderr
                // Parse "time=HH:MM:SS.ms"
                if ($totalDuration > 0 && preg_match('/time=(\d{2}:\d{2}:\d{2}\.\d{2})/', $line, $matches)) {
                    $currentTime = timeToSeconds($matches[1]);
                    $qualityProgress = ($currentTime / $totalDuration); // 0 to 1

                    // Global progress: (Previous Steps + Current Step Progress) / Total Steps
                    $globalProgress = (($currentStep - 1) + $qualityProgress) / $totalSteps * 100;
                    $globalProgress = min(99, round($globalProgress)); // Cap at 99% until fully done

                    // Update DB and UI every 2 seconds or >1% change to save resources
                    if (time() - $lastUpdate >= 1) {
                        updateProcessingStatus($db, $videoId, 1, $globalProgress);
                        echo "<script>
                            document.getElementById('progress-bar-$videoId').style.width = '$globalProgress%'; 
                            document.getElementById('progress-bar-$videoId').innerText = '$globalProgress%';
                            document.getElementById('progress-text-$videoId').innerText = 'جاري معالجة $quality ($globalProgress%)';
                         </script>";
                        flushOutput();
                        $lastUpdate = time();
                    }
                }
            }

            fclose($pipes[0]);
            fclose($pipes[1]);
            fclose($pipes[2]);
            $return_var = proc_close($process);
        } else {
            // Fallback to exec if proc_open fails
            $output = [];
            exec($cmd, $output, $return_var);
        }

        if ($return_var !== 0) {
            $logBuffer .= "⚠️ فشل معالجة جودة $quality<br>";
            $success = false;
            break;
        } else {
            $generatedPlaylists[$quality] = [
                'path' => "$quality/playlist.m3u8",
                'resolution' => $settings['resolution'],
                'bandwidth' => (int) str_replace('k', '000', $settings['video_bitrate']) + (int) str_replace('k', '000', $settings['audio_bitrate'])
            ];
            $logBuffer .= "✅ تم إنشاء جودة $quality بنجاح<br>";
        }
    }

    if ($success && !empty($generatedPlaylists)) {
        createMasterPlaylist($generatedPlaylists, $outputDir);
        $logBuffer .= "🏁 تم إنشاء القائمة الرئيسية Master Playlist<br>";
    }

    return $success;
}

function createMasterPlaylist($playlists, $outputDir)
{
    $masterFile = $outputDir . 'master.m3u8';
    $content = "#EXTM3U\n#EXT-X-VERSION:3\n\n";
    foreach ($playlists as $quality => $info) {
        list($width, $height) = explode(':', $info['resolution']);
        $content .= sprintf("#EXT-X-STREAM-INF:BANDWIDTH=%d,RESOLUTION=%dx%d\n%s\n\n", $info['bandwidth'], $width, $height, $info['path']);
    }
    return file_put_contents($masterFile, $content) !== false;
}

// ============================================
// Main Execution
// ============================================

printHeader();

// FFmpeg Check
echo '<div class="card"><div class="card-header">🛠️ فحص النظام</div><div class="card-body">';
if (checkFFmpeg($ffmpeg_path)) {
    echo '<div class="alert alert-success mb-0">✅ FFmpeg متوفر: <strong>' . htmlspecialchars($ffmpeg_path) . '</strong></div>';
} else {
    echo '<div class="alert alert-danger mb-0">❌ FFmpeg غير موجود!</div>';
    printFooter();
    exit;
}
echo '</div></div>';

// Fetch Videos
try {
    $sql = "SELECT id, post_id, video_url, title, video_processing, processing_percentage 
            FROM social_media_content 
            WHERE video_url IS NOT NULL 
            AND video_url != '' 
            AND (video_processing = 0 OR video_processing IS NULL)
            AND content_type != 2
            ORDER BY id DESC 
            LIMIT 5";

    $stmt = $db->query($sql);
    $videos = $stmt->fetchAll(PDO::FETCH_ASSOC);

    echo '<div class="card">
        <div class="card-header">📋 قائمة المعالجة (أحدث الفيديوهات)</div>
        <div class="card-body p-0">
            <table class="table table-striped table-hover mb-0">
                <thead>
                    <tr>
                        <th width="5%">#</th>
                        <th width="10%">ID</th>
                        <th width="30%">العنوان</th>
                        <th width="35%">التقدم</th>
                        <th width="20%">الحالة</th>
                    </tr>
                </thead>
                <tbody>';

    if (empty($videos)) {
        echo '<tr><td colspan="5" class="text-center p-4">لا توجد فيديوهات بحاجة للمعالجة 🎉</td></tr>';
    } else {
        foreach ($videos as $video) {
            $id = $video['id'];
            $title = $video['title'] ? mb_substr($video['title'], 0, 40) . '...' : 'بدون عنوان';
            $percent = $video['processing_percentage'];

            echo "<tr>
                    <td>{$id}</td>
                    <td>{$video['post_id']}</td>
                    <td>" . htmlspecialchars($title) . "</td>
                    <td>
                        <div class='progress'>
                            <div id='progress-bar-{$id}' class='progress-bar progress-bar-striped progress-bar-animated bg-info' role='progressbar' style='width: {$percent}%'>{$percent}%</div>
                        </div>
                        <small id='progress-text-{$id}' class='text-muted'>في الانتظار...</small>
                    </td>
                    <td id='status-{$id}'>
                        <span class='badge bg-secondary'>في الانتظار</span>
                    </td>
                  </tr>";
        }
    }
    echo '</tbody></table></div></div>';

    flushOutput();

    // Loop for processing
    if (!empty($videos)) {
        echo '<div class="card"><div class="card-header">⚡ سجل العمليات</div><div class="card-body log-console">';

        foreach ($videos as $video) {
            $id = $video['id'];
            $postId = $video['post_id'];
            $videoUrl = $video['video_url'];

            // Skip if already processed (just in case query logic changes)
            if ($video['video_processing'] == 2)
                continue;

            echo "<div>[" . date('H:i:s') . "] البدء في معالجة ID: <strong>$id</strong></div>";
            flushOutput();

            // File Check logic
            $inputFile = '';
            $localCandidate = $media_dir . $postId . '.mp4';

            if (file_exists($localCandidate)) {
                $inputFile = $localCandidate;
            } elseif (!filter_var($videoUrl, FILTER_VALIDATE_URL) && file_exists($media_dir . $videoUrl)) {
                $inputFile = $media_dir . $videoUrl;
            }

            if (empty($inputFile)) {
                echo "<div style='color:orange;'>⚠️ تم التخطي: الملف مفقود</div>";
                echo "<div>مسارات تم فحصها:<br>- Local: $localCandidate<br>- URL Based: " . ($media_dir . $videoUrl) . "</div>";

                $updateResult = updateProcessingStatus($db, $id, 3); // 3 = Failed/Skipped
                if ($updateResult) {
                    echo "<div style='color:green;'>✅ تم تحديث الحالة في قاعدة البيانات إلى 3 (فشل/تخطي)</div>";
                } else {
                    echo "<div style='color:red;'>❌ فشل تحديث قاعدة البيانات! تحقق من الأخطاء.</div>";
                }

                echo "<script>document.getElementById('status-{$id}').innerHTML = '<span class=\"badge bg-danger\">ملف مفقود</span>';</script>";
                flushOutput();
                continue;
            }

            updateProcessingStatus($db, $id, 1, 0); // Start
            echo "<script>
                document.getElementById('status-{$id}').innerHTML = '<span class=\"badge bg-primary\">جاري المعالجة</span>';
                document.getElementById('progress-bar-{$id}').classList.remove('bg-secondary');
                document.getElementById('progress-bar-{$id}').classList.add('bg-info');
            </script>";
            flushOutput();

            $outputDir = $media_dir . $postId . '_hls/';
            $logBuffer = "";
            $startTime = microtime(true);

            $success = processVideoToHLS($ffmpeg_path, $inputFile, $outputDir, $qualities, $db, $id, $logBuffer);

            $duration = round(microtime(true) - $startTime, 2);
            echo "<div style='padding-left:15px; border-left: 2px solid #555; margin: 5px 0;'>$logBuffer</div>";

            if ($success) {
                updateProcessingStatus($db, $id, 2, 100); // Completed
                echo "<div style='color:lightgreen;'>✅ تمت بنجاح ($duration ث)</div>";
                echo "<script>
                    document.getElementById('status-{$id}').innerHTML = '<span class=\"badge bg-success\">مكتمل</span>';
                    document.getElementById('progress-bar-{$id}').style.width = '100%';
                    document.getElementById('progress-bar-{$id}').innerText = '100%';
                    document.getElementById('progress-bar-{$id}').classList.remove('bg-info', 'progress-bar-animated');
                    document.getElementById('progress-bar-{$id}').classList.add('bg-success');
                    document.getElementById('progress-text-{$id}').innerText = 'اكتملت المعالجة';
                </script>";
            } else {
                updateProcessingStatus($db, $id, 3); // 3 = Failed/Skipped
                echo "<div style='color:red;'>❌ فشلت المعالجة (تم تحديث الحالة إلى فشل)</div>";
                echo "<script>
                    document.getElementById('status-{$id}').innerHTML = '<span class=\"badge bg-danger\">فشل</span>';
                    document.getElementById('progress-bar-{$id}').classList.add('bg-danger');
                </script>";
            }

            echo "<hr style='border-color:#444;'>";
            flushOutput();
        }
        echo '</div></div>';
    }

} catch (PDOException $e) {
    echo '<div class="alert alert-danger">خطأ في قاعدة البيانات: ' . $e->getMessage() . '</div>';
}

printFooter();
?>