@extends('dashboard.app')

@section('title', 'My Keywords')
@section('page_title', 'My Keywords')
@section('page_subtitle', 'Manage your private emoji keywords and language tags.')

@section('dashboard_content')
@php
    $user = $user ?? auth()->user();
    $isPersonal = $user && (string) $user->tier === 'personal';
    $freeLimit = $freeLimit ?? null;
    $activeCount = (int) ($activeCount ?? $items->where('is_active', true)->count());
    $limitReached = $freeLimit !== null && $activeCount >= $freeLimit;
    $emojiLookup = $emojiLookup ?? [];
@endphp

@if (session('status'))
    <div class="mb-6 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700 dark:border-emerald-500/30 dark:bg-emerald-500/15 dark:text-emerald-200">
        {{ session('status') }}
    </div>
@endif
@if ($errors->any())
    <div class="mb-6 rounded-2xl border border-amber-300/40 bg-amber-400/10 px-4 py-3 text-sm text-amber-200">
        {{ $errors->first() }}
    </div>
@endif

<div class="rounded-3xl glass-card p-6">
    <div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
        <div>
            <div class="text-xs uppercase tracking-[0.25em] text-gray-400">Keyword library</div>
            <div class="mt-2 text-xl font-semibold text-white">{{ $isPersonal ? 'Ready to personalize' : 'Free plan keywords' }}</div>
            <p class="mt-2 text-sm text-gray-400">Add keywords to emojis to improve your personal search results.</p>
            @if (!$isPersonal && $freeLimit)
                <p class="mt-1 text-xs text-gray-500">Free active limit: {{ $activeCount }} / {{ $freeLimit }} keywords. Inactive keywords are stored but not used in search.</p>
            @endif
        </div>
        <div class="flex flex-wrap items-center gap-2">
            <button id="add-keyword-btn" class="rounded-full bg-brand-ocean text-white force-white font-semibold px-4 py-2 text-sm {{ $limitReached ? 'opacity-50 cursor-not-allowed' : '' }}" {{ $limitReached ? 'disabled' : '' }}>
                + Add Keyword
            </button>
            <button id="import-btn" class="rounded-full border border-white/10 px-4 py-2 text-sm text-gray-200 hover:bg-white/5 {{ $limitReached ? 'opacity-50 cursor-not-allowed' : '' }}" {{ $limitReached ? 'disabled' : '' }}>
                Import JSON
            </button>
            <a href="{{ route('dashboard.keywords.export') }}" class="rounded-full border border-white/10 px-4 py-2 text-sm text-gray-200 hover:bg-white/5">
                Export JSON
            </a>
            <div class="relative">
                <input id="keyword-search" type="text" placeholder="Search keywords..." class="rounded-full bg-white/5 border border-white/10 px-4 py-2 text-sm text-gray-200 focus:outline-none focus:border-brand-ocean">
            </div>
        </div>
    </div>

    @if (!$isPersonal && $freeLimit)
        <div class="mt-6 rounded-2xl border border-brand-sun/30 bg-brand-sun/10 p-4 text-sm text-brand-sun">
            Free plan allows up to {{ $freeLimit }} active keywords. You can keep extras as inactive and reactivate after upgrading.
        </div>
    @endif
    <div class="mt-4 rounded-2xl border border-white/10 bg-white/5 p-4 text-xs text-gray-400">
        Search behavior: only <strong class="text-gray-200">Active</strong> private keywords are used in emoji matching. Inactive keywords stay saved in your account but are ignored by search and API results.
    </div>

    <div id="import-panel" class="mt-6 hidden rounded-2xl border border-white/10 bg-white/5 p-5">
        <form method="POST" action="{{ route('dashboard.keywords.import') }}" enctype="multipart/form-data" class="grid gap-3 md:grid-cols-2">
            @csrf
            <div class="space-y-2">
                <label class="text-xs uppercase tracking-[0.2em] text-gray-400">JSON file</label>
                <input type="file" name="file" accept="application/json" class="block w-full text-sm text-gray-200 file:mr-4 file:rounded-full file:border-0 file:bg-brand-ocean file:px-4 file:py-2 file:text-sm file:font-semibold file:text-white hover:file:bg-brand-oceanSoft" {{ $limitReached ? 'disabled' : '' }}>
            </div>
            <div class="space-y-2">
                <label class="text-xs uppercase tracking-[0.2em] text-gray-400">Or paste JSON</label>
                <textarea name="payload" rows="4" class="w-full rounded-2xl bg-black/30 border border-white/10 px-4 py-3 text-sm text-gray-200 focus:outline-none focus:border-brand-ocean" placeholder='[{"emoji_slug":"sparkles","keyword":"magic","lang":"en"}]'></textarea>
            </div>
            <div class="md:col-span-2 flex items-center justify-end gap-2">
                <button type="button" id="import-cancel" class="rounded-full border border-white/10 px-4 py-2 text-sm text-gray-200 hover:bg-white/5">Cancel</button>
                <button type="submit" class="rounded-full bg-brand-ocean text-white force-white font-semibold px-5 py-2 text-sm" {{ $limitReached ? 'disabled' : '' }}>Import</button>
            </div>
        </form>
    </div>

    <div class="mt-6 overflow-hidden rounded-2xl border border-white/10">
        <table class="min-w-full text-sm text-gray-300">
            <thead class="bg-white/5 text-xs uppercase tracking-[0.2em] text-gray-400">
                <tr>
                    <th class="px-4 py-3 text-left">Emoji</th>
                    <th class="px-4 py-3 text-left">Keyword</th>
                    <th class="px-4 py-3 text-left">Language</th>
                    <th class="px-4 py-3 text-left">Status</th>
                    <th class="hidden px-4 py-3 text-right md:table-cell">Actions</th>
                </tr>
            </thead>
            <tbody id="keyword-table">
                @forelse ($items as $item)
                    <tr class="border-t border-white/5 keyword-row" data-keyword="{{ strtolower($item->keyword) }}" data-slug="{{ strtolower($item->emoji_slug) }}">
                        @php
                            $lookup = $emojiLookup[$item->emoji_slug] ?? null;
                        @endphp
                        <td class="px-4 py-3">
                            <div class="flex items-center gap-3">
                                <span class="text-xl">{{ $lookup['emoji'] ?? '⬚' }}</span>
                                <div>
                                    <div class="text-sm text-white">{{ $lookup['name'] ?? $item->emoji_slug }}</div>
                                    <div class="text-xs text-gray-500">{{ $item->emoji_slug }}</div>
                                </div>
                            </div>
                        </td>
                        <td class="px-4 py-3 font-semibold text-white">
                            {{ $item->keyword }}
                            @php
                                $isActiveMobile = (bool) ($item->is_active ?? true);
                                $canActivateMobile = $isActiveMobile || $isPersonal || !$limitReached;
                            @endphp
                            <div class="mt-3 flex flex-wrap gap-2 md:hidden">
                                <button
                                    type="button"
                                    class="edit-btn rounded-full border border-white/10 px-3 py-1.5 text-xs text-gray-200 hover:bg-white/10"
                                    data-id="{{ $item->id }}"
                                    data-emoji="{{ $item->emoji_slug }}"
                                    data-keyword="{{ $item->keyword }}"
                                    data-lang="{{ $item->lang }}"
                                >
                                    Edit
                                </button>
                                <form method="POST" action="{{ route('dashboard.keywords.toggle_active', $item->id) }}" class="inline">
                                    @csrf
                                    @method('PUT')
                                    <input type="hidden" name="is_active" value="{{ $isActiveMobile ? '0' : '1' }}">
                                    <button
                                        type="submit"
                                        class="rounded-full border border-white/10 px-3 py-1.5 text-xs text-gray-200 hover:bg-white/10 {{ (!$canActivateMobile && !$isActiveMobile) ? 'opacity-50 cursor-not-allowed' : '' }}"
                                        {{ (!$canActivateMobile && !$isActiveMobile) ? 'disabled' : '' }}
                                    >
                                        {{ $isActiveMobile ? 'Deactivate' : 'Activate' }}
                                    </button>
                                </form>
                                <form method="POST" action="{{ route('dashboard.keywords.delete', $item->id) }}" class="inline">
                                    @csrf
                                    @method('DELETE')
                                    <button type="submit" class="rounded-full border border-white/10 px-3 py-1.5 text-xs text-gray-200 hover:bg-white/10">
                                        Delete
                                    </button>
                                </form>
                            </div>
                        </td>
                        <td class="px-4 py-3 text-xs uppercase tracking-[0.15em] text-gray-400">{{ $item->lang ?? 'und' }}</td>
                        <td class="px-4 py-3">
                            @php
                                $isActive = (bool) ($item->is_active ?? true);
                                $canActivate = $isActive || $isPersonal || !$limitReached;
                            @endphp
                            <span class="rounded-full px-3 py-1 text-xs font-semibold {{ $isActive ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-500/20 dark:text-emerald-200' : 'bg-slate-100 text-slate-700 dark:bg-slate-500/20 dark:text-slate-200' }}">
                                {{ $isActive ? 'Active' : 'Inactive' }}
                            </span>
                        </td>
                        <td class="hidden px-4 py-3 text-right md:table-cell">
                            <button
                                type="button"
                                class="edit-btn rounded-full border border-white/10 px-3 py-1 text-xs text-gray-200 hover:bg-white/10"
                                data-id="{{ $item->id }}"
                                data-emoji="{{ $item->emoji_slug }}"
                                data-keyword="{{ $item->keyword }}"
                                data-lang="{{ $item->lang }}"
                                >
                                Edit
                            </button>
                            <form method="POST" action="{{ route('dashboard.keywords.toggle_active', $item->id) }}" class="inline">
                                @csrf
                                @method('PUT')
                                <input type="hidden" name="is_active" value="{{ $isActive ? '0' : '1' }}">
                                <button
                                    type="submit"
                                    class="rounded-full border border-white/10 px-3 py-1 text-xs text-gray-200 hover:bg-white/10 {{ (!$canActivate && !$isActive) ? 'opacity-50 cursor-not-allowed' : '' }}"
                                    {{ (!$canActivate && !$isActive) ? 'disabled' : '' }}
                                >
                                    {{ $isActive ? 'Deactivate' : 'Activate' }}
                                </button>
                            </form>
                            <form method="POST" action="{{ route('dashboard.keywords.delete', $item->id) }}" class="inline">
                                @csrf
                                @method('DELETE')
                                <button type="submit" class="rounded-full border border-white/10 px-3 py-1 text-xs text-gray-200 hover:bg-white/10">
                                    Delete
                                </button>
                            </form>
                        </td>
                    </tr>
                @empty
                    <tr>
                        <td colspan="5" class="px-4 py-8 text-center text-sm text-gray-500">No keywords yet.</td>
                    </tr>
                @endforelse
            </tbody>
        </table>
    </div>
