<?php
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../config/media.php';
requireLogin();
$user = getCurrentUser();
if (!hasRole('instructor') && !hasPermission('can_create_courses')) {
    redirect('dashboard.php');
}
$db = Database::getInstance();

$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$course_id = isset($_GET['course_id']) ? (int)$_GET['course_id'] : 0;
$lesson = null;
if ($id) {
    $lesson = $db->get("SELECT * FROM course_lessons WHERE id = ? AND (SELECT c.instructor_id FROM courses c WHERE c.id = course_lessons.course_id) = ?", [$id, $user['id']]);
    if (!$lesson) redirect('dashboard.php');
    $course_id = $lesson['course_id'];
}

// Load modules for the selected course (optional). Used to let instructors assign a lesson to a module.
$modules = [];
if ($course_id) {
    $modules = $db->getAll("SELECT id, title FROM course_modules WHERE course_id = ? ORDER BY sort_order, id", [$course_id]);
} 

// Handle upload directory (store in project-level uploads folder)
function lesson_upload_dir($courseId) {
    $dir = __DIR__ . "/../uploads/courses/" . (int)$courseId . "/lessons";
    if (!is_dir($dir)) mkdir($dir, 0755, true);
    return $dir;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $title = trim($_POST['title'] ?? '');
    $description = trim($_POST['description'] ?? '');
    $content_type = $_POST['content_type'] ?? 'text';
    $content_text = null;
    $content_url = null;
    $downloadable_resources = [];

    // Save text content
    if ($content_type === 'text') {
        $content_text = trim($_POST['content_text'] ?? '');
    }

    // Ensure course_id
    if (!$course_id) {
        $course_id = (int)($_POST['course_id'] ?? 0);
    }

    // Server-side validation helpers
    function is_allowed_mime($mime, $ctype) {
        return in_array($mime, MEDIA_ALLOWED[$ctype] ?? []);
    }

    // Handle primary content file (form-upload fallback)
    if (in_array($content_type, ['video','slides','assignment','live_session']) && isset($_FILES['content_file']) && $_FILES['content_file']['error'] === UPLOAD_ERR_OK) {
        $file = $_FILES['content_file'];
        $tmp = $file['tmp_name'];
        $size = (int)$file['size'];

        $max = MEDIA_MAX_SIZE[$content_type] ?? (50 * 1024 * 1024);
        if ($size > $max) {
            $errors[] = 'Uploaded file exceeds maximum allowed size for ' . htmlspecialchars($content_type);
        } else {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime = finfo_file($finfo, $tmp);
            finfo_close($finfo);

            if (!is_allowed_mime($mime, $content_type)) {
                $errors[] = 'Uploaded file type (' . htmlspecialchars($mime) . ') is not allowed for ' . htmlspecialchars($content_type);
            } else {
                $dir = lesson_upload_dir($course_id);
                $name = preg_replace('/[^A-Za-z0-9._-]/', '_', basename($file['name']));
                $targetName = time() . '_' . $name;
                $target = $dir . DIRECTORY_SEPARATOR . $targetName;
                if (move_uploaded_file($tmp, $target)) {
                    $content_url = MEDIA_WEBPATH . '/' . (int)$course_id . '/lessons/' . $targetName;

                    // generate thumbnail if video and ffmpeg present
                    $thumbnail = null;
                    if ($content_type === 'video' && defined('FFMPEG_PATH') && is_executable(FFMPEG_PATH)) {
                        $thumbName = pathinfo($targetName, PATHINFO_FILENAME) . '.jpg';
                        $thumbTarget = $dir . DIRECTORY_SEPARATOR . $thumbName;
                        $cmd = escapeshellcmd(FFMPEG_PATH) . ' -y -ss 00:00:01 -i ' . escapeshellarg($target) . ' -frames:v 1 -q:v 2 ' . escapeshellarg($thumbTarget) . ' 2>&1';
                        @shell_exec($cmd);
                        if (file_exists($thumbTarget)) {
                            $thumbnail = MEDIA_WEBPATH . '/' . (int)$course_id . '/lessons/' . $thumbName;
                        }
                    }

                    // insert metadata
                    $db->query("INSERT INTO course_media (course_id, lesson_id, file_path, mime, size, thumbnail_path) VALUES (?, ?, ?, ?, ?, ?)", [ $course_id, null, $content_url, $mime, $size, $thumbnail ]);
                } else {
                    $errors[] = 'Failed to move uploaded file to storage.';
                }
            }
        }
    }

    // Handle multiple downloadable resources (form fallback)
    if (isset($_FILES['resources'])) {
        $files = $_FILES['resources'];
        $dir = lesson_upload_dir($course_id);
        for ($i = 0; $i < count($files['name']); $i++) {
            if ($files['error'][$i] === UPLOAD_ERR_OK) {
                $tmp = $files['tmp_name'][$i];
                $size = (int)$files['size'][$i];
                $name = preg_replace('/[^A-Za-z0-9._-]/', '_', basename($files['name'][$i]));
                $targetName = time() . '_' . $name;
                $target = $dir . DIRECTORY_SEPARATOR . $targetName;

                // Basic MIME/size check (allow many resource types)
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $mime = finfo_file($finfo, $tmp);
                finfo_close($finfo);

                if ($size > (50 * 1024 * 1024)) {
                    $errors[] = 'One of the resource files exceeds the 50MB limit.';
                    continue;
                }

                if (move_uploaded_file($tmp, $target)) {
                    $rel = MEDIA_WEBPATH . '/' . (int)$course_id . '/lessons/' . $targetName;
                    $downloadable_resources[] = $rel;
                    $db->query("INSERT INTO course_media (course_id, lesson_id, file_path, mime, size) VALUES (?, ?, ?, ?, ?)", [ $course_id, null, $rel, $mime, $size ]);
                }
            }
        }
    }

    // If AJAX upload provided a path, use it
    if (empty($content_url) && !empty($_POST['content_file_path'])) {
        $content_url = trim($_POST['content_file_path']);
    }

    // Update or insert lesson
    if (empty($errors)) {
        if ($id) {
            $db->query("UPDATE course_lessons SET title = ?, description = ?, content_type = ?, content_url = ?, content_text = ?, downloadable_resources = ? WHERE id = ?", [$title, $description, $content_type, $content_url ?: $lesson['content_url'], $content_text ?: $lesson['content_text'], !empty($downloadable_resources) ? json_encode($downloadable_resources) : $lesson['downloadable_resources'], $id]);
            header('Location: ' . APP_URL . '/lms/courses.php?course_id=' . (int)$course_id);
            exit;
        } else {
            // Ensure module_id is properly treated as NULL when not provided
            $module_id = null;
            if (isset($_POST['module_id']) && $_POST['module_id'] !== '') {
                $module_id = (int)$_POST['module_id'];
            }

            $db->query("INSERT INTO course_lessons (module_id, course_id, title, description, content_type, content_url, content_text, downloadable_resources, is_published) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)", [$module_id, $course_id, $title, $description, $content_type, $content_url, $content_text, !empty($downloadable_resources) ? json_encode($downloadable_resources) : null]);
            $newId = $db->getLastInsertId();
            // associate any uploaded media records that were uploaded before saving the lesson
            if (!empty($content_url)) {
                $db->query("UPDATE course_media SET lesson_id = ? WHERE course_id = ? AND file_path = ? AND (lesson_id IS NULL OR lesson_id = 0)", [$newId, $course_id, $content_url]);
            }
            header('Location: ' . APP_URL . '/lms/courses.php?course_id=' . (int)$course_id);
            exit;
        }
    }
}

