<?php
declare(strict_types=1);
require __DIR__ . '/../partials/auth.php';

$pageTitle = 'Word Library';
$pageSubtitle = 'Master vocabulary database shared across all lessons';
$activeTeacherNav = 'word-library';

require_once __DIR__ . '/../../config/database.php';
$pdo = getDbConnection();
$currentUserId = (int)($_SESSION['user_id'] ?? 0);
$currentUserRole = strtolower(trim((string)($_SESSION['user_role'] ?? $_SESSION['role'] ?? 'teacher')));
$isAdmin = ($currentUserRole === 'admin');

function wlCanManageWord(array $word, bool $isAdmin, int $currentUserId): bool {
    return $isAdmin || ((int)($word['created_by_teacher_id'] ?? 0) > 0 && (int)$word['created_by_teacher_id'] === $currentUserId);
}
function wlRequireWordOwner(PDO $pdo, int $wordId, bool $isAdmin, int $currentUserId): array {
    $st = $pdo->prepare('SELECT id, created_by_teacher_id FROM words WHERE id = ? LIMIT 1');
    $st->execute([$wordId]);
    $row = $st->fetch(PDO::FETCH_ASSOC);
    if (!$row || !wlCanManageWord($row, $isAdmin, $currentUserId)) {
        http_response_code(403);
        exit('You do not have permission to modify this word.');
    }
    return $row;
}

// ─── Messaging ─────────────────────────
$message = $_SESSION['wl_message'] ?? '';
$messageType = $_SESSION['wl_message_type'] ?? 'success';
unset($_SESSION['wl_message'], $_SESSION['wl_message_type']);

// ─── Actions (Create / Update / Archive / Delete Image/Audio) ──
$formError = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';

    if ($action === 'assign_topics') {
        $wordIds = array_values(array_unique(array_filter(array_map(
            'intval',
            (array)($_POST['word_ids'] ?? [])
        ))));
        $topicIds = array_values(array_unique(array_filter(array_map(
            'intval',
            (array)($_POST['assign_topic_ids'] ?? [])
        ))));
        $assignMode = ($_POST['assign_mode'] ?? 'add') === 'replace'
            ? 'replace'
            : 'add';

        if (empty($wordIds) || empty($topicIds)) {
            $_SESSION['wl_message'] = 'Please select at least one word and one Topic.';
            $_SESSION['wl_message_type'] = 'error';
            header('Location: index.php');
            exit;
        }

        try {
            $pdo->beginTransaction();

            $validWord = $pdo->prepare(
                "SELECT id, created_by_teacher_id FROM words WHERE id = ? AND status = 'active' LIMIT 1"
            );
            $validTopic = $pdo->prepare(
                "SELECT id FROM topics WHERE id = ? AND status = 'active' LIMIT 1"
            );
            $deleteTopics = $pdo->prepare(
                'DELETE FROM topic_words WHERE word_id = ?'
            );
            $linkExists = $pdo->prepare(
                'SELECT id FROM topic_words WHERE topic_id = ? AND word_id = ? LIMIT 1'
            );
            $insertLink = $pdo->prepare(
                'INSERT INTO topic_words (topic_id, word_id, sort_order) VALUES (?, ?, 1)'
            );

            $validTopicIds = [];
            foreach ($topicIds as $topicId) {
                $validTopic->execute([$topicId]);
                if ($validTopic->fetchColumn()) {
                    $validTopicIds[] = $topicId;
                }
            }

            if (empty($validTopicIds)) {
                throw new RuntimeException('No valid Topic selected.');
            }

            $updatedWords = 0;

            foreach ($wordIds as $wordId) {
                $validWord->execute([$wordId]);
                $validWordRow = $validWord->fetch(PDO::FETCH_ASSOC);
                if (!$validWordRow || !wlCanManageWord($validWordRow, $isAdmin, $currentUserId)) {
                    continue;
                }

                if ($assignMode === 'replace') {
                    $deleteTopics->execute([$wordId]);
                }

                foreach ($validTopicIds as $topicId) {
                    $linkExists->execute([$topicId, $wordId]);

                    if (!$linkExists->fetchColumn()) {
                        $insertLink->execute([$topicId, $wordId]);
                    }
                }

                $updatedWords++;
            }

            $pdo->commit();

            $_SESSION['wl_message'] = $updatedWords . ' words updated successfully.';
            $_SESSION['wl_message_type'] = 'success';
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }

            $_SESSION['wl_message'] = 'Could not assign Topics. Please try again.';
            $_SESSION['wl_message_type'] = 'error';
        }

        header('Location: index.php');
        exit;
    } elseif ($action === 'add_example') {
        $wordId = (int)($_POST['word_id'] ?? 0);
        $exampleEn = trim((string)($_POST['example_en'] ?? ''));
        $exampleVi = trim((string)($_POST['example_vi'] ?? ''));

        if ($wordId <= 0 || $exampleEn === '') {
            $_SESSION['wl_message'] = 'Please enter an example sentence.';
            $_SESSION['wl_message_type'] = 'error';
            header('Location: index.php');
            exit;
        }

        $wordStmt = $pdo->prepare("SELECT id FROM words WHERE id = ? AND status = 'active' LIMIT 1");
        $wordStmt->execute([$wordId]);
        if (!$wordStmt->fetchColumn()) {
            $_SESSION['wl_message'] = 'Word not found.';
            $_SESSION['wl_message_type'] = 'error';
            header('Location: index.php');
            exit;
        }

        // Any logged-in Teacher may contribute a new example to a shared Word.
        // This does NOT grant permission to edit the Word itself.
        $dupExample = $pdo->prepare(
            "SELECT id FROM word_examples WHERE word_id = ? AND LOWER(TRIM(example_en)) = LOWER(TRIM(?)) AND status = 'active' LIMIT 1"
        );
        $dupExample->execute([$wordId, $exampleEn]);
        if ($dupExample->fetchColumn()) {
            $_SESSION['wl_message'] = 'This example already exists for the selected Word.';
            $_SESSION['wl_message_type'] = 'error';
            header('Location: index.php');
            exit;
        }

        $sortStmt = $pdo->prepare('SELECT COALESCE(MAX(sort_order), 0) + 1 FROM word_examples WHERE word_id = ?');
        $sortStmt->execute([$wordId]);
        $nextSort = (int)$sortStmt->fetchColumn();

        try {
            $insertExample = $pdo->prepare(
                'INSERT INTO word_examples (word_id, example_en, example_vi, sort_order, status, created_by_teacher_id) VALUES (?, ?, ?, ?, ?, ?)'
            );
            $insertExample->execute([
                $wordId,
                $exampleEn,
                $exampleVi,
                $nextSort,
                'active',
                $isAdmin ? null : $currentUserId,
            ]);
            $_SESSION['wl_message'] = 'Example added successfully.';
            $_SESSION['wl_message_type'] = 'success';
        } catch (PDOException $e) {
            error_log('Word example add error: ' . $e->getMessage());
            $_SESSION['wl_message'] = 'Could not add Example. Please check the word_examples database update.';
            $_SESSION['wl_message_type'] = 'error';
        }

        header('Location: index.php');
        exit;
    } elseif ($action === 'save') {
        $id = (int)($_POST['id'] ?? 0);
        $word = trim($_POST['word'] ?? '');
        $phonetic = trim($_POST['phonetic'] ?? '');
        $partOfSpeech = trim($_POST['part_of_speech'] ?? '');
        $meaningVi = trim($_POST['meaning_vi'] ?? '');
        $exampleEns = (array)($_POST['example_en'] ?? []);
        $exampleVis = (array)($_POST['example_vi'] ?? []);
        $exampleRows = [];
        $exampleCount = max(count($exampleEns), count($exampleVis));
        for ($exampleIndex = 0; $exampleIndex < $exampleCount; $exampleIndex++) {
            $exampleEn = trim((string)($exampleEns[$exampleIndex] ?? ''));
            $exampleVi = trim((string)($exampleVis[$exampleIndex] ?? ''));
            if ($exampleEn === '' && $exampleVi === '') {
                continue;
            }
            // English sentence is the primary value; ignore translation-only rows.
            if ($exampleEn === '') {
                continue;
            }
            $exampleRows[] = [
                'example_en' => $exampleEn,
                'example_vi' => $exampleVi,
            ];
        }
        $status = $_POST['status'] ?? 'active';
        $notes = trim($_POST['notes'] ?? '');
        $cefrLevel = trim((string)($_POST['cefr_level'] ?? ''));

        $allowedCefrLevels = ['Pre-A1', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2'];
        if (!in_array($cefrLevel, $allowedCefrLevels, true)) {
            $cefrLevel = '';
        }

        $difficultyLevel = (int)($_POST['difficulty_level'] ?? 1);
        $topicIds = $_POST['topic_ids'] ?? [];

        if ($word === '') {
            $formError = 'Please enter a word.';
        } else {
            try {
                if ($id > 0) {
                    wlRequireWordOwner($pdo, $id, $isAdmin, $currentUserId);
                }
                // ── Duplicate check (case-insensitive, trimmed) ──
                $dupCheck = $pdo->prepare(
                    'SELECT id FROM words WHERE LOWER(TRIM(word)) = LOWER(TRIM(?))' . ($id > 0 ? ' AND id != ?' : '')
                );
                $dupParams = [$word];
                if ($id > 0) $dupParams[] = $id;
                $dupCheck->execute($dupParams);

                if ($dupCheck->fetch()) {
                    $formError = 'This word already exists.';
                } else {
                    $slug = strtolower(trim(preg_replace('/[^a-zA-Z0-9]+/', '-', $word), '-'));
                    if (empty($slug)) $slug = 'word-' . time();

                    // ── Upload image ──
                    $imagePath = '';
                    if (!empty($_FILES['image_file']['name']) && $_FILES['image_file']['error'] === UPLOAD_ERR_OK) {
                        $imagePath = uploadFile('image_file', 'images');
                    }
                    // Keep existing if no new upload
                    if (empty($imagePath) && $id > 0) {
                        $imagePath = $_POST['existing_image'] ?? '';
                    }

                    // ── Upload audio ──
                    $audioPath = '';
                    if (!empty($_FILES['audio_file']['name']) && $_FILES['audio_file']['error'] === UPLOAD_ERR_OK) {
                        $audioPath = uploadFile('audio_file', 'audio');
                    }
                    if (empty($audioPath) && $id > 0) {
                        $audioPath = $_POST['existing_audio'] ?? '';
                    }

                    if ($id > 0) {
                        // Update
                        $stmt = $pdo->prepare('
                            UPDATE words SET
                                word = ?, slug = ?, phonetic = ?, part_of_speech = ?,
                                meaning_vi = ?, image_path = ?, audio_us_path = ?,
                                difficulty_level = ?, cefr_level = ?,
                                status = ?, notes = ?, updated_at = NOW()
                            WHERE id = ?
                        ');
                        $stmt->execute([
                            $word, $slug, $phonetic, $partOfSpeech,
                            $meaningVi, $imagePath, $audioPath,
                            $difficultyLevel, $cefrLevel,
                            $status, $notes, $id
                        ]);

                        // Update examples: one Word can have many reusable example sentences.
                        $pdo->prepare('DELETE FROM word_examples WHERE word_id = ?')->execute([$id]);
                        if ($exampleRows !== []) {
                            $insertExample = $pdo->prepare(
                                'INSERT INTO word_examples (word_id, example_en, example_vi, sort_order, status) VALUES (?, ?, ?, ?, ?)'
                            );
                            foreach ($exampleRows as $exampleIndex => $exampleRow) {
                                $insertExample->execute([
                                    $id,
                                    $exampleRow['example_en'],
                                    $exampleRow['example_vi'],
                                    $exampleIndex + 1,
                                    $status,
                                ]);
                            }
                        }

                        // Sync topics
                        $pdo->prepare('DELETE FROM topic_words WHERE word_id = ?')->execute([$id]);
                        foreach ((array)$topicIds as $tid) {
                            $pdo->prepare('INSERT INTO topic_words (topic_id, word_id, sort_order) VALUES (?, ?, 1)')
                                ->execute([(int)$tid, $id]);
                        }

                        $_SESSION['wl_message'] = 'Word updated successfully.';
                    } else {
                        // Insert
                        $stmt = $pdo->prepare('
                            INSERT INTO words (
                                word, slug, phonetic, part_of_speech, meaning_vi,
                                image_path, audio_us_path, difficulty_level,
                                cefr_level, status, notes, created_by_teacher_id, created_at, updated_at
                            )
                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
                        ');
                        $stmt->execute([
                            $word, $slug, $phonetic, $partOfSpeech,
                            $meaningVi, $imagePath, $audioPath,
                            $difficultyLevel, $cefrLevel,
                            $status, $notes, ($isAdmin ? null : $currentUserId)
                        ]);
                        $newId = (int)$pdo->lastInsertId();

                        // Insert examples.
                        if ($exampleRows !== []) {
                            $insertExample = $pdo->prepare(
                                'INSERT INTO word_examples (word_id, example_en, example_vi, sort_order, status) VALUES (?, ?, ?, ?, ?)'
                            );
                            foreach ($exampleRows as $exampleIndex => $exampleRow) {
                                $insertExample->execute([
                                    $newId,
                                    $exampleRow['example_en'],
                                    $exampleRow['example_vi'],
                                    $exampleIndex + 1,
                                    $status,
                                ]);
                            }
                        }

                        // Insert topics
                        foreach ((array)$topicIds as $tid) {
                            $pdo->prepare('INSERT INTO topic_words (topic_id, word_id, sort_order) VALUES (?, ?, 1)')
                                ->execute([(int)$tid, $newId]);
                        }

                        $_SESSION['wl_message'] = 'Word created successfully.';
                    }
                    $_SESSION['wl_message_type'] = 'success';
                    header('Location: index.php?' . ($id > 0 ? '' : ''));
                    exit;
                }
            } catch (PDOException $e) {
                error_log('Word Library save error: ' . $e->getMessage());
                $formError = 'Database error occurred. Please try again.';
            }
        }
    } elseif ($action === 'archive' || $action === 'restore') {
        $id = (int)($_POST['id'] ?? 0);
        $newStatus = ($action === 'archive') ? 'inactive' : 'active';
        if ($id > 0) {
            wlRequireWordOwner($pdo, $id, $isAdmin, $currentUserId);
            $pdo->prepare('UPDATE words SET status = ?, updated_at = NOW() WHERE id = ?')->execute([$newStatus, $id]);
            $_SESSION['wl_message'] = ($action === 'archive') ? 'Word archived.' : 'Word restored.';
            $_SESSION['wl_message_type'] = 'success';
        }
        header('Location: index.php');
        exit;
    } elseif ($action === 'delete_image') {
        $id = (int)($_POST['id'] ?? 0);
        if ($id > 0) {
            wlRequireWordOwner($pdo, $id, $isAdmin, $currentUserId);
            $pdo->prepare("UPDATE words SET image_path = '', updated_at = NOW() WHERE id = ?")->execute([$id]);
            $_SESSION['wl_message'] = 'Image removed.';
            $_SESSION['wl_message_type'] = 'success';
        }
        header('Location: index.php?edit=' . $id);
        exit;
    } elseif ($action === 'delete_audio') {
        $id = (int)($_POST['id'] ?? 0);
        if ($id > 0) {
            wlRequireWordOwner($pdo, $id, $isAdmin, $currentUserId);
            $pdo->prepare("UPDATE words SET audio_us_path = '', updated_at = NOW() WHERE id = ?")->execute([$id]);
            $_SESSION['wl_message'] = 'Audio removed.';
            $_SESSION['wl_message_type'] = 'success';
        }
        header('Location: index.php?edit=' . $id);
        exit;
    }
}

// ─── Upload helper ─────────────────────
function uploadFile(string $field, string $subdir): string {
    $allowed = [
        'images' => ['jpg', 'jpeg', 'png', 'webp', 'gif', 'svg'],
        'audio'  => ['mp3', 'wav', 'ogg', 'm4a', 'aac'],
    ];
    $ext = strtolower(pathinfo($_FILES[$field]['name'], PATHINFO_EXTENSION));
    if (!in_array($ext, $allowed[$subdir] ?? [], true)) {
        throw new RuntimeException('File type not allowed.');
    }
    $uploadDir = __DIR__ . '/../../uploads/word-library/' . $subdir;
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0775, true);
    }
    $filename = uniqid('wl_', true) . '.' . $ext;
    $dest = $uploadDir . '/' . $filename;
    if (!move_uploaded_file($_FILES[$field]['tmp_name'], $dest)) {
        throw new RuntimeException('Could not save file.');
    }
    return 'uploads/word-library/' . $subdir . '/' . $filename;
}