</div>

<div id="keyword-modal" class="hidden fixed inset-0 z-[90] items-center justify-center">
    <div class="absolute inset-0 bg-black/70 backdrop-blur-sm"></div>
    <div class="relative z-10 w-full max-w-lg rounded-3xl glass-card theme-surface p-6">
        <div class="flex items-center justify-between">
            <h3 class="text-lg font-semibold text-slate-900 dark:text-white" id="keyword-modal-title">Add keyword</h3>
            <button id="keyword-modal-close" class="w-8 h-8 rounded-full bg-slate-100 hover:bg-slate-200 dark:bg-white/10 dark:hover:bg-white/20 flex items-center justify-center text-slate-600 dark:text-gray-200">
                <i data-lucide="x" class="w-4 h-4"></i>
            </button>
        </div>
        <form id="keyword-form" method="POST" action="{{ route('dashboard.keywords.store') }}" class="mt-4 grid gap-4">
            @csrf
            <input type="hidden" name="_method" id="keyword-form-method" value="POST">
            <div>
                <label class="text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-gray-400">Emoji</label>
                <input type="hidden" name="emoji_slug" id="keyword-emoji" required>
                <div class="relative mt-2">
                    <input type="text" id="keyword-emoji-combo" autocomplete="off" class="w-full rounded-xl bg-white border border-slate-300 px-4 py-3 text-sm text-slate-900 placeholder-slate-400 focus:outline-none focus:border-brand-ocean dark:bg-black/40 dark:border-white/10 dark:text-gray-200 dark:placeholder-gray-500" placeholder="Search emoji (e.g. sparkles)" required>
                    <div id="keyword-emoji-menu" class="hidden absolute left-0 right-0 mt-2 max-h-56 overflow-y-auto rounded-xl border border-slate-200 bg-white shadow-xl z-[100] dark:border-white/10 dark:bg-[#0b0b0f]"></div>
                </div>
            </div>
            <div>
                <label class="text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-gray-400">Keyword</label>
                <input type="text" name="keyword" id="keyword-text" class="mt-2 w-full rounded-xl bg-white border border-slate-300 px-4 py-3 text-sm text-slate-900 placeholder-slate-400 focus:outline-none focus:border-brand-ocean dark:bg-black/40 dark:border-white/10 dark:text-gray-200 dark:placeholder-gray-500" placeholder="magic" required>
            </div>
            <div>
                <label class="text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-gray-400">Language</label>
                <input type="hidden" name="lang" id="keyword-lang" value="und">
                <div class="relative mt-2">
                    <input type="text" id="keyword-lang-combo" autocomplete="off" class="w-full rounded-xl bg-white border border-slate-300 px-4 py-3 text-sm text-slate-900 placeholder-slate-400 focus:outline-none focus:border-brand-ocean dark:bg-black/40 dark:border-white/10 dark:text-gray-200 dark:placeholder-gray-500" placeholder="Search language (e.g. Indonesian)">
                    <div id="keyword-lang-menu" class="hidden absolute left-0 right-0 mt-2 max-h-56 overflow-y-auto rounded-xl border border-slate-200 bg-white shadow-xl z-[100] dark:border-white/10 dark:bg-[#0b0b0f]"></div>
                </div>
                <select id="keyword-lang-source" class="hidden">
                    @include('partials.language-datalist')
                </select>
            </div>
            <div class="flex items-center justify-end gap-2">
                <button type="button" id="keyword-cancel" class="rounded-full border border-slate-300 px-4 py-2 text-sm text-slate-700 hover:bg-slate-100 dark:border-white/10 dark:text-gray-200 dark:hover:bg-white/5">Cancel</button>
                <button type="submit" class="rounded-full bg-brand-ocean text-white force-white font-semibold px-5 py-2 text-sm">Save keyword</button>
            </div>
        </form>
    </div>
