<?php
declare(strict_types=1);

/**
 * EnglishSpeak - Sentence Library V2
 * File: teacher/sentence-library/index.php
 *
 * Features:
 * - Compact toolbar
 * - Search and filters
 * - Modal Add/Edit
 * - Book / Level / Topic / Tags
 * - Image and audio paths
 * - Preview / Play / Duplicate / Delete
 * - Multi-select prepared for Sentence Sets
 */

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

$pdo = getDbConnection();

$currentUserId = (int)($_SESSION['user_id'] ?? 0);
$currentUserRole = strtolower(trim((string)($_SESSION['user_role'] ?? $_SESSION['role'] ?? 'teacher')));
$isAdmin = $currentUserRole === 'admin';

$pageTitle = 'Sentence Library';
$pageSubtitle = 'Manage reusable sentences';
$activeTeacherNav = 'content';

function slv2TableExists(PDO $pdo, string $table): bool
{
    $stmt = $pdo->prepare(
        "SELECT COUNT(*)
         FROM information_schema.TABLES
         WHERE TABLE_SCHEMA = DATABASE()
           AND TABLE_NAME = ?"
    );
    $stmt->execute([$table]);

    return (int)$stmt->fetchColumn() > 0;
}

function slv2Columns(PDO $pdo, string $table): array
{
    if (!slv2TableExists($pdo, $table)) {
        return [];
    }

    $rows = $pdo
        ->query("SHOW COLUMNS FROM `{$table}`")
        ->fetchAll(PDO::FETCH_ASSOC);

    return array_column($rows, null, 'Field');
}

function slv2FirstColumn(array $columns, array $candidates): ?string
{
    foreach ($candidates as $candidate) {
        if (isset($columns[$candidate])) {
            return $candidate;
        }
    }

    return null;
}

function slv2Clean(string $value): string
{
    $value = trim($value);
    $value = preg_replace('/\s+/u', ' ', $value) ?? $value;

    return trim($value);
}

function slv2NormalizeWord(string $value): string
{
    $value = mb_strtolower(trim($value), 'UTF-8');
    $value = preg_replace('/[^\\p{L}\\p{N}\']+/u', '', $value) ?? $value;

    return trim($value);
}

function slv2SentenceTokens(string $sentence): array
{
    $sentence = mb_strtolower($sentence, 'UTF-8');
    $parts = preg_split('/[^\\p{L}\\p{N}\']+/u', $sentence) ?: [];

    return array_values(array_filter(array_map(
        static fn(string $part): string => slv2NormalizeWord($part),
        $parts
    )));
}

function slv2AssetUrl(string $path): string
{
    $path = trim($path);

    if ($path === '') {
        return '';
    }

    if (
        str_starts_with($path, 'http://')
        || str_starts_with($path, 'https://')
        || str_starts_with($path, 'data:')
        || str_starts_with($path, '/')
    ) {
        return $path;
    }

    return '/EnglishSpeak/' . ltrim($path, './');
}


function slv2StoreSentenceImage(array $file): string
{
    if (
        !isset($file['error'])
        || (int)$file['error'] === UPLOAD_ERR_NO_FILE
    ) {
        return '';
    }

    if ((int)$file['error'] !== UPLOAD_ERR_OK) {
        throw new RuntimeException('Không thể tải ảnh lên. Vui lòng thử lại.');
    }

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

    if ($tmpName === '' || !is_uploaded_file($tmpName)) {
        throw new RuntimeException('Tệp ảnh tải lên không hợp lệ.');
    }

    if ($size <= 0 || $size > 5 * 1024 * 1024) {
        throw new RuntimeException('Ảnh phải nhỏ hơn hoặc bằng 5 MB.');
    }

    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime = (string)$finfo->file($tmpName);

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

    if (!isset($allowed[$mime])) {
        throw new RuntimeException('Chỉ hỗ trợ ảnh JPG, PNG, WEBP hoặc GIF.');
    }

    $uploadDir = dirname(__DIR__, 2) . '/uploads/sentences';

    if (!is_dir($uploadDir) && !mkdir($uploadDir, 0775, true) && !is_dir($uploadDir)) {
        throw new RuntimeException('Không thể tạo thư mục lưu ảnh sentence.');
    }

    $fileName = 'sentence_' . date('Ymd_His') . '_'
        . bin2hex(random_bytes(6))
        . '.' . $allowed[$mime];

    $destination = $uploadDir . '/' . $fileName;

    if (!move_uploaded_file($tmpName, $destination)) {
        throw new RuntimeException('Không thể lưu ảnh sentence.');
    }

    return 'uploads/sentences/' . $fileName;
}

function slv2FindTopicTable(PDO $pdo): array
{
    foreach (
        [
            ['topics', ['name', 'title']],
            ['word_topics', ['name', 'title']],
            ['topic_library', ['name', 'title']],
        ]
        as [$table, $nameCandidates]
    ) {
        $columns = slv2Columns($pdo, $table);

        if ($columns === [] || !isset($columns['id'])) {
            continue;
        }

        $nameColumn = slv2FirstColumn($columns, $nameCandidates);

        if ($nameColumn !== null) {
            return [$table, $nameColumn];
        }
    }

    return ['', ''];
}

if (!slv2TableExists($pdo, 'sentences')) {
    http_response_code(500);
    exit('The sentences table does not exist.');
}

$columns = slv2Columns($pdo, 'sentences');

$textColumn = slv2FirstColumn(
    $columns,
    ['sentence_text', 'sentence', 'text', 'content']
);

$meaningColumn = slv2FirstColumn(
    $columns,
    ['vietnamese_meaning', 'meaning_vi', 'meaning']
);

$ipaColumn = slv2FirstColumn(
    $columns,
    ['ipa', 'phonetic']
);

$imageColumn = slv2FirstColumn(
    $columns,
    ['image_path', 'image', 'image_url']
);

$audioColumn = slv2FirstColumn(
    $columns,
    ['audio_us_path', 'audio_path', 'audio', 'audio_url']
);

$bookColumn = isset($columns['book_id']) ? 'book_id' : null;
$levelColumn = isset($columns['level_id']) ? 'level_id' : null;
$topicColumn = isset($columns['topic_id']) ? 'topic_id' : null;
$tagsColumn = isset($columns['tags']) ? 'tags' : null;
$statusColumn = isset($columns['status']) ? 'status' : null;
$ownerColumn = isset($columns['created_by_teacher_id']) ? 'created_by_teacher_id' : null;

if ($textColumn === null) {
    http_response_code(500);
    exit('The sentences table does not contain a sentence text column.');
}

$books = [];
if (slv2TableExists($pdo, 'books')) {
    $bookColumns = slv2Columns($pdo, 'books');
    $bookNameColumn = slv2FirstColumn($bookColumns, ['name', 'title']);

    if ($bookNameColumn !== null) {
        $books = $pdo->query(
            "SELECT id, `{$bookNameColumn}` AS name
             FROM books
             ORDER BY `{$bookNameColumn}` ASC"
        )->fetchAll(PDO::FETCH_ASSOC);
    }
}