// ─── URL params ────────────────────────
$search       = trim($_GET['search'] ?? '');
$filterStatus = $_GET['status'] ?? '';
$filterPos    = $_GET['part_of_speech'] ?? '';
$filterTopic  = (int)($_GET['topic'] ?? 0);
$filterCefr   = trim((string)($_GET['cefr_level'] ?? ''));
$filterQuality = trim((string)($_GET['quality'] ?? ''));
$sort         = $_GET['sort'] ?? 'newest';

$cefrLevels = ['Pre-A1', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2'];
if (!in_array($filterCefr, $cefrLevels, true)) {
    $filterCefr = '';
}

$qualityLevels = ['complete', 'missing', 'incomplete'];
if (!in_array($filterQuality, $qualityLevels, true)) {
    $filterQuality = '';
}

$page         = max(1, (int)($_GET['page'] ?? 1));
$perPage      = 20;
$editId       = (int)($_GET['edit'] ?? 0);

// Filter/sort/pagination links must never carry the edit modal state.
$cleanQuery = $_GET;
unset($cleanQuery['edit']);

// ─── Build query ───────────────────────
$where = [];
$params = [];

// Base: show all words (active + inactive) for library management
// But default to active only unless filter explicitly says "archived" or "all"
if ($filterStatus === 'inactive') {
    $where[] = "w.status = 'inactive'";
} elseif ($filterStatus === 'all') {
    // no status filter
} else {
    $where[] = "w.status = 'active'";
}

if ($search !== '') {
    $where[] = "(w.word LIKE ? OR w.meaning_vi LIKE ? OR w.phonetic LIKE ?)";
    $like = "%{$search}%";
    $params[] = $like;
    $params[] = $like;
    $params[] = $like;
}

if ($filterPos !== '') {
    $where[] = "w.part_of_speech = ?";
    $params[] = $filterPos;
}

if ($filterTopic > 0) {
    $where[] = "EXISTS (SELECT 1 FROM topic_words tw2 WHERE tw2.word_id = w.id AND tw2.topic_id = ?)";
    $params[] = $filterTopic;
}

if ($filterCefr !== '') {
    $where[] = "w.cefr_level = ?";
    $params[] = $filterCefr;
}

if ($filterQuality !== '') {
    $qualityScoreSql = "(
        (CASE WHEN COALESCE(TRIM(w.image_path), '') <> '' THEN 1 ELSE 0 END) +
        (CASE WHEN COALESCE(TRIM(w.audio_us_path), '') <> '' THEN 1 ELSE 0 END) +
        (CASE WHEN COALESCE(TRIM(w.phonetic), '') <> '' THEN 1 ELSE 0 END) +
        (CASE WHEN COALESCE(TRIM(w.meaning_vi), '') <> '' THEN 1 ELSE 0 END) +
        (CASE WHEN COALESCE(TRIM(w.cefr_level), '') <> '' THEN 1 ELSE 0 END) +
        (CASE WHEN EXISTS (
            SELECT 1 FROM word_examples qwe
            WHERE qwe.word_id = w.id
              AND qwe.status = 'active'
              AND COALESCE(TRIM(qwe.example_en), '') <> ''
        ) THEN 1 ELSE 0 END) +
        (CASE WHEN EXISTS (
            SELECT 1 FROM topic_words qtw
            WHERE qtw.word_id = w.id
        ) THEN 1 ELSE 0 END)
    )";

    if ($filterQuality === 'complete') {
        $where[] = "{$qualityScoreSql} = 7";
    } elseif ($filterQuality === 'missing') {
        $where[] = "{$qualityScoreSql} BETWEEN 4 AND 6";
    } else {
        $where[] = "{$qualityScoreSql} <= 3";
    }
}