</div>
@endsection

@push('scripts')
<script>
(() => {
    const isPersonal = @json($isPersonal);
    const limitReached = @json($limitReached);
    const modal = document.getElementById('keyword-modal');
    const modalTitle = document.getElementById('keyword-modal-title');
    const openBtn = document.getElementById('add-keyword-btn');
    const closeBtn = document.getElementById('keyword-modal-close');
    const cancelBtn = document.getElementById('keyword-cancel');
    const form = document.getElementById('keyword-form');
    const methodEl = document.getElementById('keyword-form-method');
    const emojiEl = document.getElementById('keyword-emoji');
    const emojiComboEl = document.getElementById('keyword-emoji-combo');
    const emojiMenuEl = document.getElementById('keyword-emoji-menu');
    const textEl = document.getElementById('keyword-text');
    const langEl = document.getElementById('keyword-lang');
    const langComboEl = document.getElementById('keyword-lang-combo');
    const langMenuEl = document.getElementById('keyword-lang-menu');
    const langSourceEl = document.getElementById('keyword-lang-source');
    const searchEl = document.getElementById('keyword-search');
    const importBtn = document.getElementById('import-btn');
    const importPanel = document.getElementById('import-panel');
    const importCancel = document.getElementById('import-cancel');

    window.dewemojiPopulateLanguageSelect?.(langSourceEl);
    const canonicalizeLanguageCode = (raw) => window.dewemojiCanonicalLanguageCode?.(raw) || String(raw || '').trim().toLowerCase();
    const emojiLookup = @json($emojiLookup);
    const emojiSearchUrl = @json(route('dashboard.keywords.search'));
    const publicEmojiSearchUrl = @json(url('/v1/emojis'));

    const DEFAULT_LANGUAGE_CODE = 'en';
    const UNDETERMINED_LANGUAGE_CODE = 'und';
    const emojiItems = Object.entries(emojiLookup || {}).map(([slug, item]) => {
        const name = String(item?.name || slug);
        const glyph = String(item?.emoji || '');
        const label = `${glyph ? `${glyph} ` : ''}${name}`;
        return {
            slug,
            name,
            glyph,
            label,
            search: `${slug} ${name} ${glyph}`.toLowerCase(),
        };
    }).sort((a, b) => a.name.localeCompare(b.name));
    const emojiBySlug = new Map(emojiItems.map((item) => [item.slug.toLowerCase(), item]));
    let remoteEmojiItems = [];
    let remoteEmojiSearched = false;
    let emojiQueryToken = 0;
    let emojiSearchTimer = null;
    let emojiSearchAbort = null;

    const languageItems = Array.from(langSourceEl?.options || []).map((option) => ({
        code: option.value,
        label: option.text,
    }));
    const labelByCode = new Map(languageItems.map((item) => [item.code.toLowerCase(), item.label]));
    const itemByCode = new Map(languageItems.map((item) => [item.code.toLowerCase(), item]));

    const renderLanguageMenu = (query = '') => {
        if (!langMenuEl) return;
        const q = query.trim().toLowerCase();
        const filtered = languageItems.filter((item) => item.label.toLowerCase().includes(q));
        langMenuEl.innerHTML = filtered.map((item) => {
            const selected = langEl.value === item.code;
            return `<button type="button" data-code="${item.code}" class="w-full text-left px-3 py-2 text-sm ${selected ? 'bg-brand-ocean/10 text-brand-ocean dark:text-brand-oceanSoft' : 'text-slate-700 hover:bg-slate-100 dark:text-gray-200 dark:hover:bg-white/10'}">${item.label}</button>`;
        }).join('') || '<div class="px-3 py-2 text-sm text-slate-500 dark:text-gray-400">No matches</div>';
    };

    const openLanguageMenu = () => {
        renderLanguageMenu(langComboEl.value);
        langMenuEl.classList.remove('hidden');
    };

    const closeLanguageMenu = () => {
        langMenuEl.classList.add('hidden');
    };

    const setLanguageByCode = (code, { silentInput = false } = {}) => {
        const value = canonicalizeLanguageCode(code || UNDETERMINED_LANGUAGE_CODE) || UNDETERMINED_LANGUAGE_CODE;
        langEl.value = value;
        if (silentInput || value.toLowerCase() === UNDETERMINED_LANGUAGE_CODE) {
            langComboEl.value = '';
            return;
        }
        langComboEl.value = labelByCode.get(value.toLowerCase()) || value;
    };

    const resolveLanguageCode = (raw) => {
        const value = (raw || '').trim();
        if (!value) return UNDETERMINED_LANGUAGE_CODE;
        const byCode = itemByCode.get(canonicalizeLanguageCode(value));
        if (byCode) return byCode.code;
        const byLabel = languageItems.find((item) => item.label.toLowerCase() === value.toLowerCase());
        if (byLabel) return canonicalizeLanguageCode(byLabel.code);
        return UNDETERMINED_LANGUAGE_CODE;
    };

    const renderEmojiMenu = (query = '') => {
        if (!emojiMenuEl) return;
        const q = query.trim().toLowerCase();
        const useRemote = q.length >= 2 && remoteEmojiSearched;
        const filtered = useRemote
            ? remoteEmojiItems.slice(0, 80)
            : emojiItems.filter((item) => !q || item.search.includes(q)).slice(0, 80);
        emojiMenuEl.innerHTML = filtered.map((item) => {
            const selected = emojiEl.value === item.slug;
            const glyph = item.glyph || '&nbsp;';
            return `<button type="button" data-slug="${item.slug}" class="w-full text-left px-3 py-2 text-sm ${selected ? 'bg-brand-ocean/10 text-brand-ocean dark:text-brand-oceanSoft' : 'text-slate-700 hover:bg-slate-100 dark:text-gray-200 dark:hover:bg-white/10'}"><span class="inline-flex items-center gap-2"><span class="inline-flex w-6 shrink-0 justify-center">${glyph}</span><span class="truncate">${item.name}</span></span></button>`;
        }).join('') || '<div class="px-3 py-2 text-sm text-slate-500 dark:text-gray-400">No matches</div>';
    };

    const mapApiItemsToEmojiItems = (items) => (items || []).map((item) => {
        const slug = String(item?.slug || '').trim();
        if (!slug) return null;
        const existing = emojiBySlug.get(slug.toLowerCase());
        const name = String(item?.name || existing?.name || slug);
        const glyph = String(item?.emoji || existing?.glyph || '');
        return {
            slug,
            name,
            glyph,
            label: `${glyph ? `${glyph} ` : ''}${name}`,
            search: `${slug} ${name} ${glyph}`.toLowerCase(),
        };
    }).filter(Boolean);

    const fetchEmojiMenuItems = async (query) => {
        const q = String(query || '').trim();
        if (q.length < 2) {
            remoteEmojiItems = [];
            remoteEmojiSearched = false;
            renderEmojiMenu(q);
            return;
        }

        const token = ++emojiQueryToken;
        if (emojiSearchAbort) {
            emojiSearchAbort.abort();
        }
        emojiSearchAbort = new AbortController();

        const base = emojiSearchUrl;
        const url = `${base}?${new URLSearchParams({ q, limit: '30', page: '1' }).toString()}`;

        try {
            const res = await fetch(url, {
                headers: { 'Accept': 'application/json' },
                signal: emojiSearchAbort.signal,
            });
            const data = await res.json().catch(() => null);
            if (token !== emojiQueryToken) return;
            const items = Array.isArray(data?.items) ? data.items : [];
            remoteEmojiItems = mapApiItemsToEmojiItems(items);
            remoteEmojiSearched = true;
            renderEmojiMenu(q);
        } catch (error) {
            if (error?.name === 'AbortError') return;
            if (token !== emojiQueryToken) return;
            remoteEmojiItems = [];
            remoteEmojiSearched = true;
            renderEmojiMenu(q);
        }
    };

    const scheduleEmojiFetch = (query) => {
        if (emojiSearchTimer) {
            clearTimeout(emojiSearchTimer);
        }
        emojiSearchTimer = setTimeout(() => {
            fetchEmojiMenuItems(query);
        }, 180);
    };

    const openEmojiMenu = () => {
        renderEmojiMenu(emojiComboEl.value);
        emojiMenuEl?.classList.remove('hidden');
        scheduleEmojiFetch(emojiComboEl.value);
    };

    const closeEmojiMenu = () => {
        emojiMenuEl?.classList.add('hidden');
    };

    const setEmojiBySlug = (slug, { keepRaw = false } = {}) => {
        const normalized = String(slug || '').trim().toLowerCase();
        if (!normalized) {
            emojiEl.value = '';
            emojiComboEl.value = '';
            return;
        }
        const item = emojiBySlug.get(normalized);
        if (!item) {
            emojiEl.value = normalized;
            emojiComboEl.value = keepRaw ? String(slug || '') : normalized;
            return;
        }
        emojiEl.value = item.slug;
        emojiComboEl.value = item.label;
    };

    const resolveEmojiSlug = (raw) => {
        const value = String(raw || '').trim().toLowerCase();
        if (!value) return '';
        const exact = emojiBySlug.get(value);
        if (exact) return exact.slug;
        const exactLabel = emojiItems.find((item) => item.label.toLowerCase() === value);
        if (exactLabel) return exactLabel.slug;
        const exactName = emojiItems.find((item) => item.name.toLowerCase() === value);
        if (exactName) return exactName.slug;
        const starts = emojiItems.filter((item) => item.slug.toLowerCase().startsWith(value) || item.name.toLowerCase().startsWith(value));
        if (starts.length === 1) return starts[0].slug;
        return '';
    };

    const openModal = (mode, data = {}) => {
        if (mode === 'add' && limitReached) return;
        modal.classList.remove('hidden');
        modal.classList.add('flex');
        modalTitle.textContent = mode === 'edit' ? 'Edit keyword' : 'Add keyword';
        form.action = mode === 'edit' ? `/dashboard/keywords/${data.id}` : '{{ route('dashboard.keywords.store') }}';
        methodEl.value = mode === 'edit' ? 'PUT' : 'POST';
        setEmojiBySlug(data.emoji || '');
        textEl.value = data.keyword || '';
        const initialLanguage = mode === 'edit'
            ? (data.lang || UNDETERMINED_LANGUAGE_CODE)
            : DEFAULT_LANGUAGE_CODE;
        setLanguageByCode(initialLanguage, { silentInput: initialLanguage.toLowerCase() === UNDETERMINED_LANGUAGE_CODE });
        closeLanguageMenu();
        emojiComboEl.focus();
    };

    const closeModal = () => {
        modal.classList.add('hidden');
        modal.classList.remove('flex');
    };

    openBtn?.addEventListener('click', () => openModal('add'));
    closeBtn?.addEventListener('click', closeModal);
    cancelBtn?.addEventListener('click', closeModal);
    modal?.addEventListener('click', (e) => {
        if (e.target === modal) closeModal();
    });

    emojiComboEl?.addEventListener('focus', openEmojiMenu);
    emojiComboEl?.addEventListener('input', () => {
        openEmojiMenu();
        scheduleEmojiFetch(emojiComboEl.value);
    });
    emojiComboEl?.addEventListener('blur', () => {
        const nextSlug = resolveEmojiSlug(emojiComboEl.value);
        setEmojiBySlug(nextSlug);
        setTimeout(closeEmojiMenu, 120);
    });
    emojiMenuEl?.addEventListener('mousedown', (event) => {
        const button = event.target.closest('button[data-slug]');
        if (!button) return;
        event.preventDefault();
        setEmojiBySlug(button.dataset.slug);
        closeEmojiMenu();
    });

    langComboEl?.addEventListener('focus', openLanguageMenu);
    langComboEl?.addEventListener('input', openLanguageMenu);
    langComboEl?.addEventListener('blur', () => {
        const nextCode = resolveLanguageCode(langComboEl.value);
        setLanguageByCode(nextCode, { silentInput: nextCode.toLowerCase() === UNDETERMINED_LANGUAGE_CODE });
        setTimeout(closeLanguageMenu, 120);
    });
    langMenuEl?.addEventListener('mousedown', (event) => {
        const button = event.target.closest('button[data-code]');
        if (!button) return;
        event.preventDefault();
        setLanguageByCode(button.dataset.code);
        closeLanguageMenu();
    });

    document.querySelectorAll('.edit-btn').forEach((btn) => {
        btn.addEventListener('click', () => {
            openModal('edit', {
                id: btn.dataset.id,
                emoji: btn.dataset.emoji,
                keyword: btn.dataset.keyword,
                lang: btn.dataset.lang,
            });
        });
    });

    form?.addEventListener('submit', (event) => {
        const slug = resolveEmojiSlug(emojiComboEl?.value || emojiEl?.value || '');
        if (!slug) {
            event.preventDefault();
            alert('Please select a valid emoji from the dropdown.');
            emojiComboEl?.focus();
            openEmojiMenu();
            return;
        }
        setEmojiBySlug(slug);
    });

    if (searchEl) {
        searchEl.addEventListener('input', () => {
            const value = searchEl.value.trim().toLowerCase();
            document.querySelectorAll('.keyword-row').forEach((row) => {
                const match = row.dataset.keyword?.includes(value) || row.dataset.slug?.includes(value);
                row.classList.toggle('hidden', value && !match);
            });
        });
    }

    importBtn?.addEventListener('click', () => {
        if (!isPersonal) return;
        importPanel.classList.remove('hidden');
    });
    importCancel?.addEventListener('click', () => {
        importPanel.classList.add('hidden');
    });

    if (window.location.hash === '#add') {
        openModal('add');
    }
    window.addEventListener('hashchange', () => {
        if (window.location.hash === '#add') {
            openModal('add');
        }
    });
})();
</script>
@endpush