$pageTitle = $id ? 'Edit Lesson' : 'New Lesson';

// Warn if PHP upload limits are lower than configured limits
function php_ini_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    $num = (int)$val;
    switch($last) {
        case 'g': $num *= 1024;
        case 'm': $num *= 1024;
        case 'k': $num *= 1024;
    }
    return $num;
}
$uploadMax = php_ini_bytes(ini_get('upload_max_filesize'));
$postMax = php_ini_bytes(ini_get('post_max_size'));
$maxConfigured = max(MEDIA_MAX_SIZE);
$phpLimitWarning = ($uploadMax < $maxConfigured || $postMax < $maxConfigured);

include __DIR__ . '/includes/header.php';
?>

<div class="row">
    <div class="col-md-8">
        <div class="card">
            <div class="card-header"><h5 class="m-0"><?php echo htmlspecialchars($pageTitle); ?></h5></div>
            <div class="card-body">
                <?php if (!empty($phpLimitWarning)): ?>
                    <div class="alert alert-warning">Server PHP upload limits (upload_max_filesize or post_max_size) may be lower than configured media limits. Please check PHP settings.</div>
                <?php endif; ?>
                <form method="post" enctype="multipart/form-data">
                    <div class="mb-3">
                        <label class="form-label">Course ID</label>
                        <input class="form-control" name="course_id" value="<?php echo htmlspecialchars($course_id); ?>" required />
                    </div>
                    <?php if (!empty($modules)): ?>
                    <div class="mb-3">
                        <label class="form-label">Module (optional)</label>
                        <select name="module_id" class="form-select">
                            <option value="">None</option>
                            <?php foreach ($modules as $m): ?>
                                <option value="<?php echo (int)$m['id']; ?>" <?php echo (isset($lesson['module_id']) && (int)$lesson['module_id'] === (int)$m['id']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($m['title']); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <?php endif; ?>

                    <div class="mb-3">
                        <label class="form-label">Title</label>
                        <input class="form-control" name="title" value="<?php echo htmlspecialchars($lesson['title'] ?? ''); ?>" required />
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Description</label>
                        <textarea class="form-control" name="description"><?php echo htmlspecialchars($lesson['description'] ?? ''); ?></textarea>
                    </div>
                    <div class="mb-3">
                        <label class="form-label">Content Type</label>
                        <select name="content_type" class="form-select" id="content_type">
                            <option value="text" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'text') ? 'selected' : ''; ?>>Text</option>
                            <option value="video" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'video') ? 'selected' : ''; ?>>Video</option>
                            <option value="slides" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'slides') ? 'selected' : ''; ?>>Slides</option>
                            <option value="quiz" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'quiz') ? 'selected' : ''; ?>>Quiz</option>
                            <option value="assignment" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'assignment') ? 'selected' : ''; ?>>Assignment</option>
                            <option value="live_session" <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'live_session') ? 'selected' : ''; ?>>Live Session</option>
                        </select>
                    </div>

                    <div class="mb-3" id="text_content" style="display: <?php echo (isset($lesson['content_type']) && $lesson['content_type'] === 'text') ? 'block' : 'none'; ?>">
                        <label class="form-label">Text Content</label>
                        <textarea class="form-control" name="content_text"><?php echo htmlspecialchars($lesson['content_text'] ?? ''); ?></textarea>
                    </div>

                    <div class="mb-3" id="file_content" style="display: <?php echo (isset($lesson['content_type']) && $lesson['content_type'] !== 'text') ? 'block' : 'none'; ?>">
                        <label class="form-label">Upload File (video/pdf/zip)</label>
                        <input type="file" id="content_file_input" name="content_file" class="form-control" />
                        <input type="hidden" id="content_file_path" name="content_file_path" value="<?php echo htmlspecialchars($lesson['content_url'] ?? ''); ?>" />
                        <div class="progress mt-2" id="upload_progress" style="display:none; height:8px;">
                            <div class="progress-bar" role="progressbar" style="width:0%"></div>
                        </div>
                        <div id="upload_status" class="small text-muted mt-1"></div>
                    </div>

                    <div class="mb-3">
                        <label class="form-label">Downloadable Resources (multiple)</label>
                        <input type="file" name="resources[]" class="form-control" multiple />
                    </div>

                    <div>
                        <button class="btn btn-success">Save</button>
                        <a class="btn btn-outline-secondary ms-2" href="<?php echo APP_URL; ?>/lms/courses.php?course_id=<?php echo (int)$course_id; ?>">Cancel</a>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