$whereSQL = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

// ─── Sort ──────────────────────────────
$sortMap = [
    'az'       => 'w.word ASC',
    'newest'   => 'w.created_at DESC',
    'updated'  => 'w.updated_at DESC',
    'mostused' => 'usage_count DESC, w.word ASC',
    'cefr'     => "
        CASE w.cefr_level
            WHEN 'Pre-A1' THEN 1
            WHEN 'A1' THEN 2
            WHEN 'A2' THEN 3
            WHEN 'B1' THEN 4
            WHEN 'B2' THEN 5
            WHEN 'C1' THEN 6
            WHEN 'C2' THEN 7
            ELSE 99
        END ASC,
        w.word ASC
    ",
];
$orderBy = $sortMap[$sort] ?? 'w.updated_at DESC';

// ─── Count total ───────────────────────
$countSQL = "SELECT COUNT(DISTINCT w.id) FROM words w {$whereSQL}";
$stmt = $pdo->prepare($countSQL);
$stmt->execute($params);
$totalWords = (int)$stmt->fetchColumn();
$totalPages = max(1, (int)ceil($totalWords / $perPage));
if ($page > $totalPages) $page = $totalPages;
$offset = ($page - 1) * $perPage;

// ─── Detect existing relationship tables ──
$allTables = array_column($pdo->query('SHOW TABLES')->fetchAll(PDO::FETCH_NUM), 0);
$hasLessonWords  = in_array('lesson_words', $allTables);
$hasActivityWords = in_array('activity_words', $allTables);
$hasTopicWords    = in_array('topic_words', $allTables);

// ─── Fetch words with stats ────────────
$selectParts = ["w.*"];
$selectParts[] = "(SELECT example_en FROM word_examples we WHERE we.word_id = w.id AND we.status = 'active' LIMIT 1) AS example_en";
$selectParts[] = "(SELECT example_vi FROM word_examples we WHERE we.word_id = w.id AND we.status = 'active' LIMIT 1) AS example_vi";
$selectParts[] = "(
    (CASE WHEN COALESCE(TRIM(w.image_path), '') <> '' THEN 1 ELSE 0 END) +
    (CASE WHEN COALESCE(TRIM(w.audio_us_path), '') <> '' THEN 1 ELSE 0 END) +
    (CASE WHEN COALESCE(TRIM(w.phonetic), '') <> '' THEN 1 ELSE 0 END) +
    (CASE WHEN COALESCE(TRIM(w.meaning_vi), '') <> '' THEN 1 ELSE 0 END) +
    (CASE WHEN COALESCE(TRIM(w.cefr_level), '') <> '' THEN 1 ELSE 0 END) +
    (CASE WHEN EXISTS (
        SELECT 1 FROM word_examples qwe
        WHERE qwe.word_id = w.id
          AND qwe.status = 'active'
          AND COALESCE(TRIM(qwe.example_en), '') <> ''
    ) THEN 1 ELSE 0 END) +
    (CASE WHEN EXISTS (
        SELECT 1 FROM topic_words qtw
        WHERE qtw.word_id = w.id
    ) THEN 1 ELSE 0 END)
) AS quality_score";

if ($hasLessonWords) {
    $selectParts[] = "(SELECT COUNT(DISTINCT lw.lesson_id) FROM lesson_words lw WHERE lw.word_id = w.id) AS lesson_count";
} else {
    $selectParts[] = "0 AS lesson_count";
}

if ($hasTopicWords) {
    $selectParts[] = "
        (
            SELECT GROUP_CONCAT(
                DISTINCT t.name
                ORDER BY t.name
                SEPARATOR ', '
            )
            FROM topic_words tw
            INNER JOIN topics t ON t.id = tw.topic_id
            WHERE tw.word_id = w.id
        ) AS topic_names
    ";
} else {
    $selectParts[] = "NULL AS topic_names";
}

// usage_count: combine lesson_words + activity_words counts (only if tables exist)
$usageParts = [];
if ($hasLessonWords) {
    $usageParts[] = "(SELECT COUNT(DISTINCT lw2.lesson_id) FROM lesson_words lw2 WHERE lw2.word_id = w.id)";
} else {
    $usageParts[] = "0";
}
if ($hasActivityWords) {
    $usageParts[] = "(SELECT COUNT(DISTINCT aw.activity_id) FROM activity_words aw WHERE aw.word_id = w.id)";
} else {
    $usageParts[] = "0";
}
$selectParts[] = "(" . implode(' + ', $usageParts) . ") AS usage_count";

$wordsSQL = "SELECT " . implode(', ', $selectParts) . " FROM words w {$whereSQL} ORDER BY {$orderBy} LIMIT {$perPage} OFFSET {$offset}";

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