$levels = [];
if (slv2TableExists($pdo, 'levels')) {
    $levelColumns = slv2Columns($pdo, 'levels');
    $levelNameColumn = slv2FirstColumn($levelColumns, ['name', 'title']);

    if ($levelNameColumn !== null) {
        $bookSelect = isset($levelColumns['book_id'])
            ? 'book_id'
            : 'NULL AS book_id';

        $levels = $pdo->query(
            "SELECT id, {$bookSelect}, `{$levelNameColumn}` AS name
             FROM levels
             ORDER BY `{$levelNameColumn}` ASC"
        )->fetchAll(PDO::FETCH_ASSOC);
    }
}

[$topicTable, $topicNameColumn] = slv2FindTopicTable($pdo);
$topics = [];

if ($topicTable !== '' && $topicNameColumn !== '') {
    $topicColumns = slv2Columns($pdo, $topicTable);
    $topicStatusColumn = isset($topicColumns['status']) ? 'status' : null;

    $topicSql = "SELECT id, `{$topicNameColumn}` AS name
                 FROM `{$topicTable}`";

    if ($topicStatusColumn !== null) {
        $topicSql .= " WHERE `{$topicStatusColumn}`='active'";
    }

    $topicSql .= " ORDER BY `{$topicNameColumn}` ASC";

    $topics = $pdo->query($topicSql)->fetchAll(PDO::FETCH_ASSOC);
}

$error = '';
$success = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = trim((string)($_POST['action'] ?? ''));

    try {
        if ($action === 'save') {
            $id = max(0, (int)($_POST['id'] ?? 0));
            $sentenceText = slv2Clean((string)($_POST['sentence_text'] ?? ''));
            $meaning = slv2Clean((string)($_POST['vietnamese_meaning'] ?? ''));
            $ipa = slv2Clean((string)($_POST['ipa'] ?? ''));
            $tags = slv2Clean((string)($_POST['tags'] ?? ''));
            $bookId = max(0, (int)($_POST['book_id'] ?? 0));
            $levelId = max(0, (int)($_POST['level_id'] ?? 0));
            $topicId = max(0, (int)($_POST['topic_id'] ?? 0));
            $status = trim((string)($_POST['status'] ?? 'active')) === 'inactive'
                ? 'inactive'
                : 'active';

            $currentOwnImage = '';

            if ($imageColumn !== null && $id > 0) {
                $currentImageStmt = $pdo->prepare(
                    "SELECT `{$imageColumn}` FROM sentences WHERE id = ? LIMIT 1"
                );
                $currentImageStmt->execute([$id]);
                $currentOwnImage = trim((string)($currentImageStmt->fetchColumn() ?: ''));
            }

            $removeOwnImage = isset($_POST['remove_sentence_image'])
                && (string)$_POST['remove_sentence_image'] === '1';

            $uploadedOwnImage = '';

            if ($imageColumn !== null && isset($_FILES['sentence_image'])) {
                $uploadedOwnImage = slv2StoreSentenceImage($_FILES['sentence_image']);
            }

            $sentenceOwnImage = $currentOwnImage;

            if ($removeOwnImage) {
                $sentenceOwnImage = '';
            }

            if ($uploadedOwnImage !== '') {
                $sentenceOwnImage = $uploadedOwnImage;
            }

            if ($sentenceText === '') {
                throw new RuntimeException('Sentence is required.');
            }

            $duplicateSql =
                "SELECT id
                 FROM sentences
                 WHERE LOWER(TRIM(`{$textColumn}`)) = LOWER(TRIM(?))";

            $duplicateParams = [$sentenceText];

            if ($id > 0) {
                $duplicateSql .= ' AND id <> ?';
                $duplicateParams[] = $id;
            }

            $duplicateSql .= ' LIMIT 1';

            $duplicateStmt = $pdo->prepare($duplicateSql);
            $duplicateStmt->execute($duplicateParams);

            if ($duplicateStmt->fetchColumn()) {
                throw new RuntimeException(
                    'This sentence already exists in Sentence Library.'
                );
            }

            $fieldValues = [
                $textColumn => $sentenceText,
            ];

            if ($meaningColumn !== null) {
                $fieldValues[$meaningColumn] = $meaning !== '' ? $meaning : null;
            }

            if ($ipaColumn !== null) {
                $fieldValues[$ipaColumn] = $ipa !== '' ? $ipa : null;
            }


            if ($imageColumn !== null) {
                $fieldValues[$imageColumn] = $sentenceOwnImage !== ''
                    ? $sentenceOwnImage
                    : null;
            }

            if ($bookColumn !== null) {
                $fieldValues[$bookColumn] = $bookId > 0 ? $bookId : null;
            }

            if ($levelColumn !== null) {
                $fieldValues[$levelColumn] = $levelId > 0 ? $levelId : null;
            }

            if ($topicColumn !== null) {
                $fieldValues[$topicColumn] = $topicId > 0 ? $topicId : null;
            }

            if ($tagsColumn !== null) {
                $fieldValues[$tagsColumn] = $tags !== '' ? $tags : null;
            }

            if ($statusColumn !== null) {
                $fieldValues[$statusColumn] = $status;
            }

            if ($id > 0) {
                if (!$isAdmin && $ownerColumn !== null) {
                    $own = $pdo->prepare('SELECT created_by_teacher_id FROM sentences WHERE id = ? LIMIT 1');
                    $own->execute([$id]);
                    $owner = $own->fetchColumn();
                    if ($owner === false || $owner === null || (int)$owner !== $currentUserId) { throw new RuntimeException('Bạn không có quyền sửa câu này.'); }
                }
                $setSql = [];
                $params = [];

                foreach ($fieldValues as $field => $value) {
                    $setSql[] = "`{$field}` = ?";
                    $params[] = $value;
                }

                $params[] = $id;

                $update = $pdo->prepare(
                    'UPDATE sentences SET '
                    . implode(', ', $setSql)
                    . ' WHERE id = ?'
                );
                $update->execute($params);

                $success = 'Sentence updated.';
            } else {
                if ($ownerColumn !== null) { $fieldValues[$ownerColumn] = $isAdmin ? null : $currentUserId; }
                $fields = array_keys($fieldValues);
                $params = array_values($fieldValues);

                $insert = $pdo->prepare(
                    'INSERT INTO sentences ('
                    . implode(', ', array_map(
                        static fn(string $field): string => "`{$field}`",
                        $fields
                    ))
                    . ') VALUES ('
                    . implode(', ', array_fill(0, count($fields), '?'))
                    . ')'
                );
                $insert->execute($params);

                $success = 'Sentence added.';
            }
        }

        if ($action === 'duplicate') {
            $id = max(0, (int)($_POST['id'] ?? 0));

            if ($id <= 0) {
                throw new RuntimeException('Invalid sentence.');
            }

            $copyStmt = $pdo->prepare(
                "SELECT * FROM sentences WHERE id = ? LIMIT 1"
            );
            $copyStmt->execute([$id]);
            $row = $copyStmt->fetch(PDO::FETCH_ASSOC);

            if (!$row) {
                throw new RuntimeException('Sentence not found.');
            }

            unset($row['id']);

            $baseText = slv2Clean((string)($row[$textColumn] ?? ''));
            $copyText = $baseText . ' (Copy)';
            $counter = 2;

            while (true) {
                $exists = $pdo->prepare(
                    "SELECT id
                     FROM sentences
                     WHERE LOWER(TRIM(`{$textColumn}`)) = LOWER(TRIM(?))
                     LIMIT 1"
                );
                $exists->execute([$copyText]);

                if (!$exists->fetchColumn()) {
                    break;
                }

                $copyText = $baseText . ' (Copy ' . $counter . ')';
                $counter++;
            }

            $row[$textColumn] = $copyText;
            if ($ownerColumn !== null) { $row[$ownerColumn] = $isAdmin ? null : $currentUserId; }

            $fields = array_keys($row);
            $insert = $pdo->prepare(
                'INSERT INTO sentences ('
                . implode(', ', array_map(
                    static fn(string $field): string => "`{$field}`",
                    $fields
                ))
                . ') VALUES ('
                . implode(', ', array_fill(0, count($fields), '?'))
                . ')'
            );
            $insert->execute(array_values($row));

            $success = 'Sentence duplicated.';
        }

        if ($action === 'delete') {
            $id = max(0, (int)($_POST['id'] ?? 0));

            if ($id <= 0) {
                throw new RuntimeException('Invalid sentence.');
            }

            if (!$isAdmin && $ownerColumn !== null) {
                $own = $pdo->prepare('SELECT created_by_teacher_id FROM sentences WHERE id = ? LIMIT 1');
                $own->execute([$id]);
                $owner = $own->fetchColumn();
                if ($owner === false || $owner === null || (int)$owner !== $currentUserId) { throw new RuntimeException('Bạn không có quyền xóa câu này.'); }
            }
            $delete = $pdo->prepare(
                'DELETE FROM sentences WHERE id = ?'
            );
            $delete->execute([$id]);

            $success = 'Sentence deleted.';
        }
    } catch (Throwable $exception) {
        $error = $exception->getMessage();
    }
}