<script>
// Simple client-side validation and AJAX upload with progress
var MEDIA_ALLOWED = <?php echo json_encode(MEDIA_ALLOWED); ?>;
var MEDIA_MAX_SIZE = <?php echo json_encode(MEDIA_MAX_SIZE); ?>;

document.getElementById('content_type').addEventListener('change', function(){
    var v = this.value;
    document.getElementById('text_content').style.display = v === 'text' ? 'block' : 'none';
    document.getElementById('file_content').style.display = v === 'text' ? 'none' : 'block';
});

(function(){
    var input = document.getElementById('content_file_input');
    if (!input) return;
    var progress = document.getElementById('upload_progress');
    var progressBar = progress ? progress.querySelector('.progress-bar') : null;
    var status = document.getElementById('upload_status');
    var hiddenPath = document.getElementById('content_file_path');

    input.addEventListener('change', function(){
        var file = this.files[0];
        if (!file) return;
        var ctype = document.getElementById('content_type').value || 'assignment';
        var courseId = document.querySelector('input[name="course_id"]').value;

        // client-side size check
        var max = MEDIA_MAX_SIZE[ctype] || (50*1024*1024);
        if (file.size > max) {
            showToast('File exceeds maximum allowed size for ' + ctype, 'danger');
            this.value = '';
            return;
        }

        // client-side mime check (best-effort via file.type)
        var allowed = MEDIA_ALLOWED[ctype] || [];
        if (allowed.length && allowed.indexOf(file.type) === -1) {
            showToast('File type ' + file.type + ' is not allowed for ' + ctype, 'danger');
            this.value = '';
            return;
        }

        var CHUNK_SIZE = 5 * 1024 * 1024; // 5MB

        function uploadChunked(file) {
            return new Promise(function(resolve, reject){
                var total = Math.ceil(file.size / CHUNK_SIZE);
                var identifier = Date.now().toString(36) + Math.random().toString(36).substring(2,8);
                var current = 0;

                function sendChunk(i) {
                    var start = i * CHUNK_SIZE;
                    var end = Math.min(start + CHUNK_SIZE, file.size);
                    var blob = file.slice(start, end);
                    var fd = new FormData();
                    fd.append('chunk', blob);
                    fd.append('course_id', courseId);
                    fd.append('identifier', identifier);
                    fd.append('chunk_index', i);
                    fd.append('total_chunks', total);
                    fd.append('filename', file.name);
                    fd.append('type', ctype);

                    var xhrChunk = new XMLHttpRequest();
                    xhrChunk.open('POST', '<?php echo APP_URL; ?>/lms/api/upload_chunk.php', true);
                    xhrChunk.onload = function() {
                        if (xhrChunk.status === 200) {
                            try { var r = JSON.parse(xhrChunk.responseText); } catch (e) { r = {}; }
                            var pct = Math.round(((i+1)/total) * 100);
                            if (progress) progress.style.display = 'block';
                            if (progressBar) progressBar.style.width = pct + '%';

                            if ((i+1) < total) {
                                sendChunk(i+1);
                            } else {
                                // final response should include success and file info
                                if (r.success) resolve(r);
                                else reject(r.error || 'Chunked upload failed');
                            }
                        } else {
                            reject('Chunk upload HTTP ' + xhrChunk.status);
                        }
                    };
                    xhrChunk.onerror = function() { reject('Chunk upload failed'); };
                    xhrChunk.send(fd);
                }

                sendChunk(0);
            });
        }

        // Decide whether to perform chunked upload
        var threshold = 20 * 1024 * 1024; // 20MB
        if (file.size > threshold) {
            status.innerText = 'Uploading large file...';
            uploadChunked(file).then(function(res){
                progress.style.display = 'none';
                if (res && res.success) {
                    hiddenPath.value = res.file_path;
                    showToast('Chunked upload completed', 'success');
                    status.innerText = 'Uploaded: ' + res.file_path;
                } else {
                    showToast(res.error || 'Chunked upload failed', 'danger');
                }
            }).catch(function(err){
                progress.style.display = 'none';
                showToast('Upload error: ' + err, 'danger');
            });
        } else {
            // Small files: single upload
            var xhr = new XMLHttpRequest();
            var form = new FormData();
            form.append('file', file);
            form.append('course_id', courseId);
            form.append('type', ctype);

            xhr.open('POST', '<?php echo APP_URL; ?>/lms/api/upload_lesson_file.php', true);

            xhr.upload.onprogress = function(e) {
                if (e.lengthComputable) {
                    var pct = Math.round((e.loaded / e.total) * 100);
                    if (progress) progress.style.display = 'block';
                    if (progressBar) progressBar.style.width = pct + '%';
                }
            };

            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    progress.style.display = 'none';
                    if (xhr.status === 200) {
                        var res = {};
                        try { res = JSON.parse(xhr.responseText); } catch (e) {}
                        if (res.success) {
                            hiddenPath.value = res.file_path;
                            showToast('Upload completed', 'success');
                            status.innerText = 'Uploaded: ' + res.file_path;
                        } else {
                            showToast(res.error || 'Upload failed', 'danger');
                        }
                    } else {
                        showToast('Upload error: ' + xhr.status, 'danger');
                    }
                }
            };

            xhr.send(form);
        }
    });
})();

</script>

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