// ─── Aggregate stats ───────────────────
$statsStmt = $pdo->query("
    SELECT
        SUM(status = 'active') AS total,
SUM(status = 'active') AS active,
SUM(status = 'inactive') AS archived
    FROM words
");
$stats = $statsStmt->fetch(PDO::FETCH_ASSOC);

// ─── All topics for filter & form ──────
$topics = $pdo->query("SELECT id, name, slug FROM topics WHERE status = 'active' ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);

// ─── Parts of speech list ──────────────
$posList = ['noun', 'verb', 'adjective', 'adverb', 'pronoun', 'preposition', 'conjunction', 'interjection', 'determiner', 'article'];

// ─── Edit word data ────────────────────
$editWord = null;
$editTopics = [];
$editExamples = [];
if ($editId > 0) {
    $estmt = $pdo->prepare("SELECT * FROM words WHERE id = ?");
    $estmt->execute([$editId]);
    $editWord = $estmt->fetch(PDO::FETCH_ASSOC);
    if ($editWord && !wlCanManageWord($editWord, $isAdmin, $currentUserId)) {
        http_response_code(403);
        exit('You do not have permission to edit this word.');
    }

    if ($editWord) {
        $etStmt = $pdo->prepare("SELECT topic_id FROM topic_words WHERE word_id = ?");
        $etStmt->execute([$editId]);
        $editTopics = $etStmt->fetchAll(PDO::FETCH_COLUMN);

        $exStmt = $pdo->prepare(
            "SELECT * FROM word_examples
             WHERE word_id = ? AND status = 'active'
             ORDER BY sort_order ASC, id ASC"
        );
        $exStmt->execute([$editId]);
        $editExamples = $exStmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

// ─── Helpers ───────────────────────────
function posLabel(string $pos): string {
    return match($pos) {
        'noun' => 'Noun', 'verb' => 'Verb', 'adjective' => 'Adjective',
        'adverb' => 'Adverb', 'pronoun' => 'Pronoun', 'preposition' => 'Preposition',
        'conjunction' => 'Conjunction', 'interjection' => 'Interjection',
        'determiner' => 'Determiner', 'article' => 'Article',
        default => ucfirst($pos)
    };
}

function posClass(string $pos): string {
    return 'wl-pos-' . $pos;
}

function timeAgo(string $datetime): string {
    $diff = time() - strtotime($datetime);
    if ($diff < 60) return 'Just now';
    if ($diff < 3600) return floor($diff / 60) . 'm ago';
    if ($diff < 86400) return floor($diff / 3600) . 'h ago';
    if ($diff < 604800) return floor($diff / 86400) . 'd ago';
    return date('M j, Y', strtotime($datetime));
}

function qualityLabel(int $score): string {
    if ($score >= 7) return 'Complete';
    if ($score >= 4) return 'Missing';
    return 'Incomplete';
}

function qualityClass(int $score): string {
    if ($score >= 7) return 'wl-quality-complete';
    if ($score >= 4) return 'wl-quality-missing';
    return 'wl-quality-incomplete';
}

function qualityMissingItems(array $word): array {
    $missing = [];

    if (empty($word['image_path'])) $missing[] = 'Image';
    if (empty($word['audio_us_path'])) $missing[] = 'Audio';
    if (empty($word['phonetic'])) $missing[] = 'IPA';
    if (empty($word['meaning_vi'])) $missing[] = 'Meaning';
    if (empty($word['cefr_level'])) $missing[] = 'CEFR';
    if (empty($word['example_en'])) $missing[] = 'Example';
    if (empty($word['topic_names'])) $missing[] = 'Topic';

    return $missing;
}

ob_start();
?>

<style>
.wl-cefr-badge{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:48px;
    padding:5px 9px;
    border-radius:999px;
    background:#eef2ff;
    color:#4338ca;
    font-size:11px;
    font-weight:850;
    letter-spacing:.02em;
}
.wl-cefr-prea1{background:#ecfdf3;color:#047857}
.wl-cefr-a1{background:#eff6ff;color:#1d4ed8}
.wl-cefr-a2{background:#eef2ff;color:#4338ca}
.wl-cefr-b1{background:#faf5ff;color:#7e22ce}
.wl-cefr-b2{background:#fdf2f8;color:#be185d}
.wl-cefr-c1{background:#fff7ed;color:#c2410c}
.wl-cefr-c2{background:#fef2f2;color:#b91c1c}
.wl-quality-badge{
    display:inline-flex;
    align-items:center;
    gap:6px;
    min-width:78px;
    padding:5px 9px;
    border-radius:999px;
    font-size:11px;
    font-weight:850;
}
.wl-quality-badge::before{
    content:'';
    width:7px;
    height:7px;
    border-radius:50%;
    background:currentColor;
}
.wl-quality-complete{background:#ecfdf5;color:#047857}
.wl-quality-missing{background:#fff7ed;color:#c2410c}
.wl-quality-incomplete{background:#fef2f2;color:#b91c1c}
.wl-quality-note{
    display:block;
    margin-top:4px;
    color:var(--muted);
    font-size:10px;
    white-space:nowrap;
}
.wl-preview-grid{
    display:grid;
    grid-template-columns:110px 1fr;
    gap:18px;
}
.wl-preview-image{
    width:110px;
    height:110px;
    border-radius:16px;
    object-fit:contain;
    background:#f8fafc;
    border:1px solid #e5e7eb;
}
.wl-preview-placeholder{
    display:flex;
    align-items:center;
    justify-content:center;
    width:110px;
    height:110px;
    border-radius:16px;
    background:#f1f5f9;
    color:#2563eb;
    font-size:40px;
    font-weight:900;
}
.wl-preview-word{
    margin:0;
    color:#0f172a;
    font-size:26px;
    line-height:1.1;
}
.wl-preview-ipa{margin-top:5px;color:#64748b;font-size:13px}
.wl-preview-block{margin-top:14px}
.wl-preview-label{
    display:block;
    margin-bottom:4px;
    color:#94a3b8;
    font-size:10px;
    font-weight:850;
    letter-spacing:.08em;
    text-transform:uppercase;
}
.wl-preview-value{color:#334155;font-size:13px;line-height:1.55}
.wl-word-edit-link{
    color:inherit;
    text-decoration:none;
    cursor:pointer;
}
.wl-word-edit-link:hover{
    color:#2563eb;
    text-decoration:underline;
}
@media(max-width:600px){
    .wl-preview-grid{grid-template-columns:1fr}
}

/* Word Library table scrolling */
.wl-scroll-top{
    width:100%;
    height:16px;
    margin:0 0 8px;
    overflow-x:auto;
    overflow-y:hidden;
    border:1px solid #e5e7eb;
    border-radius:8px;
    background:#f8fafc;
    scrollbar-gutter:stable;
}
.wl-scroll-top-inner{
    height:1px;
}
.wl-table{
    max-height:calc(100vh - 340px);
    min-height:320px;
    overflow:auto !important;
    scrollbar-gutter:stable;
    position:relative;
}
.wl-table .data-table{
    min-width:1320px;
}
.wl-table .data-table thead th{
    position:sticky;
    top:0;
    z-index:4;
    background:#f8fafc;
}
@media(max-height:760px){
    .wl-table{
        max-height:430px;
    }
}
@media(max-width:900px){
    .wl-table{
        max-height:60vh;
        min-height:280px;
    }
}
.wl-examples-box{
    margin-top:4px;
    padding:14px;
    border:1px solid #e2e8f0;
    border-radius:14px;
    background:#f8fafc;
}
.wl-example-row{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;
    gap:10px;
    align-items:end;
    margin-bottom:10px;
}
.wl-example-row:last-child{margin-bottom:0}
.wl-example-remove{
    width:40px;
    height:40px;
    border:1px solid #fecaca;
    border-radius:10px;
    background:#fff1f2;
    color:#be123c;
    cursor:pointer;
    font-size:20px;
    line-height:1;
}
.wl-example-actions{
    display:flex;
    justify-content:flex-start;
    margin-top:10px;
}
@media(max-width:700px){
    .wl-example-row{grid-template-columns:1fr}
    .wl-example-remove{width:100%}
}
</style>

<div class="wl-page-header">
    <div>
        <span class="section-kicker">Word Library</span>
        <h2>Master Vocabulary Database</h2>
    </div>
    <div class="button-group">
        <button
            type="button"
            class="button button-secondary"
            id="assignTopicBtn"
            disabled
        >
            Assign Topic
        </button>

        <a href="import.php" class="button button-secondary">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
            Import Images
        </a>

        <a href="import-excel.php" class="button button-secondary">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M4 4h16v16H4z"/><path d="M4 9h16M9 4v16"/></svg>
            Import Excel
        </a>

        <button class="button button-primary" id="wlAddWordBtn">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M12 5v14M5 12h14"/></svg>
            Add Word
        </button>
    </div>
</div>

<?php if ($message): ?>
<div class="wl-toast wl-toast-<?= $messageType ?>">
    <?= htmlspecialchars($message) ?>
</div>
<script>setTimeout(function(){var t=document.querySelector('.wl-toast');if(t)t.remove();},3500);</script>
<?php endif; ?>

<!-- Stats Bar -->
<div class="wl-stats-bar">
   
    <div class="wl-stat-pill wl-stat-success">
        Active <strong><?= (int)($stats['active'] ?? 0) ?></strong>
    </div>
    <div class="wl-stat-pill wl-stat-danger">
        Archived <strong><?= (int)($stats['archived'] ?? 0) ?></strong>
    </div>
</div>

<!-- Toolbar: Search + Filters + Sort -->
<div class="wl-toolbar">
    <form class="form-search" method="get" style="display:flex;gap:8px;flex:1;max-width:360px;">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" style="position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--muted);"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
        <input type="text" name="search" class="form-control" placeholder="Search word, meaning, IPA..." value="<?= htmlspecialchars($search) ?>" style="padding-left:38px;">
        <button type="submit" class="button button-sm button-primary" style="height:40px;">Search</button>
    </form>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:130px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['status' => '', 'page' => 1])) ?>" <?= $filterStatus === '' ? 'selected' : '' ?>>Status: Active</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['status' => 'inactive', 'page' => 1])) ?>" <?= $filterStatus === 'inactive' ? 'selected' : '' ?>>Status: Archived</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['status' => 'all', 'page' => 1])) ?>" <?= $filterStatus === 'all' ? 'selected' : '' ?>>Status: All</option>
    </select>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:140px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['part_of_speech' => '', 'page' => 1])) ?>">All POS</option>
        <?php foreach ($posList as $pos): ?>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['part_of_speech' => $pos, 'page' => 1])) ?>" <?= $filterPos === $pos ? 'selected' : '' ?>><?= posLabel($pos) ?></option>
        <?php endforeach; ?>
    </select>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:140px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['topic' => 0, 'page' => 1])) ?>">All Topics</option>
        <?php foreach ($topics as $t): ?>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['topic' => $t['id'], 'page' => 1])) ?>" <?= $filterTopic === (int)$t['id'] ? 'selected' : '' ?>><?= htmlspecialchars($t['name']) ?></option>
        <?php endforeach; ?>
    </select>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:135px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['cefr_level' => '', 'page' => 1])) ?>" <?= $filterCefr === '' ? 'selected' : '' ?>>All CEFR</option>
        <?php foreach ($cefrLevels as $cefr): ?>
        <option
            value="?<?= http_build_query(array_merge($cleanQuery, ['cefr_level' => $cefr, 'page' => 1])) ?>"
            <?= $filterCefr === $cefr ? 'selected' : '' ?>
        >
            <?= htmlspecialchars($cefr, ENT_QUOTES, 'UTF-8') ?>
        </option>
        <?php endforeach; ?>
    </select>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:145px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['quality' => '', 'page' => 1])) ?>" <?= $filterQuality === '' ? 'selected' : '' ?>>All Quality</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['quality' => 'complete', 'page' => 1])) ?>" <?= $filterQuality === 'complete' ? 'selected' : '' ?>>Quality: Complete</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['quality' => 'missing', 'page' => 1])) ?>" <?= $filterQuality === 'missing' ? 'selected' : '' ?>>Quality: Missing</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['quality' => 'incomplete', 'page' => 1])) ?>" <?= $filterQuality === 'incomplete' ? 'selected' : '' ?>>Quality: Incomplete</option>
    </select>

    <select class="form-control" onchange="window.location=this.value" style="width:auto;min-width:130px;height:40px;">
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['sort' => 'az', 'page' => 1])) ?>" <?= $sort === 'az' ? 'selected' : '' ?>>Sort: A-Z</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['sort' => 'newest', 'page' => 1])) ?>" <?= $sort === 'newest' ? 'selected' : '' ?>>Sort: Newest</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['sort' => 'updated', 'page' => 1])) ?>" <?= $sort === 'updated' ? 'selected' : '' ?>>Sort: Recently Updated</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['sort' => 'mostused', 'page' => 1])) ?>" <?= $sort === 'mostused' ? 'selected' : '' ?>>Sort: Most Used</option>
        <option value="?<?= http_build_query(array_merge($cleanQuery, ['sort' => 'cefr', 'page' => 1])) ?>" <?= $sort === 'cefr' ? 'selected' : '' ?>>Sort: CEFR</option>
    </select>
</div>

<!-- Word Table -->
<div class="wl-scroll-top" id="wlScrollTop" aria-label="Horizontal table scrollbar">
    <div class="wl-scroll-top-inner" id="wlScrollTopInner"></div>
