<?php
declare(strict_types=1);

/**
 * EnglishSpeak - Teacher Lessons
 * File: teacher/lessons/store.php
 *
 * Creates one Lesson under one Unit.
 */

require __DIR__ . '/../partials/auth.php';
require_once __DIR__ . '/../../config/database.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: index.php');
    exit;
}

$pdo = getDbConnection();

$teacherId = (int)($_SESSION['teacher_id'] ?? $_SESSION['user_id'] ?? 0);
$role = strtolower((string)($_SESSION['role'] ?? $_SESSION['user_role'] ?? 'teacher'));
$isAdmin = ($role === 'admin');
$createdByTeacherId = $isAdmin ? null : $teacherId;

if (!$isAdmin && $teacherId <= 0) {
    http_response_code(403);
    exit('Teacher account not found.');
}

$bookId = max(0, (int)($_POST['book_id'] ?? 0));
$unitId = max(0, (int)($_POST['unit_id'] ?? 0));
$lessonNumber = trim((string)($_POST['lesson_number'] ?? ''));
$title = trim((string)($_POST['title'] ?? ''));
$lessonType = trim((string)($_POST['lesson_type'] ?? 'vocabulary'));
$description = trim((string)($_POST['description'] ?? ''));
$accessType = (string)($_POST['access_type'] ?? 'free');
$requiredXp = max(0, (int)($_POST['required_xp'] ?? 0));
$sortOrder = max(0, (int)($_POST['sort_order'] ?? 0));
$status = (string)($_POST['status'] ?? 'active');
$unlockMode = (string)($_POST['unlock_mode'] ?? 'sequential_daily');
$unlockDate = trim((string)($_POST['unlock_date'] ?? ''));

$allowedLessonTypes = [
    'vocabulary',
    'listening',
    'speaking',
    'reading',
    'writing',
    'phonics',
    'story',
    'review',
    'song',
    'chant',
];

if (!in_array($lessonType, $allowedLessonTypes, true)) {
    $lessonType = 'vocabulary';
}

if (!in_array($accessType, ['free', 'premium'], true)) {
    $accessType = 'free';
}

if (!in_array($status, ['active', 'inactive'], true)) {
    $status = 'active';
}

if (!in_array($unlockMode, ['sequential_daily', 'scheduled'], true)) {
    $unlockMode = 'sequential_daily';
}

if ($unlockMode === 'sequential_daily') {
    $unlockDate = '';
}

$old = [
    'book_id' => $bookId,
    'unit_id' => $unitId,
    'lesson_number' => $lessonNumber,
    'title' => $title,
    'lesson_type' => $lessonType,
    'description' => $description,
    'access_type' => $accessType,
    'required_xp' => $requiredXp,
    'sort_order' => $sortOrder,
    'status' => $status,
    'unlock_mode' => $unlockMode,
    'unlock_date' => $unlockDate,
];

$errors = [];

// Validate Unit and Book relationship.
if ($bookId <= 0) {
    $errors[] = 'Please select a Book.';
}

if ($unitId <= 0) {
    $errors[] = 'Please select a Unit.';
}

if ($bookId > 0 && $unitId > 0) {
    $unitSql = "
        SELECT u.id
        FROM units u
        INNER JOIN books b ON b.id = u.book_id
        WHERE u.id = ?
          AND u.book_id = ?
          AND u.status = 'active'
          AND b.status = 'active'
    ";
    $unitParams = [$unitId, $bookId];

    if (!$isAdmin) {
        $unitSql .= "
          AND EXISTS (
              SELECT 1
              FROM teacher_books tb
              WHERE tb.teacher_id = ?
                AND tb.book_id = u.book_id
          )
        ";
        $unitParams[] = $teacherId;
    }

    $unitSql .= " LIMIT 1";

    $unitStmt = $pdo->prepare($unitSql);
    $unitStmt->execute($unitParams);

    if (!$unitStmt->fetchColumn()) {
        $errors[] = $isAdmin
            ? 'The selected Unit does not belong to the selected Book.'
            : 'You are not allowed to create a Lesson in this Book.';
    }
}

// Validate fields.
if ($lessonNumber === '') {
    $errors[] = 'Lesson Number is required.';
} elseif (mb_strlen($lessonNumber) > 30) {
    $errors[] = 'Lesson Number must not exceed 30 characters.';
}

if ($title === '') {
    $errors[] = 'Lesson Title is required.';
} elseif (mb_strlen($title) > 150) {
    $errors[] = 'Lesson Title must not exceed 150 characters.';
}

if ($lessonType !== '' && mb_strlen($lessonType) > 50) {
    $errors[] = 'Lesson Type is too long.';
}

if (mb_strlen($description) > 5000) {
    $errors[] = 'Description is too long.';
}

if ($unlockMode === 'scheduled') {
    if ($unlockDate === '') {
        $errors[] = 'Please select an Unlock Date for Scheduled Unlock.';
    } else {
        $date = DateTimeImmutable::createFromFormat('!Y-m-d', $unlockDate);
        if (!$date || $date->format('Y-m-d') !== $unlockDate) {
            $errors[] = 'Unlock Date is invalid.';
        }
    }
}

// Unique Lesson Number inside one Unit.
if ($unitId > 0 && $lessonNumber !== '') {
    $duplicateStmt = $pdo->prepare(
        "SELECT id
         FROM lessons
         WHERE unit_id = ?
           AND LOWER(TRIM(lesson_number)) = LOWER(TRIM(?))
         LIMIT 1"
    );
    $duplicateStmt->execute([$unitId, $lessonNumber]);

    if ($duplicateStmt->fetchColumn()) {
        $errors[] = 'This Lesson Number already exists in the selected Unit.';
    }
}