$search = slv2Clean((string)($_GET['q'] ?? ''));
$statusFilter = trim((string)($_GET['status'] ?? ''));
$bookFilter = max(0, (int)($_GET['book_id'] ?? 0));
$levelFilter = max(0, (int)($_GET['level_id'] ?? 0));
$topicFilter = max(0, (int)($_GET['topic_id'] ?? 0));

$where = [];
$params = [];

if ($search !== '') {
    $searchParts = ["s.`{$textColumn}` LIKE ?"];
    $params[] = '%' . $search . '%';

    if ($meaningColumn !== null) {
        $searchParts[] = "s.`{$meaningColumn}` LIKE ?";
        $params[] = '%' . $search . '%';
    }

    if ($tagsColumn !== null) {
        $searchParts[] = "s.`{$tagsColumn}` LIKE ?";
        $params[] = '%' . $search . '%';
    }

    $where[] = '(' . implode(' OR ', $searchParts) . ')';
}

if (
    $statusColumn !== null
    && in_array($statusFilter, ['active', 'inactive'], true)
) {
    $where[] = "s.`{$statusColumn}` = ?";
    $params[] = $statusFilter;
}

if ($bookColumn !== null && $bookFilter > 0) {
    $where[] = "s.`{$bookColumn}` = ?";
    $params[] = $bookFilter;
}

if ($levelColumn !== null && $levelFilter > 0) {
    $where[] = "s.`{$levelColumn}` = ?";
    $params[] = $levelFilter;
}

if ($topicColumn !== null && $topicFilter > 0) {
    $where[] = "s.`{$topicColumn}` = ?";
    $params[] = $topicFilter;
}

$meaningSelect = $meaningColumn !== null
    ? "s.`{$meaningColumn}` AS vietnamese_meaning"
    : "'' AS vietnamese_meaning";

$ipaSelect = $ipaColumn !== null
    ? "s.`{$ipaColumn}` AS ipa"
    : "'' AS ipa";

$imageSelect = $imageColumn !== null
    ? "s.`{$imageColumn}` AS image_path"
    : "'' AS image_path";

$audioSelect = $audioColumn !== null
    ? "s.`{$audioColumn}` AS audio_path"
    : "'' AS audio_path";

$tagsSelect = $tagsColumn !== null
    ? "s.`{$tagsColumn}` AS tags"
    : "'' AS tags";

$statusSelect = $statusColumn !== null
    ? "s.`{$statusColumn}` AS status"
    : "'active' AS status";

$bookIdSelect = $bookColumn !== null
    ? "s.`{$bookColumn}` AS book_id"
    : "NULL AS book_id";

$levelIdSelect = $levelColumn !== null
    ? "s.`{$levelColumn}` AS level_id"
    : "NULL AS level_id";

$topicIdSelect = $topicColumn !== null
    ? "s.`{$topicColumn}` AS topic_id"
    : "NULL AS topic_id";

$bookJoin = '';
$bookNameSelect = "'' AS book_name";

if ($bookColumn !== null && $books !== []) {
    $bookColumns = slv2Columns($pdo, 'books');
    $bookNameColumn = slv2FirstColumn($bookColumns, ['name', 'title']);

    if ($bookNameColumn !== null) {
        $bookJoin = " LEFT JOIN books b ON b.id = s.`{$bookColumn}`";
        $bookNameSelect = "b.`{$bookNameColumn}` AS book_name";
    }
}

$levelJoin = '';
$levelNameSelect = "'' AS level_name";

if ($levelColumn !== null && $levels !== []) {
    $levelColumns = slv2Columns($pdo, 'levels');
    $levelNameColumn = slv2FirstColumn($levelColumns, ['name', 'title']);

    if ($levelNameColumn !== null) {
        $levelJoin = " LEFT JOIN levels lv ON lv.id = s.`{$levelColumn}`";
        $levelNameSelect = "lv.`{$levelNameColumn}` AS level_name";
    }
}

$topicJoin = '';
$topicNameSelect = "'' AS topic_name";

if (
    $topicColumn !== null
    && $topicTable !== ''
    && $topicNameColumn !== ''
) {
    $topicJoin =
        " LEFT JOIN `{$topicTable}` tp
          ON tp.id = s.`{$topicColumn}`";

    $topicNameSelect =
        "tp.`{$topicNameColumn}` AS topic_name";
}

$ownerSelect = $ownerColumn !== null ? 's.`' . $ownerColumn . '` AS created_by_teacher_id' : 'NULL AS created_by_teacher_id';