</div>
<div class="table-shell wl-table" id="wlTableScroll">
    <table class="data-table" id="wlDataTable">
        <thead>
            <tr>
                <th style="width:40px;">
                    <input type="checkbox" id="checkAllWords">
                </th>
                <th></th>
                <th>Word</th>
                <th>IPA</th>
               <th>Part of Speech</th>
                <th>Meaning</th>
                <th>CEFR</th>
                <th>Quality</th>
                <th>Topics</th>
                <th>Lessons</th>
                <th>Status</th>
                <th>Updated</th>
               <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            <?php if (empty($words)): ?>
            <tr>
                <td colspan="13">
                    <div class="wl-empty">
                        <div class="wl-empty-icon">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 4v16m-8-8h16"/><path d="M4 4l16 16M20 4L4 20"/></svg>
                        </div>
                        <h3>No words yet</h3>
                        <p>Create your first vocabulary item to start building the word library.</p>
                        <button class="button button-primary" onclick="document.getElementById('wlAddWordBtn').click()">
                            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M12 5v14M5 12h14"/></svg>
                            Create First Word
                        </button>
                    </div>
                </td>
            </tr>
            <?php else: ?>
                <?php foreach ($words as $w): ?>
                <tr>
                    <td style="width:40px;">
                        <input
                            type="checkbox"
                            class="word-check"
                            value="<?= (int)$w['id'] ?>"
                        >
                    </td>
                    <td style="width:56px;">
                        <?php if (!empty($w['image_path'])): ?>
                        <a href="<?= htmlspecialchars(es_url($w['image_path'])) ?>" target="_blank" class="wl-word-thumb-link">
                            <img src="<?= htmlspecialchars(es_url($w['image_path'])) ?>" alt="" class="wl-word-thumb" loading="lazy">
                        </a>
                        <?php else: ?>
                        <div class="wl-word-thumb-placeholder"><?= htmlspecialchars(mb_strtoupper(mb_substr($w['word'], 0, 1))) ?></div>
                        <?php endif; ?>
                    </td>
                    <td>
                        <div class="wl-word-info">
                            <?php if (wlCanManageWord($w, $isAdmin, $currentUserId)): ?>
                            <a
                                href="?<?= htmlspecialchars(http_build_query(array_merge($cleanQuery, ['edit' => (int)$w['id']])), ENT_QUOTES, 'UTF-8') ?>"
                                class="wl-word-edit-link"
                                title="Edit <?= htmlspecialchars((string)$w['word'], ENT_QUOTES, 'UTF-8') ?>"
                            ><strong><?= htmlspecialchars($w['word']) ?></strong></a>
                            <?php else: ?>
                            <strong><?= htmlspecialchars($w['word']) ?></strong>
                            <?php endif; ?>
                            <?php if (!empty($w['phonetic'])): ?>
                            <span class="wl-ipa"><?= htmlspecialchars($w['phonetic']) ?></span>
                            <?php endif; ?>
                        </div>
                    </td>
                    <td>
    <div style="display:flex;align-items:center;gap:8px;">
        <span class="wl-ipa">
            <?= htmlspecialchars($w['phonetic'] ?? '—') ?>
        </span>

        <button
            type="button"
            class="wl-play-btn"
            data-word="<?= htmlspecialchars($w['word']) ?>"
            data-audio="<?= !empty($w['audio_us_path'])
    ? htmlspecialchars(es_url($w['audio_us_path']))
    : '' ?>"
            title="Play pronunciation">
            🔊
        </button>
    </div>
</td>
                    <td>
                        <?php if (!empty($w['part_of_speech'])): ?>
                        <span class="wl-pos-badge <?= posClass($w['part_of_speech']) ?>"><?= posLabel($w['part_of_speech']) ?></span>
                        <?php else: ?>
                        <span style="color:var(--muted);font-size:12px;">—</span>
                        <?php endif; ?>
                    </td>
                    <td class="u-truncate" style="max-width:180px;"><?= htmlspecialchars($w['meaning_vi'] ?? '') ?: '—' ?></td>
                    <td>
                        <?php if (!empty($w['cefr_level'])): ?>
                        <span class="wl-cefr-badge wl-cefr-<?= strtolower(str_replace('-', '', (string)$w['cefr_level'])) ?>">
                            <?= htmlspecialchars((string)$w['cefr_level'], ENT_QUOTES, 'UTF-8') ?>
                        </span>
                        <?php else: ?>
                        <span style="color:var(--muted);font-size:12px;">—</span>
                        <?php endif; ?>
                    </td>
                    <td>
                        <?php
                            $qualityScore = (int)($w['quality_score'] ?? 0);
                            $missingItems = qualityMissingItems($w);
                        ?>
                        <span
                            class="wl-quality-badge <?= qualityClass($qualityScore) ?>"
                            title="<?= htmlspecialchars(
                                empty($missingItems)
                                    ? 'All required fields are complete.'
                                    : 'Missing: ' . implode(', ', $missingItems),
                                ENT_QUOTES,
                                'UTF-8'
                            ) ?>"
                        >
                            <?= qualityLabel($qualityScore) ?>
                        </span>
                        <span class="wl-quality-note"><?= $qualityScore ?>/7 fields</span>
                    </td>
                    <td>
<?php if (!empty($w['topic_names'])): ?>

    <span class="wl-topic-list">
        <?= htmlspecialchars($w['topic_names']) ?>
    </span>

<?php else: ?>

    <span style="color:#999;">—</span>