/**
 * Validate and store an optional Lesson thumbnail.
 *
 * @return string|null Relative project path for database storage.
 */
function storeLessonThumbnail(array &$errors): ?string
{
    if (
        !isset($_FILES['thumbnail'])
        || !is_array($_FILES['thumbnail'])
        || (int)($_FILES['thumbnail']['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE
    ) {
        return null;
    }

    $file = $_FILES['thumbnail'];
    $errorCode = (int)($file['error'] ?? UPLOAD_ERR_NO_FILE);

    if ($errorCode !== UPLOAD_ERR_OK) {
        $errors[] = 'The thumbnail could not be uploaded.';
        return null;
    }

    $tmpPath = (string)($file['tmp_name'] ?? '');
    $size = (int)($file['size'] ?? 0);

    if ($tmpPath === '' || !is_uploaded_file($tmpPath)) {
        $errors[] = 'The uploaded thumbnail is invalid.';
        return null;
    }

    if ($size <= 0 || $size > 3 * 1024 * 1024) {
        $errors[] = 'Thumbnail must be smaller than 3 MB.';
        return null;
    }

    $mime = '';

    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);

        if ($finfo !== false) {
            $mime = (string)finfo_file($finfo, $tmpPath);
            finfo_close($finfo);
        }
    }

    $allowed = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
    ];

    if (!isset($allowed[$mime])) {
        $errors[] = 'Thumbnail must be a JPG, PNG or WEBP image.';
        return null;
    }

    $projectRoot = dirname(__DIR__, 2);
    $relativeDir = 'uploads/lessons';
    $absoluteDir = $projectRoot . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'lessons';

    if (!is_dir($absoluteDir) && !mkdir($absoluteDir, 0775, true) && !is_dir($absoluteDir)) {
        $errors[] = 'The Lesson upload folder could not be created.';
        return null;
    }

    try {
        $random = bin2hex(random_bytes(8));
    } catch (Throwable $e) {
        $random = str_replace('.', '', uniqid('', true));
    }

    $filename = 'lesson-' . date('Ymd-His') . '-' . $random . '.' . $allowed[$mime];
    $absolutePath = $absoluteDir . DIRECTORY_SEPARATOR . $filename;

    if (!move_uploaded_file($tmpPath, $absolutePath)) {
        $errors[] = 'The thumbnail could not be saved.';
        return null;
    }

    return $relativeDir . '/' . $filename;
}

$thumbnail = null;

if ($errors === []) {
    $thumbnail = storeLessonThumbnail($errors);
}

if ($errors !== []) {
    $_SESSION['lessons_old'] = $old;
    $_SESSION['lessons_errors'] = $errors;

    header('Location: create.php' . ($unitId > 0 ? '?unit_id=' . $unitId : ''));
    exit;
}

try {
    $stmt = $pdo->prepare(
        "INSERT INTO lessons
            (
                unit_id,
                created_by_teacher_id,
                lesson_number,
                title,
                lesson_type,
                thumbnail,
                description,
                access_type,
                required_xp,
                unlock_mode,
                unlock_date,
                sort_order,
                status,
                created_at,
                updated_at
            )
         VALUES
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())"
    );

    $pdo->beginTransaction();

    $stmt->execute([
        $unitId,
        $createdByTeacherId,
        $lessonNumber,
        $title,
        $lessonType !== '' ? $lessonType : null,
        $thumbnail,
        $description !== '' ? $description : null,
        $accessType,
        $requiredXp,
        $unlockMode,
        $unlockMode === 'scheduled' ? $unlockDate : null,
        $sortOrder,
        $status,
    ]);

    $lessonId = (int)$pdo->lastInsertId();

    // V3.2 Review/Publish: every new Lesson starts as Draft.
    $workflowStmt = $pdo->prepare(
        "INSERT INTO content_review_workflow
            (content_type, content_id, author_id, status, created_at, updated_at)
         VALUES ('lesson', ?, ?, 'draft', NOW(), NOW())
         ON DUPLICATE KEY UPDATE author_id = VALUES(author_id), updated_at = NOW()"
    );
    $workflowStmt->execute([$lessonId, $teacherId]);

    $pdo->commit();

    $_SESSION['lessons_message'] = 'Lesson created successfully as Draft.';
    $_SESSION['lessons_message_type'] = 'success';

    header('Location: index.php?book_id=' . $bookId . '&unit_id=' . $unitId);
    exit;
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    // Remove uploaded thumbnail when the insert fails.
    if ($thumbnail !== null) {
        $absoluteThumbnail = dirname(__DIR__, 2)
            . DIRECTORY_SEPARATOR
            . str_replace('/', DIRECTORY_SEPARATOR, $thumbnail);

        if (is_file($absoluteThumbnail)) {
            @unlink($absoluteThumbnail);
        }
    }

    $_SESSION['lessons_old'] = $old;

    if ($e instanceof PDOException && (string)$e->getCode() === '23000') {
        $_SESSION['lessons_errors'] = [
            'This Lesson Number already exists in the selected Unit.',
        ];
    } else {
        $_SESSION['lessons_errors'] = [
            'Could not create the Lesson. Please try again.',
        ];
    }

    header('Location: create.php?unit_id=' . $unitId);
    exit;
}