$sql =
    "SELECT
        s.id,
        {$ownerSelect},
        s.`{$textColumn}` AS sentence_text,
        {$meaningSelect},
        {$ipaSelect},
        {$imageSelect},
        {$audioSelect},
        {$tagsSelect},
        {$statusSelect},
        {$bookIdSelect},
        {$levelIdSelect},
        {$topicIdSelect},
        {$bookNameSelect},
        {$levelNameSelect},
        {$topicNameSelect}
     FROM sentences s
     {$bookJoin}
     {$levelJoin}
     {$topicJoin}";

if ($where !== []) {
    $sql .= ' WHERE ' . implode(' AND ', $where);
}

$sql .= ' ORDER BY s.id DESC';

$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$sentences = $stmt->fetchAll(PDO::FETCH_ASSOC);

/*
 * Sentence image resolution is centralized in:
 * includes/sentence_image_resolver.php
 *
 * This page does not search Word Library by itself anymore.
 */
foreach ($sentences as &$sentence) {
    $resolvedImage = esResolveSentenceImage(
        $pdo,
        (string)$sentence['sentence_text'],
        (string)($sentence['image_path'] ?? '')
    );

    $sentence['resolved_image_path'] = (string)($resolvedImage['path'] ?? '');
    $sentence['resolved_image_url'] = (string)($resolvedImage['url'] ?? '');
    $sentence['image_source'] = (string)($resolvedImage['source'] ?? 'none');
    $sentence['matched_word'] = (string)($resolvedImage['matched_word'] ?? '');
}
unset($sentence);

ob_start();
?>