<?php endif; ?>
</td>
                    <td><span class="wl-usage-count"><?= (int)($w['lesson_count'] ?? 0) ?></span></td>
                    <td>
                        <span class="wl-status-badge <?= $w['status'] === 'active' ? 'wl-status-active' : 'wl-status-archived' ?>">
                            <?= $w['status'] === 'active' ? 'Active' : 'Archived' ?>
                        </span>
                    </td>
                    <td style="color:var(--muted);font-size:11px;"><?= timeAgo($w['updated_at'] ?? $w['created_at']) ?></td>
                    <td>
                        <div class="wl-action-group">
                            <button
                                type="button"
                                class="icon-button wl-preview-btn"
                                title="Quick Preview"
                                data-word-id="<?= (int)$w['id'] ?>"
                                data-word="<?= htmlspecialchars((string)$w['word'], ENT_QUOTES, 'UTF-8') ?>"
                                data-ipa="<?= htmlspecialchars((string)($w['phonetic'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-meaning="<?= htmlspecialchars((string)($w['meaning_vi'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-example="<?= htmlspecialchars((string)($w['example_en'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-example-vi="<?= htmlspecialchars((string)($w['example_vi'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-cefr="<?= htmlspecialchars((string)($w['cefr_level'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-topics="<?= htmlspecialchars((string)($w['topic_names'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                data-quality="<?= htmlspecialchars(qualityLabel((int)($w['quality_score'] ?? 0)), ENT_QUOTES, 'UTF-8') ?>"
                                data-missing="<?= htmlspecialchars(implode(', ', qualityMissingItems($w)), ENT_QUOTES, 'UTF-8') ?>"
                                data-image="<?= !empty($w['image_path']) ? htmlspecialchars(es_url($w['image_path']), ENT_QUOTES, 'UTF-8') : '' ?>"
                            >
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12Z"/>
                                    <circle cx="12" cy="12" r="2.5"/>
                                </svg>
                            </button>
                            <button
                                type="button"
                                class="icon-button wl-add-example-btn"
                                title="Add Example"
                                data-word-id="<?= (int)$w['id'] ?>"
                                data-word="<?= htmlspecialchars((string)$w['word'], ENT_QUOTES, 'UTF-8') ?>"
                                style="color:#2563eb;"
                            >
                                <span style="font-size:18px;font-weight:900;line-height:1;">＋</span>
                            </button>
                            <?php if (wlCanManageWord($w, $isAdmin, $currentUserId)): ?>
                            <a
                                href="?<?= htmlspecialchars(http_build_query(array_merge($cleanQuery, ['edit' => (int)$w['id']])), ENT_QUOTES, 'UTF-8') ?>"
                                class="icon-button"
                                title="Edit"
                            >
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
                            </a>
                            <?php if ($w['status'] === 'active'): ?>
                            <form method="post" style="display:inline;" onsubmit="return confirm('Archive this word?')">
                                <input type="hidden" name="action" value="archive">
                                <input type="hidden" name="id" value="<?= $w['id'] ?>">
                                <button type="submit" class="icon-button" title="Archive" style="color:var(--danger);">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14"/></svg>
                                </button>
                            </form>
                            <?php else: ?>
                            <form method="post" style="display:inline;" onsubmit="return confirm('Restore this word?')">
                                <input type="hidden" name="action" value="restore">
                                <input type="hidden" name="id" value="<?= $w['id'] ?>">
                                <button type="submit" class="icon-button" title="Restore" style="color:var(--success);">
                                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 4v6h6M23 20v-6h-6"/><path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"/></svg>
                                </button>
                            </form>
                            <?php endif; ?>
                            <?php endif; ?>
                        </div>
                    </td>
                </tr>
                <?php endforeach; ?>
            <?php endif; ?>
        </tbody>
    </table>
</div>

<!-- Pagination -->
<?php if ($totalPages > 1): ?>
<div class="wl-pagination">
    <?php if ($page > 1): ?>
    <a href="?<?= http_build_query(array_merge($cleanQuery, ['page' => $page - 1])) ?>" class="button button-sm button-secondary">Previous</a>
    <?php endif; ?>
    <span class="wl-page-current">Page <?= $page ?> of <?= $totalPages ?></span>
    <?php if ($page < $totalPages): ?>
    <a href="?<?= http_build_query(array_merge($cleanQuery, ['page' => $page + 1])) ?>" class="button button-sm button-secondary">Next</a>
    <?php endif; ?>
</div>
<?php endif; ?>

<!-- Quick Preview Modal -->
<div class="wl-modal-overlay" id="wlPreviewOverlay">
    <div class="wl-modal" style="max-width:620px;">
        <div class="wl-modal-header">
            <h3>Word Preview</h3>
            <button type="button" class="wl-modal-close" id="wlPreviewClose">&times;</button>
        </div>

        <div class="wl-preview-grid">
            <div id="wlPreviewMedia"></div>

            <div>
                <h2 class="wl-preview-word" id="wlPreviewWord">—</h2>
                <div class="wl-preview-ipa" id="wlPreviewIpa"></div>

                <div class="wl-preview-block">
                    <span class="wl-preview-label">Meaning</span>
                    <div class="wl-preview-value" id="wlPreviewMeaning">—</div>
                </div>

                <div class="wl-preview-block">
                    <span class="wl-preview-label">Example</span>
                    <div class="wl-preview-value" id="wlPreviewExample">—</div>
                    <div class="wl-preview-value" id="wlPreviewExampleVi" style="color:#64748b;"></div>
                </div>

                <div class="wl-preview-block">
                    <span class="wl-preview-label">CEFR · Topics</span>
                    <div class="wl-preview-value" id="wlPreviewMeta">—</div>
                </div>

                <div class="wl-preview-block">
                    <span class="wl-preview-label">Quality</span>
                    <div class="wl-preview-value" id="wlPreviewQuality">—</div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Assign Topic Modal -->
<div class="wl-modal-overlay" id="assignTopicOverlay">
    <div class="wl-modal" style="max-width:560px;">
        <div class="wl-modal-header">
            <h3>Assign Topic</h3>
            <button type="button" class="wl-modal-close" id="assignTopicClose">&times;</button>
        </div>

        <form method="post" id="assignTopicForm">
            <input type="hidden" name="action" value="assign_topics">

            <div id="assignWordInputs"></div>

            <p class="form-helper" id="assignSelectedText" style="margin-bottom:16px;">
                0 words selected
            </p>

            <div class="form-group">
                <label class="form-label">Choose Topic</label>
<div class="wl-topic-actions">
    <a href="#" id="selectAllTopics">✓ Select All</a>
    <a href="#" id="clearAllTopics">✕ Clear All</a>
</div>
                <?php if (!empty($topics)): ?>
                    <div class="wl-topic-checkboxes">
                        <?php foreach ($topics as $t): ?>
                            <label class="wl-topic-checkbox">
                                <input
                                    type="checkbox"
                                    name="assign_topic_ids[]"
                                    value="<?= (int)$t['id'] ?>"
                                >
                                <?= htmlspecialchars($t['name']) ?>
                            </label>
                        <?php endforeach; ?>
                    </div>
                <?php else: ?>
                    <p class="form-helper">No active Topics available.</p>
                <?php endif; ?>
            </div>

            <div class="form-group" style="margin-top:18px;">
                <label class="form-label">Assignment Mode</label>

                <label style="display:flex;gap:8px;align-items:flex-start;margin-bottom:10px;">
                    <input type="radio" name="assign_mode" value="add" checked>
                    <span>
                        <strong>Add to existing Topics</strong><br>
                        <small style="color:var(--muted);">Keep current Topics and add the selected ones.</small>
                    </span>
                </label>

                <label style="display:flex;gap:8px;align-items:flex-start;">
                    <input type="radio" name="assign_mode" value="replace">
                    <span>
                        <strong>Replace existing Topics</strong><br>
                        <small style="color:var(--muted);">Remove current Topics, then use only the selected ones.</small>
                    </span>
                </label>
            </div>

            <div class="button-group" style="justify-content:flex-end;margin-top:22px;">
                <button type="button" class="button button-secondary" id="assignTopicCancel">
                    Cancel
                </button>

                <button
                    type="submit"
                    class="button button-primary"
                    <?= empty($topics) ? 'disabled' : '' ?>
                >
                    Save
                </button>
            </div>
        </form>
    </div>
</div>

<!-- Add Example Modal: available for shared Words -->
<div class="wl-modal-overlay" id="wlAddExampleOverlay">
    <div class="wl-modal" style="max-width:620px;">
        <div class="wl-modal-header">
            <h3>Add Example · <span id="wlAddExampleWord">Word</span></h3>
            <button type="button" class="wl-modal-close" id="wlAddExampleClose">&times;</button>
        </div>
        <form method="post" id="wlAddExampleForm">
            <input type="hidden" name="action" value="add_example">
            <input type="hidden" name="word_id" id="wlAddExampleWordId" value="0">
            <div class="form-group">
                <label class="form-label">Example Sentence <span class="required">*</span></label>
                <input type="text" name="example_en" id="wlAddExampleEn" class="form-control" required placeholder="e.g. This is a ball.">
            </div>
            <div class="form-group">
                <label class="form-label">Example Meaning</label>
                <input type="text" name="example_vi" class="form-control" placeholder="e.g. Đây là một quả bóng.">
            </div>
            <small class="form-helper" style="display:block;margin-top:8px;">
                This adds a reusable Example only. The original Word, image, IPA and meaning are not changed.
            </small>
            <div class="button-group" style="justify-content:flex-end;margin-top:20px;">
                <button type="button" class="button button-secondary" id="wlAddExampleCancel">Cancel</button>
                <button type="submit" class="button button-primary">Add Example</button>
            </div>
        </form>
    </div>
</div>

<!-- Create/Edit Modal -->
<div class="wl-modal-overlay" id="wlModalOverlay">
    <div class="wl-modal" id="wlModal">
        <div class="wl-modal-header">
            <h3 id="wlModalTitle">Add New Word</h3>
            <button class="wl-modal-close" id="wlModalClose">&times;</button>
        </div>

        <?php if ($formError): ?>
        <div class="wl-duplicate-alert">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
            <?= htmlspecialchars($formError) ?>
        </div>
        <?php endif; ?>

        <form method="post" enctype="multipart/form-data" id="wlForm">
            <input type="hidden" name="action" id="wlFormAction" value="save">
            <input type="hidden" name="id" id="wlFormId" value="<?= $editId ?>">
            <input type="hidden" name="existing_image" id="wlExistingImage" value="<?= htmlspecialchars($editWord['image_path'] ?? '') ?>">
            <input type="hidden" name="existing_audio" id="wlExistingAudio" value="<?= htmlspecialchars($editWord['audio_us_path'] ?? '') ?>">

            <!-- Word + Meaning -->
            <div class="wl-form-row">
                <div class="form-group">
                    <label class="form-label">Word <span class="required">*</span></label>
                    <input type="text" name="word" class="form-control" required value="<?= htmlspecialchars($editWord['word'] ?? '') ?>" placeholder="e.g. apple" id="wlWordInput">
                </div>
                <div class="form-group">
                    <label class="form-label">Meaning (Vietnamese)</label>
                    <input type="text" name="meaning_vi" class="form-control" value="<?= htmlspecialchars($editWord['meaning_vi'] ?? '') ?>" placeholder="e.g. quả táo">
                </div>
            </div>

            <!-- IPA + POS -->
            <div class="wl-form-row">
                <div class="form-group">
                    <label class="form-label">IPA / Phonetic</label>
                    <input type="text" name="phonetic" class="form-control" value="<?= htmlspecialchars($editWord['phonetic'] ?? '') ?>" placeholder="e.g. /ˈæp.əl/">
                </div>
                <div class="form-group">
                    <label class="form-label">Part of Speech</label>
                    <select name="part_of_speech" class="form-control">
                        <option value="">— Select —</option>
                        <?php foreach ($posList as $pos): ?>
                        <option value="<?= $pos ?>" <?= ($editWord['part_of_speech'] ?? '') === $pos ? 'selected' : '' ?>><?= posLabel($pos) ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
            </div>

            <!-- Examples: one Word can have many reusable examples -->
            <div class="form-group">
                <label class="form-label">Example Sentences</label>
                <small class="form-helper" style="display:block;margin-bottom:8px;">
                    Add multiple examples for the same Word. A Flashcard Set can choose the most suitable example later.
                </small>
                <div class="wl-examples-box" id="wlExamplesBox">
                    <?php
                    $exampleFormRows = $editExamples;
                    if ($exampleFormRows === []) {
                        $exampleFormRows = [['example_en' => '', 'example_vi' => '']];
                    }
                    ?>
                    <?php foreach ($exampleFormRows as $exampleRow): ?>
                    <div class="wl-example-row">
                        <div>
                            <label class="form-label">Example Sentence</label>
                            <input
                                type="text"
                                name="example_en[]"
                                class="form-control"
                                value="<?= htmlspecialchars((string)($exampleRow['example_en'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                placeholder="e.g. It's a ball."
                            >
                        </div>
                        <div>
                            <label class="form-label">Example Meaning</label>
                            <input
                                type="text"
                                name="example_vi[]"
                                class="form-control"
                                value="<?= htmlspecialchars((string)($exampleRow['example_vi'] ?? ''), ENT_QUOTES, 'UTF-8') ?>"
                                placeholder="e.g. Đây là một quả bóng."
                            >
                        </div>
                        <button type="button" class="wl-example-remove" title="Remove example">&times;</button>
                    </div>
                    <?php endforeach; ?>
                </div>
                <div class="wl-example-actions">
                    <button type="button" class="button button-secondary button-sm" id="wlAddExampleBtn">
                        + Add Example
                    </button>
                </div>
            </div>

            <!-- Image Upload -->
            <div class="form-group">
                <label class="form-label">Image</label>
                <div class="wl-upload-area <?= !empty($editWord['image_path']) ? 'has-file' : '' ?>" id="wlImageUpload">
                    <?php if (!empty($editWord['image_path'])): ?>
                    <div class="wl-upload-preview">
                        <img src="<?= htmlspecialchars(es_url($editWord['image_path'])) ?>" alt="Preview">
                        <div class="wl-upload-info">
                            <strong>Current image</strong>
                            <small>Click to replace</small>
                        </div>
                        <button
                            type="submit"
                            class="wl-upload-remove"
                            title="Delete image"
                            onclick="document.getElementById('wlFormAction').value='delete_image';"
                        >&times;</button>
                    </div>
                    <?php else: ?>
                    <div class="wl-upload-icon">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
                    </div>
                    <div class="wl-upload-text">Drop image or <strong>browse</strong></div>
                    <?php endif; ?>
                    <input type="file" name="image_file" accept="image/*" style="position:absolute;inset:0;opacity:0;cursor:pointer;" id="wlImageInput" onchange="handleImagePreview(this)">
                </div>
            </div>

            <!-- Audio Upload -->
            <div class="form-group">
                <label class="form-label">Audio</label>
                <div class="wl-upload-area <?= !empty($editWord['audio_us_path']) ? 'has-file' : '' ?>" id="wlAudioUpload">
                    <?php if (!empty($editWord['audio_us_path'])): ?>
                    <div class="wl-upload-preview">
                        <audio controls src="<?= htmlspecialchars(es_url($editWord['audio_us_path'])) ?>" style="flex:1;"></audio>
                        <button
                            type="submit"
                            class="wl-upload-remove"
                            title="Delete audio"
                            onclick="document.getElementById('wlFormAction').value='delete_audio';"
                        >&times;</button>
                    </div>
                    <?php else: ?>
                    <div class="wl-upload-icon">
                        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M12 1v12M8 9l4-4 4 4"/><rect x="3" y="15" width="18" height="4" rx="1"/></svg>
                    </div>
                    <div class="wl-upload-text">Drop audio or <strong>browse</strong></div>
                    <?php endif; ?>
                    <input type="file" name="audio_file" accept="audio/*" style="position:absolute;inset:0;opacity:0;cursor:pointer;" id="wlAudioInput" onchange="handleAudioPreview(this)">
                </div>
            </div>

            <!-- CEFR Level + Status -->
            <div class="wl-form-row">
                <div class="form-group">
                    <label class="form-label">CEFR Level</label>
                    <select name="cefr_level" class="form-control">
                        <option value="">— Not assigned —</option>
                        <?php foreach (['Pre-A1', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2'] as $cefr): ?>
                        <option
                            value="<?= htmlspecialchars($cefr, ENT_QUOTES, 'UTF-8') ?>"
                            <?= ($editWord['cefr_level'] ?? '') === $cefr ? 'selected' : '' ?>
                        >
                            <?= htmlspecialchars($cefr, ENT_QUOTES, 'UTF-8') ?>
                        </option>
                        <?php endforeach; ?>
                    </select>
                    <small class="form-helper">
                        Teacher-only metadata used for filtering and future AI suggestions.
                    </small>

                    <input
                        type="hidden"
                        name="difficulty_level"
                        value="<?= (int)($editWord['difficulty_level'] ?? 1) ?>"
                    >
                </div>
                <div class="form-group">
                    <label class="form-label">Status</label>
                    <select name="status" class="form-control">
                        <option value="active" <?= ($editWord['status'] ?? 'active') === 'active' ? 'selected' : '' ?>>Active</option>
                        <option value="inactive" <?= ($editWord['status'] ?? '') === 'inactive' ? 'selected' : '' ?>>Archived</option>
                    </select>
                </div>
            </div>

            <!-- Topics -->
            <div class="form-group">
                <label class="form-label">Topics</label>
                <?php if (!empty($topics)): ?>
                <div class="wl-topic-checkboxes">
                    <?php foreach ($topics as $t): ?>
                    <label class="wl-topic-checkbox">
                        <input type="checkbox" name="topic_ids[]" value="<?= $t['id'] ?>" <?= in_array($t['id'], $editTopics) ? 'checked' : '' ?>>
                        <?= htmlspecialchars($t['name']) ?>
                    </label>
                    <?php endforeach; ?>
                </div>
                <?php else: ?>
                <p class="form-helper">No topics available yet.</p>
                <?php endif; ?>
            </div>

            <!-- Notes -->
            <div class="form-group">
                <label class="form-label">Notes</label>
                <textarea name="notes" class="form-control" rows="3" placeholder="Internal notes..."><?= htmlspecialchars($editWord['notes'] ?? '') ?></textarea>
            </div>

            <!-- Buttons -->
            <div class="button-group" style="justify-content:flex-end;margin-top:20px;">
                <button type="button" class="button button-secondary" onclick="closeModal()">Cancel</button>
                <button
                    type="submit"
                    class="button button-primary"
                    onclick="document.getElementById('wlFormAction').value='save';"
                >
                    <?= $editId > 0 ? 'Save Changes' : 'Create Word' ?>
                </button>
            </div>
        </form>
    </div>
</div>

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

    const overlay = document.getElementById('wlPreviewOverlay');
    const closeBtn = document.getElementById('wlPreviewClose');

    function escapeHtml(value) {
        return String(value || '').replace(/[&<>"']/g, function (char) {
            return {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            }[char];
        });
    }

    function closePreview() {
        overlay.classList.remove('is-open');
    }

    document.addEventListener('click', function (event) {
        const button = event.target.closest('.wl-preview-btn');
        if (!button) return;

        const word = button.dataset.word || '';
        const image = button.dataset.image || '';
        const missing = button.dataset.missing || '';

        document.getElementById('wlPreviewWord').textContent = word || '—';
        document.getElementById('wlPreviewIpa').textContent = button.dataset.ipa || '';
        document.getElementById('wlPreviewMeaning').textContent = button.dataset.meaning || '—';
        document.getElementById('wlPreviewExample').textContent = button.dataset.example || 'No example sentence yet.';
        document.getElementById('wlPreviewExampleVi').textContent = button.dataset.exampleVi || '';

        const meta = [
            button.dataset.cefr || 'CEFR not assigned',
            button.dataset.topics || 'No Topic'
        ];
        document.getElementById('wlPreviewMeta').textContent = meta.join(' · ');

        document.getElementById('wlPreviewQuality').textContent =
            (button.dataset.quality || 'Incomplete') +
            (missing ? ' · Missing: ' + missing : ' · All required fields complete');

        document.getElementById('wlPreviewMedia').innerHTML = image
            ? '<img class="wl-preview-image" src="' + escapeHtml(image) + '" alt="">'
            : '<div class="wl-preview-placeholder">' +
                escapeHtml((word || '?').charAt(0).toUpperCase()) +
              '</div>';

        overlay.classList.add('is-open');
    });

    closeBtn.addEventListener('click', closePreview);
    overlay.addEventListener('click', function (event) {
        if (event.target === overlay) closePreview();
    });
})();
</script>

<script>
// Shared Word: any Teacher can contribute an Example without editing the Word.
(function(){
    var overlay = document.getElementById('wlAddExampleOverlay');
    var closeBtn = document.getElementById('wlAddExampleClose');
    var cancelBtn = document.getElementById('wlAddExampleCancel');
    var wordIdInput = document.getElementById('wlAddExampleWordId');
    var wordLabel = document.getElementById('wlAddExampleWord');
    var exampleInput = document.getElementById('wlAddExampleEn');

    function closeAddExample(){ if (overlay) overlay.classList.remove('is-open'); }
    document.querySelectorAll('.wl-add-example-btn').forEach(function(btn){
        btn.addEventListener('click', function(){
            wordIdInput.value = btn.dataset.wordId || '0';
            wordLabel.textContent = btn.dataset.word || 'Word';
            document.getElementById('wlAddExampleForm').reset();
            wordIdInput.value = btn.dataset.wordId || '0';
            overlay.classList.add('is-open');
            setTimeout(function(){ exampleInput.focus(); }, 50);
        });
    });
    closeBtn?.addEventListener('click', closeAddExample);
    cancelBtn?.addEventListener('click', closeAddExample);
    overlay?.addEventListener('click', function(e){ if (e.target === overlay) closeAddExample(); });
})();
</script>

<script>
// ─── Modal Logic ───────────────────────
var modalOverlay = document.getElementById('wlModalOverlay');

function wlExampleRowHtml(exampleEn, exampleVi) {
    function esc(value) {
        return String(value || '').replace(/[&<>"']/g, function(char) {
            return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[char];
        });
    }
    return '<div class="wl-example-row">'
        + '<div><label class="form-label">Example Sentence</label>'
        + '<input type="text" name="example_en[]" class="form-control" value="' + esc(exampleEn) + '" placeholder="e.g. It\'s a ball."></div>'
        + '<div><label class="form-label">Example Meaning</label>'
        + '<input type="text" name="example_vi[]" class="form-control" value="' + esc(exampleVi) + '" placeholder="e.g. Đây là một quả bóng."></div>'
        + '<button type="button" class="wl-example-remove" title="Remove example">&times;</button>'
        + '</div>';
}

function wlBindExampleRemoveButtons() {
    document.querySelectorAll('#wlExamplesBox .wl-example-remove').forEach(function(button) {
        button.onclick = function() {
            var box = document.getElementById('wlExamplesBox');
            var rows = box.querySelectorAll('.wl-example-row');
            if (rows.length <= 1) {
                rows[0].querySelectorAll('input').forEach(function(input){ input.value = ''; });
                return;
            }
            button.closest('.wl-example-row').remove();
        };
    });
}

document.getElementById('wlAddExampleBtn')?.addEventListener('click', function() {
    var box = document.getElementById('wlExamplesBox');
    box.insertAdjacentHTML('beforeend', wlExampleRowHtml('', ''));
    wlBindExampleRemoveButtons();
});

wlBindExampleRemoveButtons();

// Open modal for "Add Word" button
document.getElementById('wlAddWordBtn').addEventListener('click', function() {
    document.getElementById('wlModalTitle').textContent = 'Add New Word';
    document.getElementById('wlFormId').value = '0';
    document.getElementById('wlForm').reset();
    var examplesBox = document.getElementById('wlExamplesBox');
    if (examplesBox) {
        examplesBox.innerHTML = wlExampleRowHtml('', '');
        wlBindExampleRemoveButtons();
    }
    document.getElementById('wlExistingImage').value = '';
    document.getElementById('wlExistingAudio').value = '';
    document.getElementById('wlImageUpload').classList.remove('has-file');
    document.getElementById('wlAudioUpload').classList.remove('has-file');
    // Reset previews
    var imgPrev = document.querySelector('#wlImageUpload .wl-upload-preview');
    var audPrev = document.querySelector('#wlAudioUpload .wl-upload-preview');
    if (imgPrev) imgPrev.remove();
    if (audPrev) audPrev.remove();
    // Show icons
    document.querySelector('#wlImageUpload .wl-upload-icon').style.display = '';
    document.querySelector('#wlImageUpload .wl-upload-text').style.display = '';
    document.querySelector('#wlAudioUpload .wl-upload-icon').style.display = '';
    document.querySelector('#wlAudioUpload .wl-upload-text').style.display = '';
    // Clear any error
    var alert = document.querySelector('.wl-duplicate-alert');
    if (alert) alert.remove();
    modalOverlay.classList.add('is-open');
});

function openEditModal(e, wordId) {
    e.preventDefault();
    var url = new URL(window.location.href);
    url.searchParams.set('edit', String(wordId));
    window.location.href = url.pathname + '?' + url.searchParams.toString();
}

// Close modal
document.getElementById('wlModalClose').addEventListener('click', closeModal);
modalOverlay.addEventListener('click', function(e) {
    if (e.target === modalOverlay) closeModal();
});

function closeModal() {
    modalOverlay.classList.remove('is-open');

    var url = new URL(window.location.href);
    if (url.searchParams.has('edit')) {
        url.searchParams.delete('edit');
        window.history.replaceState({}, '', url.pathname + (url.search ? url.search : '') + url.hash);
    }
}

// Handle image preview
function handleImagePreview(input) {
    var uploadArea = document.getElementById('wlImageUpload');
    var file = input.files[0];
    if (!file) return;

    // Remove existing preview
    var existing = uploadArea.querySelector('.wl-upload-preview');
    if (existing) existing.remove();

    var icon = uploadArea.querySelector('.wl-upload-icon');
    var text = uploadArea.querySelector('.wl-upload-text');
    if (icon) icon.style.display = 'none';
    if (text) text.style.display = 'none';

    uploadArea.classList.add('has-file');

    var reader = new FileReader();
    reader.onload = function(e) {
        var preview = document.createElement('div');
        preview.className = 'wl-upload-preview';
        preview.innerHTML = '<img src="' + e.target.result + '" alt="Preview"><div class="wl-upload-info"><strong>' + file.name + '</strong><small>Ready to upload</small></div>';
        uploadArea.appendChild(preview);
    };
    reader.readAsDataURL(file);
}

// Handle audio preview
function handleAudioPreview(input) {
    var uploadArea = document.getElementById('wlAudioUpload');
    var file = input.files[0];
    if (!file) return;

    var existing = uploadArea.querySelector('.wl-upload-preview');
    if (existing) existing.remove();

    var icon = uploadArea.querySelector('.wl-upload-icon');
    var text = uploadArea.querySelector('.wl-upload-text');
    if (icon) icon.style.display = 'none';
    if (text) text.style.display = 'none';

    uploadArea.classList.add('has-file');

    var url = URL.createObjectURL(file);
    var preview = document.createElement('div');
    preview.className = 'wl-upload-preview';
    preview.innerHTML = '<audio controls src="' + url + '" style="flex:1;"></audio><div class="wl-upload-info"><strong>' + file.name + '</strong><small>Ready to upload</small></div>';
    uploadArea.appendChild(preview);
}

// Auto-open modal if editing
<?php if ($editId > 0 || $formError): ?>
document.addEventListener('DOMContentLoaded', function() {
    document.getElementById('wlModalTitle').textContent = 'Edit Word';
    modalOverlay.classList.add('is-open');
});
<?php endif; ?>
</script>
<script>

document.addEventListener("click",function(e){

    const btn=e.target.closest(".wl-play-btn");

    if(!btn) return;

    const audio=btn.dataset.audio;

    if(audio){

        new Audio(audio).play();

        return;

    }

    const word=btn.dataset.word;

    const speech=new SpeechSynthesisUtterance(word);

    speech.lang="en-US";

    speech.rate=0.8;

    speech.pitch=1;

    window.speechSynthesis.cancel();

    window.speechSynthesis.speak(speech);

});

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

    const checks = Array.from(document.querySelectorAll('.word-check'));
    const btn = document.getElementById('assignTopicBtn');
    const all = document.getElementById('checkAllWords');
    const overlay = document.getElementById('assignTopicOverlay');
    const closeBtn = document.getElementById('assignTopicClose');
    const cancelBtn = document.getElementById('assignTopicCancel');
    const inputWrap = document.getElementById('assignWordInputs');
    const selectedText = document.getElementById('assignSelectedText');
    const form = document.getElementById('assignTopicForm');

    function selectedChecks() {
        return checks.filter(function (checkbox) {
            return checkbox.checked;
        });
    }

    function updateAssignButton() {
        const selected = selectedChecks();

        if (btn) {
            btn.disabled = selected.length === 0;
        }

        if (all) {
            all.checked = checks.length > 0 && selected.length === checks.length;
            all.indeterminate = selected.length > 0 && selected.length < checks.length;
        }
    }

    function openAssignModal() {
        const selected = selectedChecks();

        if (!overlay || selected.length === 0) {
            return;
        }

        inputWrap.innerHTML = '';

        selected.forEach(function (checkbox) {
            const input = document.createElement('input');
            input.type = 'hidden';
            input.name = 'word_ids[]';
            input.value = checkbox.value;
            inputWrap.appendChild(input);
        });

        selectedText.textContent = selected.length + ' words selected';
        overlay.classList.add('is-open');
    }

    function closeAssignModal() {
        if (!overlay) {
            return;
        }

        overlay.classList.remove('is-open');
    }

    checks.forEach(function (checkbox) {
        checkbox.addEventListener('change', updateAssignButton);
    });

    if (all) {
        all.addEventListener('change', function () {
            checks.forEach(function (checkbox) {
                checkbox.checked = all.checked;
            });
            updateAssignButton();
        });
    }

    if (btn) {
        btn.addEventListener('click', openAssignModal);
    }

    if (closeBtn) {
        closeBtn.addEventListener('click', closeAssignModal);
    }

    if (cancelBtn) {
        cancelBtn.addEventListener('click', closeAssignModal);
    }

    if (overlay) {
        overlay.addEventListener('click', function (event) {
            if (event.target === overlay) {
                closeAssignModal();
            }
        });
    }

    if (form) {
        form.addEventListener('submit', function (event) {
            const topicChecks = form.querySelectorAll(
                'input[name="assign_topic_ids[]"]:checked'
            );

            if (topicChecks.length === 0) {
                event.preventDefault();
                alert('Please choose at least one Topic.');
            }
        });
    }


    const selectAllTopics = document.getElementById('selectAllTopics');
    const clearAllTopics = document.getElementById('clearAllTopics');

    if (selectAllTopics && form) {
        selectAllTopics.addEventListener('click', function (event) {
            event.preventDefault();

            form.querySelectorAll(
                'input[name="assign_topic_ids[]"]'
            ).forEach(function (checkbox) {
                checkbox.checked = true;
            });
        });
    }

    if (clearAllTopics && form) {
        clearAllTopics.addEventListener('click', function (event) {
            event.preventDefault();

            form.querySelectorAll(
                'input[name="assign_topic_ids[]"]'
            ).forEach(function (checkbox) {
                checkbox.checked = false;
            });
        });
    }

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

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

    const topScroll = document.getElementById('wlScrollTop');
    const topInner = document.getElementById('wlScrollTopInner');
    const tableScroll = document.getElementById('wlTableScroll');
    const table = document.getElementById('wlDataTable');

    if (!topScroll || !topInner || !tableScroll || !table) return;

    let syncingFromTop = false;
    let syncingFromTable = false;

    function refreshTopScrollbar() {
        topInner.style.width = Math.max(table.scrollWidth, tableScroll.clientWidth) + 'px';
        topScroll.style.display = table.scrollWidth > tableScroll.clientWidth ? 'block' : 'none';
        topScroll.scrollLeft = tableScroll.scrollLeft;
    }

    topScroll.addEventListener('scroll', function () {
        if (syncingFromTable) return;
        syncingFromTop = true;
        tableScroll.scrollLeft = topScroll.scrollLeft;
        requestAnimationFrame(function () {
            syncingFromTop = false;
        });
    });

    tableScroll.addEventListener('scroll', function () {
        if (syncingFromTop) return;
        syncingFromTable = true;
        topScroll.scrollLeft = tableScroll.scrollLeft;
        requestAnimationFrame(function () {
            syncingFromTable = false;
        });
    });

    window.addEventListener('resize', refreshTopScrollbar);
    window.addEventListener('load', refreshTopScrollbar);
    document.addEventListener('DOMContentLoaded', refreshTopScrollbar);
    setTimeout(refreshTopScrollbar, 100);
})();
</script>

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