<style>
.slv2-page{display:grid;gap:16px}
.slv2-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.slv2-title{margin:3px 0 0;font-size:28px;color:#0f172a}
.slv2-kicker{color:#7c3aed;font-size:12px;font-weight:850;letter-spacing:.08em;text-transform:uppercase}
.slv2-subtitle{margin:6px 0 0;color:#64748b;font-size:14px}
.slv2-actions{display:flex;gap:8px;flex-wrap:wrap}
.slv2-message{padding:12px 14px;border-radius:12px;font-weight:750}
.slv2-error{border:1px solid #fecaca;background:#fef2f2;color:#991b1b}
.slv2-success{border:1px solid #bbf7d0;background:#ecfdf3;color:#166534}
.slv2-toolbar{display:grid;grid-template-columns:minmax(220px,1fr) repeat(4,minmax(130px,170px)) auto;gap:9px;padding:14px;border:1px solid #e5e7eb;border-radius:16px;background:#fff}
.slv2-input,.slv2-select,.slv2-textarea{width:100%;border:1px solid #dbe2ea;border-radius:10px;background:#fff;color:#0f172a;font:inherit}
.slv2-input,.slv2-select{min-height:42px;padding:8px 11px}
.slv2-textarea{min-height:88px;padding:10px 11px;resize:vertical}
.slv2-bulk{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid #dbeafe;border-radius:14px;background:#eff6ff}
.slv2-bulk-left{display:flex;align-items:center;gap:10px;color:#1d4ed8;font-size:13px;font-weight:750}
.slv2-card{border:1px solid #e5e7eb;border-radius:16px;background:#fff;overflow:hidden}
.slv2-table-wrap{overflow:auto}
.slv2-table{width:100%;border-collapse:collapse}
.slv2-table th{padding:11px 12px;background:#f8fafc;color:#64748b;font-size:11px;text-align:left;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}
.slv2-table td{padding:12px;border-top:1px solid #edf0f3;vertical-align:middle;color:#334155}
.slv2-check{width:18px;height:18px}
.slv2-media{width:56px;height:56px;display:grid;place-items:center;border-radius:12px;background:#f8fafc;overflow:hidden;font-size:28px}
.slv2-media img{width:100%;height:100%;object-fit:cover}
.slv2-sentence{min-width:260px;color:#0f172a;font-weight:800;line-height:1.4}
.slv2-meaning{margin-top:4px;color:#64748b;font-size:12px;line-height:1.4}
.slv2-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:6px}
.slv2-tag{display:inline-flex;padding:3px 7px;border-radius:999px;background:#f1f5f9;color:#475569;font-size:10px;font-weight:750}
.slv2-badge{display:inline-flex;padding:5px 9px;border-radius:999px;font-size:11px;font-weight:800}
.slv2-active{background:#dcfce7;color:#166534}
.slv2-inactive{background:#f1f5f9;color:#475569}
.slv2-actions-row{display:flex;gap:6px;flex-wrap:wrap;min-width:290px}.slv2-audio-cell{min-width:112px}.slv2-audio-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:34px;padding:6px 10px;border:1px solid #dbe2ea;border-radius:9px;background:#fff;color:#2563eb;font:inherit;font-size:12px;font-weight:800;cursor:pointer}.slv2-audio-btn:hover{background:#eff6ff;border-color:#93c5fd}.slv2-audio-source{display:block;margin-top:4px;color:#94a3b8;font-size:10px;font-weight:700}
.slv2-empty{padding:50px 20px;text-align:center;color:#64748b}
.slv2-modal{position:fixed;z-index:9999;inset:0;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(15,23,42,.45);backdrop-filter:blur(4px)}
.slv2-modal.show{display:flex}
.slv2-modal-card{width:min(760px,100%);max-height:90vh;overflow:auto;border-radius:20px;background:#fff;box-shadow:0 24px 70px rgba(15,23,42,.24)}
.slv2-modal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:17px 19px;border-bottom:1px solid #e5e7eb}
.slv2-modal-head h3{margin:0;color:#0f172a}
.slv2-modal-close{width:38px;height:38px;border:0;border-radius:50%;background:#f1f5f9;font-size:24px;cursor:pointer}
.slv2-modal-body{padding:18px}
.slv2-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.slv2-field{display:grid;gap:7px}
.slv2-field-full{grid-column:1/-1}
.slv2-field span{color:#334155;font-size:13px;font-weight:750}
.slv2-modal-footer{display:flex;justify-content:flex-end;gap:9px;padding:15px 19px;border-top:1px solid #e5e7eb}
.slv2-image-upload{display:grid;grid-template-columns:120px minmax(0,1fr);gap:14px;align-items:center;padding:12px;border:1px solid #e5e7eb;border-radius:12px;background:#f8fafc}
.slv2-image-preview{width:120px;height:96px;display:grid;place-items:center;overflow:hidden;border:1px dashed #cbd5e1;border-radius:10px;background:#fff;color:#94a3b8;font-size:12px;text-align:center}
.slv2-image-preview img{width:100%;height:100%;object-fit:contain}
.slv2-image-controls{display:grid;gap:8px}
.slv2-file-input{width:100%;font:inherit;font-size:13px}
.slv2-image-note{color:#64748b;font-size:12px;line-height:1.45}
.slv2-remove-image{display:none;align-items:center;gap:7px;color:#475569;font-size:12px;font-weight:700}
.slv2-remove-image.show{display:flex}

.slv2-preview-card{width:min(440px,100%);padding:0;overflow:hidden}
.slv2-preview-body{display:grid;gap:9px;padding:18px 20px 20px;text-align:center}
.slv2-preview-media{width:100%;min-height:170px;display:grid;place-items:center;border-radius:16px;background:#f8fafc;overflow:hidden}
.slv2-preview-media img{max-width:100%;max-height:230px;object-fit:contain}
.slv2-preview-fallback{font-size:76px}
.slv2-preview-sentence{margin:1px 0 0;color:#0f172a;font-size:25px;line-height:1.35}
.slv2-preview-ipa{margin:-2px 0 0;color:#64748b;font-size:14px;font-style:italic}
.slv2-preview-meaning{margin:-1px 0 2px;color:#475569;font-size:14px;line-height:1.45}
.slv2-preview-listen{width:min(210px,100%);margin:4px auto 0}
@media(max-width:1120px){
  .slv2-toolbar{grid-template-columns:1fr 1fr 1fr}
}
@media(max-width:760px){
  .slv2-head{flex-direction:column}
  .slv2-toolbar{grid-template-columns:1fr}
  .slv2-bulk{align-items:stretch;flex-direction:column}
  .slv2-form-grid{grid-template-columns:1fr}
  .slv2-field-full{grid-column:auto}
}
</style>

<div class="slv2-page">
    <div class="slv2-head">
        <div>
            <span class="slv2-kicker">Sentence Library</span>
            <h2 class="slv2-title">Sentences</h2>
            <p class="slv2-subtitle">Manage reusable sentences.</p>
        </div>

        <div class="slv2-actions">
            <a class="button button-secondary" href="import.php">
                Import
            </a>
            <a class="button button-secondary" href="../sentence-sets/index.php">
                Sentence Sets
            </a>
            <button class="button button-primary" type="button" id="openAddSentence">
                + Add Sentence
            </button>
        </div>
    </div>

    <?php if ($error !== ''): ?>
        <div class="slv2-message slv2-error">
            <?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?>
        </div>
    <?php endif; ?>

    <?php if ($success !== ''): ?>
        <div class="slv2-message slv2-success">
            <?= htmlspecialchars($success, ENT_QUOTES, 'UTF-8') ?>
        </div>
    <?php endif; ?>

    <form method="get" class="slv2-toolbar" id="sentenceFilterForm">
        <input
            class="slv2-input"
            type="search"
            name="q"
            placeholder="Search sentence, meaning or tags..."
            value="<?= htmlspecialchars($search, ENT_QUOTES, 'UTF-8') ?>"
        >

        <select class="slv2-select" name="book_id" id="filterBook">
            <option value="0">All books</option>
            <?php foreach ($books as $book): ?>
                <option
                    value="<?= (int)$book['id'] ?>"
                    <?= $bookFilter === (int)$book['id'] ? 'selected' : '' ?>
                >
                    <?= htmlspecialchars((string)$book['name'], ENT_QUOTES, 'UTF-8') ?>
                </option>
            <?php endforeach; ?>
        </select>

        <select class="slv2-select" name="level_id" id="filterLevel">
            <option value="0">All levels</option>
            <?php foreach ($levels as $level): ?>
                <option
                    value="<?= (int)$level['id'] ?>"
                    data-book-id="<?= (int)($level['book_id'] ?? 0) ?>"
                    <?= $levelFilter === (int)$level['id'] ? 'selected' : '' ?>
                >
                    <?= htmlspecialchars((string)$level['name'], ENT_QUOTES, 'UTF-8') ?>
                </option>
            <?php endforeach; ?>
        </select>

        <select class="slv2-select" name="topic_id" id="filterTopic">
            <option value="0">All topics</option>
            <?php foreach ($topics as $topic): ?>
                <option
                    value="<?= (int)$topic['id'] ?>"
                    <?= $topicFilter === (int)$topic['id'] ? 'selected' : '' ?>
                >
                    <?= htmlspecialchars((string)$topic['name'], ENT_QUOTES, 'UTF-8') ?>
                </option>
            <?php endforeach; ?>
        </select>

        <select class="slv2-select" name="status" id="filterStatus">
            <option value="">All status</option>
            <option value="active" <?= $statusFilter === 'active' ? 'selected' : '' ?>>
                Active
            </option>
            <option value="inactive" <?= $statusFilter === 'inactive' ? 'selected' : '' ?>>
                Inactive
            </option>
        </select>

        <button class="button button-secondary" type="submit">Filter</button>
    </form>

    <div class="slv2-bulk">
        <div class="slv2-bulk-left">
            <input class="slv2-check" type="checkbox" id="selectAll">
            <span id="selectedCount">0 selected</span>
        </div>

        <button
            class="button button-primary"
            type="button"
            id="createSetButton"
            disabled
        >
            Create Sentence Set
        </button>
    </div>

    <section class="slv2-card">
        <?php if ($sentences === []): ?>
            <div class="slv2-empty">No sentences found.</div>
        <?php else: ?>
            <div class="slv2-table-wrap">
                <table class="slv2-table">
                    <thead>
                        <tr>
                            <th></th>
                            <th>Media</th>
                            <th>Sentence</th>
                            <th>Book / Level</th>
                            <th>Topic</th>
                            <th>Audio</th>
                            <th>Status</th>
                            <th>Actions</th>
                        </tr>
                    </thead>

                    <tbody>
                    <?php foreach ($sentences as $sentence): ?>
                        <?php
                        $tags = array_values(array_filter(array_map(
                            'trim',
                            explode(',', (string)$sentence['tags'])
                        )));
                        ?>
                        <tr>
                            <td>
                                <input
                                    class="slv2-check sentence-check"
                                    type="checkbox"
                                    value="<?= (int)$sentence['id'] ?>"
                                >
                            </td>

                            <td>
                                <div class="slv2-media">
                                    <?php if ((string)$sentence['resolved_image_url'] !== ''): ?>
                                        <img
                                            src="<?= htmlspecialchars(
                                                (string)$sentence['resolved_image_url'],
                                                ENT_QUOTES,
                                                'UTF-8'
                                            ) ?>"
                                            alt=""
                                        >
                                    <?php else: ?>
                                        💬
                                    <?php endif; ?>
                                </div>
                            </td>

                            <td>
                                <div class="slv2-sentence">
                                    <?= htmlspecialchars(
                                        (string)$sentence['sentence_text'],
                                        ENT_QUOTES,
                                        'UTF-8'
                                    ) ?>
                                </div>

                                <?php if ((string)$sentence['vietnamese_meaning'] !== ''): ?>
                                    <div class="slv2-meaning">
                                        <?= htmlspecialchars(
                                            (string)$sentence['vietnamese_meaning'],
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>
                                    </div>
                                <?php endif; ?>

                                <?php if ($tags !== []): ?>
                                    <div class="slv2-tags">
                                        <?php foreach ($tags as $tag): ?>
                                            <span class="slv2-tag">
                                                <?= htmlspecialchars($tag, ENT_QUOTES, 'UTF-8') ?>
                                            </span>
                                        <?php endforeach; ?>
                                    </div>
                                <?php endif; ?>
                            </td>

                            <td>
                                <div><?= htmlspecialchars(
                                    (string)($sentence['book_name'] ?: '—'),
                                    ENT_QUOTES,
                                    'UTF-8'
                                ) ?></div>
                                <div class="slv2-meaning"><?= htmlspecialchars(
                                    (string)($sentence['level_name'] ?: '—'),
                                    ENT_QUOTES,
                                    'UTF-8'
                                ) ?></div>
                            </td>

                            <td>
                                <?= htmlspecialchars(
                                    (string)($sentence['topic_name'] ?: '—'),
                                    ENT_QUOTES,
                                    'UTF-8'
                                ) ?>
                            </td>

                            <td class="slv2-audio-cell">
                                <button
                                    class="slv2-audio-btn sentence-audio-button"
                                    type="button"
                                    data-sentence="<?= htmlspecialchars(
                                        (string)$sentence['sentence_text'],
                                        ENT_QUOTES,
                                        'UTF-8'
                                    ) ?>"
                                    data-audio="<?= htmlspecialchars(
                                        slv2AssetUrl((string)$sentence['audio_path']),
                                        ENT_QUOTES,
                                        'UTF-8'
                                    ) ?>"
                                >
                                    🔊 Listen
                                </button>
                                <span class="slv2-audio-source">
                                    <?= (string)$sentence['audio_path'] !== ''
                                        ? 'TTS file'
                                        : 'Browser voice' ?>
                                </span>
                            </td>

                            <td>
                                <span class="slv2-badge <?= $sentence['status'] === 'inactive'
                                    ? 'slv2-inactive'
                                    : 'slv2-active' ?>">
                                    <?= $sentence['status'] === 'inactive'
                                        ? 'Inactive'
                                        : 'Active' ?>
                                </span>
                            </td>

                            <td>
                                <div class="slv2-actions-row">
                                    <button
                                        class="button button-sm button-secondary preview-button"
                                        type="button"
                                        data-sentence="<?= htmlspecialchars(
                                            (string)$sentence['sentence_text'],
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                        data-meaning="<?= htmlspecialchars(
                                            (string)$sentence['vietnamese_meaning'],
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                        data-ipa="<?= htmlspecialchars(
                                            (string)$sentence['ipa'],
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                        data-image="<?= htmlspecialchars(
                                            (string)$sentence['resolved_image_url'],
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                        data-audio="<?= htmlspecialchars(
                                            slv2AssetUrl((string)$sentence['audio_path']),
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                    >
                                        ▶ Preview
                                    </button>

                                    <?php $canManageSentence = $isAdmin || ((int)($sentence['created_by_teacher_id'] ?? 0) > 0 && (int)$sentence['created_by_teacher_id'] === $currentUserId); ?>
                                    <?php if ($canManageSentence): ?>
                                    <button
                                        class="button button-sm button-secondary edit-button"
                                        type="button"
                                        data-row="<?= htmlspecialchars(
                                            json_encode($sentence, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
                                            ENT_QUOTES,
                                            'UTF-8'
                                        ) ?>"
                                    >
                                        Edit
                                    </button>
                                    <?php endif; ?>

                                    <form method="post">
                                        <input type="hidden" name="action" value="duplicate">
                                        <input type="hidden" name="id" value="<?= (int)$sentence['id'] ?>">
                                        <button class="button button-sm button-secondary" type="submit">
                                            Duplicate
                                        </button>
                                    </form>

                                    <?php if ($canManageSentence): ?>
                                    <form
                                        method="post"
                                        onsubmit="return confirm('Delete this sentence?');"
                                    >
                                        <input type="hidden" name="action" value="delete">
                                        <input type="hidden" name="id" value="<?= (int)$sentence['id'] ?>">
                                        <button
                                            class="button button-sm button-secondary"
                                            type="submit"
                                            style="color:var(--danger);"
                                        >
                                            Delete
                                        </button>
                                    </form>
                                    <?php endif; ?>
                                </div>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </section>
</div>

<div class="slv2-modal" id="previewModal" aria-hidden="true">
    <div class="slv2-modal-card slv2-preview-card">
        <div class="slv2-modal-head">
            <h3>Sentence Preview</h3>
            <button
                class="slv2-modal-close"
                type="button"
                id="closePreviewModal"
                aria-label="Close"
            >×</button>
        </div>

        <div class="slv2-preview-body">
            <div class="slv2-preview-media" id="previewMedia">
                <img id="previewImage" alt="" hidden>
                <span class="slv2-preview-fallback" id="previewFallback">💬</span>
            </div>

            <h4 class="slv2-preview-sentence" id="previewSentence"></h4>
            <p class="slv2-preview-ipa" id="previewIpa" hidden></p>
            <p class="slv2-preview-meaning" id="previewMeaning" hidden></p>

            <button
                class="button button-primary slv2-preview-listen"
                type="button"
                id="previewListenButton"
            >
                🔊 Listen
            </button>
        </div>

    </div>
</div>

<div class="slv2-modal" id="sentenceModal" aria-hidden="true">
    <div class="slv2-modal-card">
        <div class="slv2-modal-head">
            <h3 id="sentenceModalTitle">Add Sentence</h3>
            <button class="slv2-modal-close" type="button" id="closeSentenceModal">×</button>
        </div>

        <form method="post" id="sentenceForm" enctype="multipart/form-data">
            <input type="hidden" name="action" value="save">
            <input type="hidden" name="id" id="sentenceId" value="0">

            <div class="slv2-modal-body">
                <div class="slv2-form-grid">
                    <label class="slv2-field slv2-field-full">
                        <span>English sentence *</span>
                        <textarea
                            class="slv2-textarea"
                            name="sentence_text"
                            id="sentenceText"
                            required
                        ></textarea>
                    </label>

                    <label class="slv2-field">
                        <span>Vietnamese meaning</span>
                        <input class="slv2-input" type="text" name="vietnamese_meaning" id="sentenceMeaning">
                    </label>

                    <label class="slv2-field">
                        <span>IPA</span>
                        <input class="slv2-input" type="text" name="ipa" id="sentenceIpa">
                    </label>

                    <label class="slv2-field">
                        <span>Book</span>
                        <select class="slv2-select" name="book_id" id="sentenceBook">
                            <option value="0">No book</option>
                            <?php foreach ($books as $book): ?>
                                <option value="<?= (int)$book['id'] ?>">
                                    <?= htmlspecialchars((string)$book['name'], ENT_QUOTES, 'UTF-8') ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </label>

                    <label class="slv2-field">
                        <span>Level</span>
                        <select class="slv2-select" name="level_id" id="sentenceLevel">
                            <option value="0">No level</option>
                            <?php foreach ($levels as $level): ?>
                                <option
                                    value="<?= (int)$level['id'] ?>"
                                    data-book-id="<?= (int)($level['book_id'] ?? 0) ?>"
                                >
                                    <?= htmlspecialchars((string)$level['name'], ENT_QUOTES, 'UTF-8') ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </label>

                    <label class="slv2-field">
                        <span>Topic</span>
                        <select class="slv2-select" name="topic_id" id="sentenceTopic">
                            <option value="0">No topic</option>
                            <?php foreach ($topics as $topic): ?>
                                <option value="<?= (int)$topic['id'] ?>">
                                    <?= htmlspecialchars((string)$topic['name'], ENT_QUOTES, 'UTF-8') ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                    </label>

                    <label class="slv2-field">
                        <span>Tags</span>
                        <input
                            class="slv2-input"
                            type="text"
                            name="tags"
                            id="sentenceTags"
                            placeholder="question, greeting, daily"
                        >
                    </label>

                    <div class="slv2-field slv2-field-full">
                        <span>Sentence image (optional)</span>
                        <div class="slv2-image-upload">
                            <div class="slv2-image-preview" id="sentenceImagePreview">
                                <img id="sentenceImagePreviewImg" alt="" hidden>
                                <span id="sentenceImagePreviewText">Chưa có ảnh riêng</span>
                            </div>

                            <div class="slv2-image-controls">
                                <input
                                    class="slv2-file-input"
                                    type="file"
                                    name="sentence_image"
                                    id="sentenceImage"
                                    accept="image/jpeg,image/png,image/webp,image/gif"
                                >

                                <label class="slv2-remove-image" id="removeSentenceImageWrap">
                                    <input
                                        type="checkbox"
                                        name="remove_sentence_image"
                                        id="removeSentenceImage"
                                        value="1"
                                    >
                                    Xóa ảnh riêng hiện tại
                                </label>

                                <div class="slv2-image-note">
                                    Chỉ thêm ảnh riêng khi ảnh từ Word Library chưa mô tả đúng câu.
                                    Ảnh riêng sẽ được lưu vào Sentence Library và được resolver ưu tiên sử dụng.
                                </div>
                            </div>
                        </div>
                    </div>

                    <label class="slv2-field">
                        <span>Status</span>
                        <select class="slv2-select" name="status" id="sentenceStatus">
                            <option value="active">Active</option>
                            <option value="inactive">Inactive</option>
                        </select>
                    </label>
                </div>
            </div>

            <div class="slv2-modal-footer">
                <button class="button button-secondary" type="button" id="cancelSentenceModal">
                    Cancel
                </button>
                <button class="button button-primary" type="submit">
                    Save Sentence
                </button>
            </div>
        </form>
    </div>
</div>

<script>
(function () {
    'use strict';

    const modal = document.getElementById('sentenceModal');
    const modalTitle = document.getElementById('sentenceModalTitle');
    const openButton = document.getElementById('openAddSentence');
    const closeButton = document.getElementById('closeSentenceModal');
    const cancelButton = document.getElementById('cancelSentenceModal');

    const fields = {
        id: document.getElementById('sentenceId'),
        text: document.getElementById('sentenceText'),
        meaning: document.getElementById('sentenceMeaning'),
        ipa: document.getElementById('sentenceIpa'),
        book: document.getElementById('sentenceBook'),
        level: document.getElementById('sentenceLevel'),
        topic: document.getElementById('sentenceTopic'),
        tags: document.getElementById('sentenceTags'),
        status: document.getElementById('sentenceStatus'),
        image: document.getElementById('sentenceImage'),
        imagePreview: document.getElementById('sentenceImagePreviewImg'),
        imagePreviewText: document.getElementById('sentenceImagePreviewText'),
        removeImage: document.getElementById('removeSentenceImage'),
        removeImageWrap: document.getElementById('removeSentenceImageWrap')
    };

    function showSentenceOwnImage(url = '') {
        const cleanUrl = String(url || '').trim();

        if (cleanUrl) {
            fields.imagePreview.src = cleanUrl;
            fields.imagePreview.hidden = false;
            fields.imagePreviewText.hidden = true;
            fields.removeImageWrap.classList.add('show');
        } else {
            fields.imagePreview.removeAttribute('src');
            fields.imagePreview.hidden = true;
            fields.imagePreviewText.hidden = false;
            fields.removeImageWrap.classList.remove('show');
        }
    }

    function openModal(row = null) {
        modalTitle.textContent = row ? 'Edit Sentence' : 'Add Sentence';

        fields.id.value = row?.id || 0;
        fields.text.value = row?.sentence_text || '';
        fields.meaning.value = row?.vietnamese_meaning || '';
        fields.ipa.value = row?.ipa || '';
        fields.book.value = row?.book_id || 0;
        fields.level.value = row?.level_id || 0;
        fields.topic.value = row?.topic_id || 0;
        fields.tags.value = row?.tags || '';

        if (fields.image) {
            fields.image.value = '';
        }

        if (fields.removeImage) {
            fields.removeImage.checked = false;
        }

        const ownImagePath = String(row?.image_path || '').trim();
        const ownImageUrl = ownImagePath === ''
            ? ''
            : (
                /^(https?:|data:|\/)/i.test(ownImagePath)
                    ? ownImagePath
                    : '/EnglishSpeak/' + ownImagePath.replace(/^\.\//, '')
            );

        showSentenceOwnImage(ownImageUrl);

        fields.status.value = row?.status || 'active';

        modal.classList.add('show');
        modal.setAttribute('aria-hidden', 'false');

        window.setTimeout(() => {
            fields.text.focus();
        }, 50);
    }

    function closeModal() {
        modal.classList.remove('show');
        modal.setAttribute('aria-hidden', 'true');
    }

    openButton?.addEventListener('click', () => openModal());
    closeButton?.addEventListener('click', closeModal);
    cancelButton?.addEventListener('click', closeModal);

    modal?.addEventListener('click', event => {
        if (event.target === modal) {
            closeModal();
        }
    });

    fields.image?.addEventListener('change', () => {
        const file = fields.image.files?.[0];

        if (!file) {
            return;
        }

        if (fields.removeImage) {
            fields.removeImage.checked = false;
        }

        const reader = new FileReader();
        reader.addEventListener('load', () => {
            showSentenceOwnImage(String(reader.result || ''));
        });
        reader.readAsDataURL(file);
    });

    fields.removeImage?.addEventListener('change', () => {
        if (fields.removeImage.checked) {
            if (fields.image) {
                fields.image.value = '';
            }

            fields.imagePreview.removeAttribute('src');
            fields.imagePreview.hidden = true;
            fields.imagePreviewText.hidden = false;
            fields.imagePreviewText.textContent = 'Ảnh riêng sẽ được xóa khi lưu';
        } else {
            fields.imagePreviewText.textContent = 'Chưa có ảnh riêng';
        }
    });

    document.querySelectorAll('.edit-button').forEach(button => {
        button.addEventListener('click', () => {
            const row = JSON.parse(button.dataset.row || '{}');
            openModal(row);
        });
    });

    const previewModal = document.getElementById('previewModal');
    const previewSentence = document.getElementById('previewSentence');
    const previewMeaning = document.getElementById('previewMeaning');
    const previewIpa = document.getElementById('previewIpa');
    const previewImage = document.getElementById('previewImage');
    const previewFallback = document.getElementById('previewFallback');
    const previewListenButton = document.getElementById('previewListenButton');
    const closePreviewModal = document.getElementById('closePreviewModal');

    let previewAudioUrl = '';
    let previewSentenceText = '';

    function openPreview(button) {
        previewSentenceText = button.dataset.sentence || '';
        previewAudioUrl = button.dataset.audio || '';

        const meaning = button.dataset.meaning || '';
        const ipa = button.dataset.ipa || '';
        const imageUrl = button.dataset.image || '';

        previewSentence.textContent = previewSentenceText;

        previewMeaning.textContent = meaning;
        previewMeaning.hidden = meaning === '';

        previewIpa.textContent = ipa;
        previewIpa.hidden = ipa === '';

        if (imageUrl) {
            previewImage.src = imageUrl;
            previewImage.alt = previewSentenceText;
            previewImage.hidden = false;
            previewFallback.hidden = true;
        } else {
            previewImage.hidden = true;
            previewImage.removeAttribute('src');
            previewFallback.hidden = false;
        }

        previewModal.classList.add('show');
        previewModal.setAttribute('aria-hidden', 'false');
    }

    function closePreview() {
        previewModal.classList.remove('show');
        previewModal.setAttribute('aria-hidden', 'true');

        if ('speechSynthesis' in window) {
            window.speechSynthesis.cancel();
        }
    }

    document.querySelectorAll('.sentence-audio-button').forEach(button => {
        button.addEventListener('click', () => {
            const sentence = button.dataset.sentence || '';
            const audioUrl = button.dataset.audio || '';

            playSentenceAudio(audioUrl, sentence);
        });
    });

    document.querySelectorAll('.preview-button').forEach(button => {
        button.addEventListener('click', () => {
            openPreview(button);
        });
    });

    previewListenButton?.addEventListener('click', () => {
        playSentenceAudio(previewAudioUrl, previewSentenceText);
    });

    closePreviewModal?.addEventListener('click', closePreview);

    previewImage?.addEventListener('error', () => {
        previewImage.hidden = true;
        previewImage.removeAttribute('src');
        previewFallback.hidden = false;
    });

    previewModal?.addEventListener('click', event => {
        if (event.target === previewModal) {
            closePreview();
        }
    });

    document.addEventListener('keydown', event => {
        if (event.key === 'Escape') {
            if (previewModal?.classList.contains('show')) {
                closePreview();
            }

            if (modal?.classList.contains('show')) {
                closeModal();
            }
        }
    });

    function playSentenceAudio(audioUrl, text) {
        if ('speechSynthesis' in window) {
            window.speechSynthesis.cancel();
        }

        if (audioUrl) {
            const audio = new Audio(audioUrl);
            audio.play().catch(() => speak(text));
            return;
        }

        speak(text);
    }

    function speak(text) {
        if (!('speechSynthesis' in window) || !text) {
            alert('Trình duyệt này chưa hỗ trợ đọc TTS.');
            return;
        }

        window.speechSynthesis.cancel();

        const utterance = new SpeechSynthesisUtterance(text);
        const voices = window.speechSynthesis.getVoices();

        const preferredVoice = voices.find(voice =>
            String(voice.lang || '').toLowerCase().startsWith('en-us')
        ) || voices.find(voice =>
            String(voice.lang || '').toLowerCase().startsWith('en')
        );

        if (preferredVoice) {
            utterance.voice = preferredVoice;
        }

        utterance.lang = 'en-US';
        utterance.rate = 0.72;
        utterance.pitch = 1;
        utterance.volume = 1;

        window.speechSynthesis.speak(utterance);
    }

    // Sentence Library filters: Book -> Level cascade + auto submit.
    const filterForm = document.getElementById('sentenceFilterForm');
    const filterBook = document.getElementById('filterBook');
    const filterLevel = document.getElementById('filterLevel');
    const filterTopic = document.getElementById('filterTopic');
    const filterStatus = document.getElementById('filterStatus');

    function syncFilterLevels(resetLevel = false) {
        if (!filterBook || !filterLevel) return;

        const bookId = String(filterBook.value || '0');
        let selectedStillValid = false;

        Array.from(filterLevel.options).forEach(option => {
            if (option.value === '0') {
                option.hidden = false;
                option.disabled = false;
                return;
            }

            const optionBookId = String(option.dataset.bookId || '0');
            const visible = bookId === '0' || optionBookId === bookId;
            option.hidden = !visible;
            option.disabled = !visible;

            if (visible && option.selected) selectedStillValid = true;
        });

        if (resetLevel || !selectedStillValid) {
            filterLevel.value = '0';
        }
    }

    syncFilterLevels(false);

    filterBook?.addEventListener('change', () => {
        syncFilterLevels(true);
        filterForm?.submit();
    });

    filterLevel?.addEventListener('change', () => filterForm?.submit());
    filterTopic?.addEventListener('change', () => filterForm?.submit());
    filterStatus?.addEventListener('change', () => filterForm?.submit());

    const selectAll = document.getElementById('selectAll');
    const checks = Array.from(
        document.querySelectorAll('.sentence-check')
    );
    const selectedCount = document.getElementById('selectedCount');
    const createSetButton = document.getElementById('createSetButton');

    function updateSelection() {
        const selected = checks.filter(check => check.checked);
        selectedCount.textContent = `${selected.length} selected`;
        createSetButton.disabled = selected.length === 0;

        if (selectAll) {
            selectAll.checked =
                checks.length > 0
                && selected.length === checks.length;

            selectAll.indeterminate =
                selected.length > 0
                && selected.length < checks.length;
        }
    }

    selectAll?.addEventListener('change', () => {
        checks.forEach(check => {
            check.checked = selectAll.checked;
        });

        updateSelection();
    });

    checks.forEach(check => {
        check.addEventListener('change', updateSelection);
    });

    createSetButton?.addEventListener('click', () => {
        const ids = checks
            .filter(check => check.checked)
            .map(check => check.value);

        if (ids.length === 0) {
            return;
        }

        window.location.href =
            '../sentence-sets/create.php?sentence_ids='
            + encodeURIComponent(ids.join(','));
    });

    updateSelection();
})();
</script>

<?php
$content = ob_get_clean();
require __DIR__ . '/../layouts/app.php';
