@extends('site.layout')

@section('title', ($emoji['name'] ?? 'Emoji').' - Dewemoji')
@section('meta_description', ($emoji['description'] ?? 'Emoji detail').' Discover meaning, keywords, and copy-ready formats on Dewemoji.')

@php
    $name = $emoji['name'] ?? '';
    $category = $emoji['category'] ?? '';
    $subcategory = $emoji['subcategory'] ?? '';
    $symbol = $emoji['emoji'] ?? '';
    $slug = $emoji['slug'] ?? '';
    $description = $emoji['description'] ?? '';
    $unified = $emoji['unified'] ?? '';
    $shortcode = $emoji['shortcodes'][0] ?? '';
    $supportsTone = (bool) ($emoji['supports_skin_tone'] ?? false);
    $emojiBase = $symbol;
    if ($supportsTone && $symbol !== '') {
        $emojiBase = preg_replace('/\x{1F3FB}|\x{1F3FC}|\x{1F3FD}|\x{1F3FE}|\x{1F3FF}/u', '', $symbol) ?: $symbol;
    }
    $toneVariants = $supportsTone
        ? [
            'light' => $emojiBase."\u{1F3FB}",
            'medium-light' => $emojiBase."\u{1F3FC}",
            'medium' => $emojiBase."\u{1F3FD}",
            'medium-dark' => $emojiBase."\u{1F3FE}",
            'dark' => $emojiBase."\u{1F3FF}",
        ]
        : [];
    $user = auth()->user();
    $userTier = $userTier ?? $user?->tier;
    $isPersonal = $userTier === 'personal';
    $userKeywords = $userKeywords ?? collect();
    $activeKeywordCount = (int) ($activeKeywordCount ?? $userKeywords->where('is_active', true)->count());
    $htmlHex = '';
    $cssCode = '';
    if (!empty($emoji['codepoints'][0])) {
        $hex = strtoupper($emoji['codepoints'][0]);
        $htmlHex = '&#x'.$hex.';';
        $cssCode = '\\'.$hex;
    }
    $related = $relatedDetails ?? [];
    $keywords = array_slice($emoji['keywords_en'] ?? [], 0, 16);
@endphp

@push('jsonld')
<script type="application/ld+json">
{
  "@@context": "https://schema.org",
  "@@graph": [
    {
      "@@type": "CreativeWork",
      "name": @json($name),
      "description": @json($description),
      "url": @json(url('/emoji/'.$slug))
    },
    {
      "@@type": "BreadcrumbList",
      "itemListElement": [
        {"@@type":"ListItem","position":1,"name":"Home","item":@json(url('/'))},
        {"@@type":"ListItem","position":2,"name":"Emoji","item":@json(url('/browse'))},
        {"@@type":"ListItem","position":3,"name":@json($name),"item":@json(url('/emoji/'.$slug))}
      ]
    }
  ]
}
</script>
@endpush

@section('content')
<div class="flex h-screen">
    <aside class="hidden lg:flex w-20 lg:w-64 h-full glass-panel flex-col justify-between p-4 z-20">
        <div>
            <div class="flex items-center gap-3 px-2 mb-10 mt-2">
                <div class="w-10 h-10 rounded-xl bg-gradient-to-br from-white to-gray-300 flex items-center justify-center shadow-lg shadow-white/20">
                    <img src="/assets/logo/logo-mark.svg" alt="Dewemoji logo" class="w-7 h-7 object-contain" />
                </div>
                <h1 class="font-display font-bold text-lg tracking-tight hidden lg:block">Dewemoji</h1>
            </div>
            <nav class="space-y-2">
                <a href="{{ route('home') }}" class="flex items-center gap-4 px-3 py-3 rounded-xl text-gray-300 hover:text-white hover:bg-white/5 transition-all group">
                    <i data-lucide="arrow-left" class="w-5 h-5 text-brand-sun"></i>
                    <span class="text-sm font-medium hidden lg:block text-brand-sun">Back</span>
                </a>
            </nav>
        </div>
    </aside>

    <main class="flex-1 h-full overflow-y-auto relative p-4 pt-0 sm:p-6 lg:p-10 pb-24 lg:pb-10 flex flex-col">
        <div class="sticky top-0 z-40 -mx-4 px-4 py-3 mb-6 bg-[var(--app-bg)]/90 backdrop-blur border-b border-white/10 sm:static sm:mx-0 sm:px-0 sm:py-0 sm:mb-8 sm:border-0">
            <div class="flex items-center justify-between">
                <div class="flex items-center gap-2 text-xs sm:text-sm text-gray-500 font-mono">
                    <button type="button" onclick="window.history.length > 1 ? window.history.back() : (window.location.href='{{ route('home') }}')" class="inline-flex sm:hidden w-8 h-8 rounded-full bg-white/5 border border-white/10 items-center justify-center text-gray-300 hover:text-white">
                        <i data-lucide="arrow-left" class="w-4 h-4"></i>
                    </button>
                    <a href="{{ route('home') }}" class="hover:text-white transition-colors">Home</a>
                    <i data-lucide="chevron-right" class="w-3 h-3"></i>
                    <span class="hidden sm:inline-flex hover:text-white">{{ $category }}</span>
                    <i data-lucide="chevron-right" class="w-3 h-3 hidden sm:inline-flex"></i>
                    <span class="text-brand-sun">{{ $name }}</span>
                </div>
                <button id="theme-toggle" class="w-9 h-9 rounded-full theme-surface border border-white/10 shadow-lg flex items-center justify-center text-gray-300 hover:text-white transition-colors">
                    <span class="sr-only">Toggle theme</span>
                    <i data-lucide="moon" class="w-4 h-4" data-theme-icon="dark"></i>
                    <i data-lucide="sun" class="w-4 h-4 hidden" data-theme-icon="light"></i>
                </button>
            </div>
        </div>

        <div class="grid grid-cols-1 lg:grid-cols-12 gap-8 max-w-6xl mx-auto w-full">
            <div class="lg:col-span-5 flex flex-col gap-6">
                <div class="glass-card rounded-[32px] aspect-square flex items-center justify-center relative overflow-hidden group">
                    <div class="absolute w-64 h-64 bg-yellow-500/20 rounded-full blur-3xl group-hover:bg-yellow-500/30 transition-colors duration-500"></div>
                    <div id="emoji-hero-symbol" class="text-[140px] md:text-[180px] leading-none select-none relative z-10 animate-float drop-shadow-2xl">{{ $symbol }}</div>
                    <div class="absolute bottom-6 flex gap-3 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-all transform translate-y-0 sm:translate-y-2 sm:group-hover:translate-y-0">
                        <button id="favorite-toggle-btn" type="button" class="w-12 h-12 bg-black/50 backdrop-blur text-white force-white rounded-full hover:bg-yellow-400/20 transition-colors border border-white/10 inline-flex items-center justify-center shrink-0" title="Add Favorite" aria-label="Add Favorite">
                            <span id="favorite-toggle-icon" class="text-yellow-300 text-lg leading-none">☆</span>
                            <span id="favorite-toggle-label" class="sr-only">Add Favorite</span>
                        </button>
                        <button onclick="copyCurrentEmoji()" class="w-12 h-12 bg-black/50 backdrop-blur text-white force-white rounded-full hover:bg-brand-sun hover:text-black transition-colors border border-white/10 inline-flex items-center justify-center shrink-0" title="Copy">
                            <i data-lucide="copy" class="w-5 h-5 force-white"></i>
                        </button>
                    </div>
                </div>

                @if(count($related) > 0)
                    <div class="glass-card rounded-2xl p-5">
                        <h3 class="text-xs font-bold text-gray-500 uppercase tracking-wider mb-4">Related</h3>
                        <div class="flex gap-2 overflow-x-auto pb-2">
                            @foreach($related as $item)
                                <div class="relative group">
                                    @if(!empty($item['slug']))
                                        <a
                                            href="{{ route('emoji-detail', ['slug' => $item['slug']]) }}"
                                            class="w-12 h-12 rounded-lg bg-white/5 hover:bg-white/10 flex items-center justify-center text-2xl transition-colors"
                                            title="{{ $item['name'] }}"
                                        >{{ $item['emoji'] }}</a>
                                    @else
                                        <div class="w-12 h-12 rounded-lg bg-white/5 flex items-center justify-center text-2xl">{{ $item['emoji'] }}</div>
                                    @endif
                                    <button
                                        type="button"
                                        onclick="copyToClipboard('{{ $item['emoji'] }}'); event.preventDefault(); event.stopPropagation();"
                                        class="absolute -bottom-1 -right-1 w-5 h-5 rounded bg-black/70 border border-white/10 text-[10px] text-white force-white hover:bg-brand-ocean/40"
                                        title="Copy {{ $item['name'] }}"
                                    >⧉</button>
                                </div>
                            @endforeach
                        </div>
                    </div>
                @endif
            </div>

            <div class="lg:col-span-7 flex flex-col gap-6">
                <div>
                    <div class="flex items-center gap-3 mb-2">
                        <span class="bg-yellow-500/10 text-yellow-400 border border-yellow-500/20 px-3 py-1 rounded-full text-xs font-bold uppercase">{{ $subcategory }}</span>
                        <span id="favorite-pill" class="hidden bg-yellow-500/10 text-yellow-300 border border-yellow-500/30 px-3 py-1 rounded-full text-xs font-bold uppercase">Favorite</span>
                    </div>
                    <h1 class="font-display text-5xl font-bold mb-4">{{ $name }}</h1>
                    <p class="text-gray-400 text-lg leading-relaxed">{{ $description }}</p>
                </div>

                @if($supportsTone)
                    <div id="tone-panel" class="glass-card rounded-xl p-3">
                        <div class="text-xs font-mono text-gray-500 mb-2">Skin tone</div>
                        <div class="flex flex-wrap gap-2">
                            <button type="button" data-tone="off" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">Default</button>
                            <button type="button" data-tone="light" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">🏻</button>
                            <button type="button" data-tone="medium-light" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">🏼</button>
                            <button type="button" data-tone="medium" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">🏽</button>
                            <button type="button" data-tone="medium-dark" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">🏾</button>
                            <button type="button" data-tone="dark" class="tone-chip px-3 py-1.5 rounded-lg border border-white/10 text-sm text-gray-200 bg-white/5 hover:bg-white/10">🏿</button>
                        </div>
                    </div>
                @endif

                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    @if($shortcode !== '')
                        <button onclick="copyToClipboard('{{ $shortcode }}')" class="glass-card p-4 rounded-xl group text-left">
                            <div class="flex justify-between items-start mb-1">
                                <span class="text-xs font-mono text-gray-500">Shortcode</span>
                                <i data-lucide="copy" class="w-3 h-3 text-gray-600 group-hover:text-brand-oceanSoft transition-colors"></i>
                            </div>
                            <div class="font-mono text-brand-sun group-hover:text-brand-sunSoft font-medium truncate">{{ $shortcode }}</div>
                        </button>
                    @endif

                    @if($unified !== '')
                        <button onclick="copyToClipboard('{{ $unified }}')" class="glass-card p-4 rounded-xl group text-left">
                            <div class="flex justify-between items-start mb-1">
                                <span class="text-xs font-mono text-gray-500">Unicode</span>
                                <i data-lucide="copy" class="w-3 h-3 text-gray-600 group-hover:text-brand-oceanSoft transition-colors"></i>
                            </div>
                            <div class="font-mono text-gray-300 group-hover:text-white font-medium">{{ $unified }}</div>
                        </button>
                    @endif

                    @if($htmlHex !== '')
                        <button onclick="copyToClipboard('{{ $htmlHex }}')" class="glass-card p-4 rounded-xl group text-left">
                            <div class="flex justify-between items-start mb-1">
                                <span class="text-xs font-mono text-gray-500">HTML Entity</span>
                                <i data-lucide="copy" class="w-3 h-3 text-gray-600 group-hover:text-brand-oceanSoft transition-colors"></i>
                            </div>
                            <div class="font-mono text-gray-400 group-hover:text-white font-medium truncate">{{ $htmlHex }}</div>
                        </button>
                    @endif

                    @if($cssCode !== '')
                        <button onclick="copyToClipboard('{{ $cssCode }}')" class="glass-card p-4 rounded-xl group text-left">
                            <div class="flex justify-between items-start mb-1">
                                <span class="text-xs font-mono text-gray-500">CSS Content</span>
                                <i data-lucide="copy" class="w-3 h-3 text-gray-600 group-hover:text-brand-oceanSoft transition-colors"></i>
                            </div>
                            <div class="font-mono text-gray-400 group-hover:text-white font-medium">{{ $cssCode }}</div>
                        </button>
                    @endif
                </div>

                @if(count($keywords) > 0)
                    <div class="mt-2">
                        <div class="flex items-center gap-2 mb-4">
                            <i data-lucide="hash" class="w-4 h-4 text-brand-sun"></i>
                            <h3 class="text-sm font-bold text-gray-200 uppercase tracking-wide">Semantic Tags</h3>
                        </div>
                        <div class="flex flex-wrap gap-2">
                            @foreach($keywords as $tag)
                                <a href="{{ route('home') }}?q={{ urlencode($tag) }}" class="px-3 py-1.5 rounded-lg bg-white/5 hover:bg-brand-ocean/10 border border-white/5 hover:border-brand-ocean/30 text-sm text-gray-300 hover:text-brand-oceanSoft transition-all">{{ $tag }}</a>
                            @endforeach
                        </div>
                    </div>
                @endif

                <div class="mt-6 glass-card rounded-2xl p-5">
                    <div class="flex items-center justify-between">
                        <div class="flex items-center gap-2">
                            <i data-lucide="sparkles" class="w-4 h-4 text-brand-ocean"></i>
                            <h3 class="text-sm font-bold text-gray-200 uppercase tracking-wide">Your Keywords</h3>
                        </div>
                        @if ($canManageKeywords)
                            <button id="user-keyword-add" class="rounded-full bg-brand-ocean text-white force-white text-xs font-semibold px-3 py-1.5 {{ $limitReached ? 'opacity-60 cursor-not-allowed' : '' }}" {{ $limitReached ? 'disabled' : '' }}>Add keyword</button>
                        @endif
                    </div>

                    @if ($canManageKeywords)
                        @if (!is_null($keywordLimit))
                            <div class="mt-3 text-xs text-gray-400">
                                Free active limit: {{ $activeKeywordCount }} / {{ $keywordLimit }} keywords.
                            </div>
                        @endif
                        <div id="user-keyword-list" class="mt-4 flex flex-wrap gap-2">
                            @forelse ($userKeywords as $keyword)
                                @php($isKeywordActive = (bool) ($keyword->is_active ?? true))
                                <span
                                    class="user-keyword-pill inline-flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm {{ $isKeywordActive ? 'bg-white/5 border-white/10 text-gray-200' : 'bg-slate-200/10 border-slate-200/20 text-gray-300' }}"
                                    data-id="{{ $keyword->id }}"
                                    data-keyword="{{ $keyword->keyword }}"
                                    data-lang="{{ $keyword->lang ?? 'und' }}"
                                    data-active="{{ $isKeywordActive ? '1' : '0' }}"
                                >
                                    <span>{{ $keyword->keyword }}</span>
                                    <span class="text-[10px] uppercase tracking-[0.2em] text-gray-500">{{ $keyword->lang ?? 'und' }}</span>
                                    @unless($isKeywordActive)
                                        <span class="text-[10px] uppercase tracking-[0.2em] text-amber-400">inactive</span>
                                    @endunless
                                    <button type="button" class="user-keyword-edit rounded-md border border-white/10 px-1.5 py-0.5 text-[10px] text-gray-300 hover:bg-white/10">Edit</button>
                                    <button type="button" class="user-keyword-delete rounded-md border border-white/10 px-1.5 py-0.5 text-[10px] text-gray-300 hover:bg-red-500/20">Delete</button>
                                </span>
                            @empty
                                <span id="user-keyword-empty" class="text-sm text-gray-400">No private keywords yet. Add one to personalize search.</span>
                            @endforelse
                        </div>
                    @else
                        <div class="mt-4 rounded-xl border border-white/10 bg-white/5 p-3 text-sm text-gray-300">
                            Sign up to personalize keywords and sync across devices.
                        </div>
                        <a href="{{ route('register') }}" class="mt-3 inline-flex items-center justify-center rounded-full bg-brand-sun text-black font-semibold px-4 py-2 text-sm">Sign up free</a>
                    @endif
                </div>

            </div>
        </div>

        <footer class="mt-auto pt-10 text-center text-gray-600 text-xs">Dewemoji Native • Press 'C' to copy</footer>
    </main>
</div>


<div id="toast" class="fixed left-1/2 -translate-x-1/2 translate-y-24 opacity-0 transition-all duration-300 z-50 pointer-events-none" style="bottom: calc(env(safe-area-inset-bottom, 0px) + 6rem);">
    <div class="bg-brand-ocean text-white px-6 py-2 rounded-full font-bold shadow-[0_0_20px_rgba(32,83,255,0.45)] flex items-center gap-2">
        <i data-lucide="check" class="w-4 h-4"></i>
        <span id="toast-msg">Copied!</span>
    </div>
</div>

<div id="user-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 id="user-keyword-title" class="text-lg font-semibold text-slate-900 dark:text-white">Add keyword</h3>
            <button id="user-keyword-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="user-keyword-form" class="mt-4 grid gap-4">
            <div>
                <label class="text-xs uppercase tracking-[0.2em] text-slate-500 dark:text-gray-400">Keyword</label>
                <input type="text" name="keyword" id="user-keyword-input" 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" id="user-keyword-lang" value="und">
                <div class="relative mt-2">
                    <input type="text" id="user-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="user-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="user-keyword-lang-source" class="hidden">
                    @include('partials.language-datalist')
                </select>
            </div>
            <div class="flex items-center justify-end gap-2">
                <button type="button" id="user-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 id="user-keyword-submit" 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 RECENT_KEY = 'dewemoji_recent';
const FAVORITES_KEY = 'dewemoji_favorites';
const TONE_STORAGE_KEY = 'dewemoji_skin_tone';
const SYMBOL_DEFAULT = @json($symbol);
const DETAIL_SLUG = @json($slug);
const DETAIL_NAME = @json($name);
const DETAIL_CATEGORY = @json($category);
const DETAIL_SUBCATEGORY = @json($subcategory);
const DETAIL_SUPPORTS_TONE = @json($supportsTone);
const DETAIL_VARIANTS_LIST = @json(array_values($toneVariants));
const TONE_VARIANTS = @json($toneVariants);
const TONE_CHAR_BY_SLUG = {
    light: '\u{1F3FB}',
    'medium-light': '\u{1F3FC}',
    medium: '\u{1F3FD}',
    'medium-dark': '\u{1F3FE}',
    dark: '\u{1F3FF}',
};
const TONE_CPS = new Set([0x1F3FB, 0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF]);
const MODIFIABLE_BASES = new Set([
    0x1F9D1, 0x1F468, 0x1F469, 0x1F466, 0x1F467, 0x1F476,
    0x1F575, 0x1F93C, 0x26F9, 0x1F3CB, 0x1F93D, 0x1F93E, 0x1F926,
]);
const NOT_TONEABLE_BASES = new Set([
    0x1F9BE, 0x1F9BF, 0x1FAC0, 0x1F9E0, 0x1FAC1, 0x1F9B7, 0x1F9B4,
    0x1F440, 0x1F441, 0x1F445, 0x1F444, 0x1FAE6,
    0x1F9DE, 0x1F9DF, 0x1F9CC, 0x26F7, 0x1F3C2,
]);
const NON_TONEABLE_NAME_PATTERNS = [
    /\bspeaking head\b/i,
    /\bbust in silhouette\b/i,
    /\bbusts in silhouette\b/i,
    /\bfootprints?\b/i,
    /\bfingerprint\b/i,
    /\bfamily\b/i,
    /\bpeople hugging\b/i,
    /\bpeople with bunny ears\b/i,
    /\bpeople wrestling\b/i,
    /\bpeople fencing\b/i,
    /\bperson fencing\b/i,
    /\bmen wrestling\b/i,
    /\bwomen wrestling\b/i,
    /\bmerman\b/i,
    /\bmermaid\b/i,
    /\bdeaf man\b/i,
    /\bdeaf woman\b/i,
    /\bman: beard\b/i,
    /\bwoman: beard\b/i,
    /\bperson running facing right\b/i,
    /\bperson walking facing right\b/i,
    /\bperson kneeling facing right\b/i,
];
const ROLE_TONEABLE_NAME_PATTERNS = [
    /\btechnologist\b/i,
    /\bscientist\b/i,
    /\boffice worker\b/i,
    /\bfactory worker\b/i,
    /\bmechanic\b/i,
    /\bcook\b/i,
    /\bfarmer\b/i,
    /\bjudge\b/i,
    /\bteacher\b/i,
    /\bstudent\b/i,
    /\bhealth worker\b/i,
    /\bsinger\b/i,
    /\bastronaut\b/i,
    /\bfirefighter\b/i,
    /\bfacepalming\b/i,
    /\bdancing\b/i,
    /\bdetective\b/i,
    /\bfencing\b/i,
    /\bbouncing ball\b/i,
    /\blifting weights\b/i,
    /\bwrestling\b/i,
];
const TONE_CATEGORY_ALLOWLIST = new Set(['people & body', 'activities']);
const ANDROID_TONE_RENDER_BLOCKLIST_PATTERNS = [
    /\bperson fencing\b/i,
    /\bmen wrestling\b/i,
    /\bwomen wrestling\b/i,
];
const ANDROID_TONE_RENDER_BLOCKLIST_SLUGS = new Set([
    'person-fencing',
    'men-wrestling',
    'women-wrestling',
]);
const ANDROID_TONE_IMAGE_FALLBACK_SLUGS = new Set([
    'person-fencing',
    'men-wrestling',
    'women-wrestling',
]);
const IS_ANDROID_RENDERER = (() => {
    try {
        if (/Android/i.test(navigator.userAgent || '')) return true;
        const platform = window.Capacitor?.getPlatform?.();
        return platform === 'android';
    } catch (_) {
        return /Android/i.test(navigator.userAgent || '');
    }
})();

function twemojiSvgUrlFromCodepoints(cp) {
    return `https://twemoji.maxcdn.com/v/latest/svg/${cp}.svg`;
}

function notoEmojiSvgUrlFromCodepoints(cp) {
    return `https://cdn.jsdelivr.net/gh/googlefonts/noto-emoji@main/svg/emoji_u${String(cp || '').replace(/-/g, '_')}.svg`;
}

function shouldUseDetailToneImageFallback(emojiStr, tone = 'off') {
    if (!IS_ANDROID_RENDERER) return false;
    if (!tone || tone === 'off') return false;
    if (!ANDROID_TONE_IMAGE_FALLBACK_SLUGS.has(String(DETAIL_SLUG || '').toLowerCase())) return false;
    return /\u200D/.test(String(emojiStr || ''));
}

function renderDetailHeroEmoji(emojiStr, tone = 'off') {
    const hero = document.getElementById('emoji-hero-symbol');
    if (!hero) return;
    const glyph = String(emojiStr || '');
    if (!glyph) {
        hero.textContent = '';
        return;
    }
    if (!shouldUseDetailToneImageFallback(glyph, tone) || !window.twemoji?.convert?.toCodePoint) {
        hero.textContent = glyph;
        return;
    }
    let cp = '';
    try {
        cp = window.twemoji.convert.toCodePoint(glyph);
    } catch (_) {
        hero.textContent = glyph;
        return;
    }
    if (!cp) {
        hero.textContent = glyph;
        return;
    }
    const img = new Image();
    img.alt = glyph;
    img.draggable = false;
    img.decoding = 'async';
    img.className = 'inline-block align-middle select-none';
    img.style.width = '1em';
    img.style.height = '1em';
    img.style.objectFit = 'contain';
    img.onerror = () => {
        img.onerror = () => {
            hero.textContent = glyph;
        };
        img.src = twemojiSvgUrlFromCodepoints(cp);
    };
    img.src = notoEmojiSvgUrlFromCodepoints(cp);
    hero.replaceChildren(img);
}
let currentDisplayEmoji = SYMBOL_DEFAULT;

function getStoredTone() {
    return localStorage.getItem(TONE_STORAGE_KEY) || 'off';
}

function setStoredTone(value) {
    localStorage.setItem(TONE_STORAGE_KEY, value || 'off');
}

function emojiByTone(tone) {
    if (!tone || tone === 'off') return SYMBOL_DEFAULT;
    if (!isDetailToneAllowed()) return stripSkinTone(SYMBOL_DEFAULT) || SYMBOL_DEFAULT;
    const toneChar = TONE_CHAR_BY_SLUG[tone];
    if (!toneChar) return TONE_VARIANTS[tone] || SYMBOL_DEFAULT;
    const base = stripSkinTone(SYMBOL_DEFAULT);
    if (!canApplyToneTo(base)) return base;
    return applyToneSmart(base, toneChar) || TONE_VARIANTS[tone] || base || SYMBOL_DEFAULT;
}

function applyTone(tone) {
    currentDisplayEmoji = emojiByTone(tone);
    renderDetailHeroEmoji(currentDisplayEmoji, tone);
    document.querySelectorAll('.tone-chip').forEach((chip) => {
        const active = chip.dataset.tone === tone;
        chip.classList.toggle('bg-brand-ocean/20', active);
        chip.classList.toggle('border-brand-ocean/50', active);
        chip.classList.toggle('text-brand-oceanSoft', active);
    });
}

function loadRecent() {
    try {
        const parsed = JSON.parse(localStorage.getItem(RECENT_KEY) || '[]');
        return Array.isArray(parsed) ? parsed.filter(isRecentEmojiToken) : [];
    } catch {
        return [];
    }
}

function isRecentEmojiToken(value) {
    const s = String(value || '').trim();
    if (!s) return false;
    if (s.length > 24) return false;
    if (/[:;&<#\\]/.test(s)) return false;
    try {
        return /\p{Extended_Pictographic}/u.test(s);
    } catch {
        return /[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]/u.test(s);
    }
}

function isDetailNameNonToneable() {
    return NON_TONEABLE_NAME_PATTERNS.some((rx) => rx.test(DETAIL_NAME || ''));
}

function isDetailRoleToneable() {
    return ROLE_TONEABLE_NAME_PATTERNS.some((rx) => rx.test(DETAIL_NAME || ''));
}

function isDetailToneAllowed() {
    if (!DETAIL_SUPPORTS_TONE) return false;
    const category = String(DETAIL_CATEGORY || '').toLowerCase();
    if (!TONE_CATEGORY_ALLOWLIST.has(category)) return false;
    if (isDetailNameNonToneable()) return false;
    if (IS_ANDROID_RENDERER) {
        const slug = String(DETAIL_SLUG || '').toLowerCase();
        const usesImageFallback = ANDROID_TONE_IMAGE_FALLBACK_SLUGS.has(slug);
        if (!usesImageFallback && ANDROID_TONE_RENDER_BLOCKLIST_SLUGS.has(slug)) return false;
        if (!usesImageFallback && ANDROID_TONE_RENDER_BLOCKLIST_PATTERNS.some((rx) => rx.test(DETAIL_NAME || ''))) return false;
    }
    const base = stripSkinTone(SYMBOL_DEFAULT);
    if (!base || !canApplyToneTo(base)) return false;

    const name = String(DETAIL_NAME || '').toLowerCase();
    const looksGenderedRole =
        category === 'people & body' &&
        (name.startsWith('man ') || name.startsWith('woman ') || /[:\-,]\s*(man|woman)\b/.test(name));
    if (looksGenderedRole && !isDetailRoleToneable()) return false;

    return true;
}

function stripSkinTone(emojiChar) {
    return String(emojiChar || '').replace(/[\u{1F3FB}-\u{1F3FF}]/gu, '');
}

function containsZWJ(s) {
    return /\u200D/.test(String(s || ''));
}

function countHumans(s) {
    let n = 0;
    for (const ch of Array.from(String(s || ''))) {
        const cp = ch.codePointAt(0);
        if (cp === 0x1F468 || cp === 0x1F469 || cp === 0x1F9D1) n++;
    }
    return n;
}

function canApplyToneTo(s) {
    if (!s) return false;
    try {
        const cp0 = String(s).codePointAt(0);
        if (NOT_TONEABLE_BASES.has(cp0)) return false;
    } catch (_) {}
    if (!containsZWJ(s)) return true;
    return countHumans(s) <= 2;
}

function toCodePoints(str) {
    const out = [];
    for (const ch of String(str || '')) out.push(ch.codePointAt(0));
    return out;
}

function fromCodePoints(arr) {
    return String.fromCodePoint(...arr);
}

function applyToneSmart(emojiChar, toneChar) {
    if (!emojiChar || !toneChar) return emojiChar;
    const toneCp = String(toneChar).codePointAt(0);
    if (!TONE_CPS.has(toneCp)) return emojiChar;

    const cps = toCodePoints(emojiChar);
    for (const cp of cps) {
        if (TONE_CPS.has(cp)) return emojiChar;
    }

    const VS16 = 0xFE0F;
    const ZWJ = 0x200D;
    const idxs = [];
    for (let i = 0; i < cps.length; i += 1) {
        if (MODIFIABLE_BASES.has(cps[i])) idxs.push(i);
    }

    if (idxs.length === 0) {
        if (cps.includes(ZWJ)) return emojiChar;
        let pos = 1;
        let rightStart = pos;
        if (cps[1] === VS16) {
            rightStart = 2;
        }
        const left = cps.slice(0, pos);
        left.push(toneCp);
        return fromCodePoints(left.concat(cps.slice(rightStart)));
    }

    if (idxs.length === 2) {
        const out = cps.slice();
        const insertAfter = (baseIdx) => {
            let pos = baseIdx + 1;
            if (out[pos] === VS16) out.splice(pos, 1);
            out.splice(pos, 0, toneCp);
        };
        insertAfter(idxs[1]);
        insertAfter(idxs[0]);
        return fromCodePoints(out);
    }

    let pos = idxs[0] + 1;
    let rightStart = pos;
    if (cps[pos] === VS16) {
        rightStart = pos + 1;
    }
    const left = cps.slice(0, pos);
    left.push(toneCp);
    return fromCodePoints(left.concat(cps.slice(rightStart)));
}

function saveRecent(items) {
    const clean = items.filter(isRecentEmojiToken);
    localStorage.setItem(RECENT_KEY, JSON.stringify(clean.slice(0, 8)));
}

function addRecent(emoji) {
    if (!isRecentEmojiToken(emoji)) return;
    const curr = loadRecent().filter((e) => e !== emoji);
    curr.unshift(emoji);
    saveRecent(curr);
}

function loadFavorites() {
    try {
        const parsed = JSON.parse(localStorage.getItem(FAVORITES_KEY) || '[]');
        if (!Array.isArray(parsed)) return [];
        return parsed
            .filter((item) => item && typeof item === 'object')
            .map((item) => ({
                slug: String(item.slug || '').trim(),
                emoji: String(item.emoji || '').trim(),
                name: String(item.name || '').trim(),
                category: String(item.category || '').trim(),
                subcategory: String(item.subcategory || '').trim(),
                supports_skin_tone: Boolean(item.supports_skin_tone),
                variants: Array.isArray(item.variants) ? item.variants : [],
            }))
            .filter((item) => item.slug !== '' && isRecentEmojiToken(item.emoji));
    } catch {
        return [];
    }
}

function saveFavorites(items) {
    localStorage.setItem(FAVORITES_KEY, JSON.stringify(items.slice(0, 24)));
}

function isCurrentFavorite() {
    return loadFavorites().some((item) => item.slug === DETAIL_SLUG);
}

function renderFavoriteButton() {
    const btn = document.getElementById('favorite-toggle-btn');
    const icon = document.getElementById('favorite-toggle-icon');
    const label = document.getElementById('favorite-toggle-label');
    const pill = document.getElementById('favorite-pill');
    if (!btn || !icon || !label) return;
    const active = isCurrentFavorite();
    icon.textContent = active ? '★' : '☆';
    icon.classList.toggle('text-yellow-300', true);
    icon.classList.toggle('text-gray-300', !active);
    label.textContent = active ? 'Favorited' : 'Add Favorite';
    btn.title = active ? 'Remove Favorite' : 'Add Favorite';
    btn.setAttribute('aria-label', active ? 'Remove Favorite' : 'Add Favorite');
    btn.classList.toggle('border-yellow-400/30', active);
    btn.classList.toggle('bg-yellow-400/10', active);
    if (pill) {
        pill.classList.toggle('hidden', !active);
    }
}

function toggleCurrentFavorite() {
    const current = loadFavorites();
    const remaining = current.filter((item) => item.slug !== DETAIL_SLUG);
    const isRemoving = remaining.length !== current.length;
    if (isRemoving) {
        saveFavorites(remaining);
        renderFavoriteButton();
        if (typeof showToast === 'function') showToast('Removed from favorites');
        else showDetailToast('Removed from favorites');
        return false;
    }
    remaining.unshift({
        slug: DETAIL_SLUG,
        emoji: currentDisplayEmoji,
        name: DETAIL_NAME,
        category: DETAIL_CATEGORY,
        subcategory: DETAIL_SUBCATEGORY,
        supports_skin_tone: Boolean(DETAIL_SUPPORTS_TONE),
        variants: Array.isArray(DETAIL_VARIANTS_LIST) ? DETAIL_VARIANTS_LIST : [],
    });
    saveFavorites(remaining);
    renderFavoriteButton();
    if (typeof showToast === 'function') showToast('Added to favorites');
    else showDetailToast('Added to favorites');
    return true;
}

function showDetailToast(message) {
    const toast = document.getElementById('toast');
    const msg = document.getElementById('toast-msg');
    if (!toast || !msg) return;
    msg.innerText = message;
    toast.classList.remove('translate-y-24', 'opacity-0');
    setTimeout(() => {
        toast.classList.add('translate-y-24', 'opacity-0');
    }, 1500);
}

function copyCurrentEmoji() {
    copyToClipboard(currentDisplayEmoji);
}

function copyToClipboard(text) {
    navigator.clipboard.writeText(text).then(() => {
        addRecent(text);
        showDetailToast(`Copied ${text}`);
    });
}

document.addEventListener('keydown', (e) => {
    if (e.key === 'c' && !e.metaKey && !e.ctrlKey && document.activeElement.tagName !== 'INPUT') {
        copyCurrentEmoji();
    }
});

(() => {
    const tonePanel = document.getElementById('tone-panel');
    if (!isDetailToneAllowed()) {
        if (tonePanel) tonePanel.classList.add('hidden');
        applyTone('off');
        return;
    }
    const initialTone = getStoredTone();
    applyTone(initialTone);
    document.querySelectorAll('.tone-chip').forEach((chip) => {
        chip.addEventListener('click', () => {
            const tone = chip.dataset.tone || 'off';
            setStoredTone(tone);
            applyTone(tone);
        });
    });
})();

document.getElementById('favorite-toggle-btn')?.addEventListener('click', toggleCurrentFavorite);
renderFavoriteButton();

// Treat opening the single-emoji page as a "recently viewed emoji" event.
addRecent(currentDisplayEmoji);

(() => {
    const canManageKeywords = @json($canManageKeywords);
    const limitReached = @json($limitReached);
    if (!canManageKeywords) return;
    const modal = document.getElementById('user-keyword-modal');
    const openBtn = document.getElementById('user-keyword-add');
    const closeBtn = document.getElementById('user-keyword-close');
    const cancelBtn = document.getElementById('user-keyword-cancel');
    const form = document.getElementById('user-keyword-form');
    const modalTitle = document.getElementById('user-keyword-title');
    const submitBtn = document.getElementById('user-keyword-submit');
    const keywordInput = document.getElementById('user-keyword-input');
    const langInput = document.getElementById('user-keyword-lang');
    const langComboInput = document.getElementById('user-keyword-lang-combo');
    const langMenuEl = document.getElementById('user-keyword-lang-menu');
    const langSourceEl = document.getElementById('user-keyword-lang-source');
    const list = document.getElementById('user-keyword-list');
    const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
    const updateUrlTemplate = @json(route('dashboard.keywords.update', ['keyword' => '__ID__']));
    const deleteUrlTemplate = @json(route('dashboard.keywords.delete', ['keyword' => '__ID__']));
    let editingKeywordId = null;
    const escHtml = (value) => String(value ?? '').replace(/[&<>"']/g, (ch) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[ch]));

    window.dewemojiPopulateLanguageSelect?.(langSourceEl);
    const canonicalizeLanguageCode = (raw) => window.dewemojiCanonicalLanguageCode?.(raw) || String(raw || '').trim().toLowerCase();

    const DEFAULT_LANGUAGE_CODE = 'en';
    const UNDETERMINED_LANGUAGE_CODE = 'und';

    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 = langInput.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(langComboInput.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;
        langInput.value = value;
        if (silentInput || value.toLowerCase() === UNDETERMINED_LANGUAGE_CODE) {
            langComboInput.value = '';
            return;
        }
        langComboInput.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 setModalMode = (mode = 'add') => {
        if (mode === 'edit') {
            modalTitle.textContent = 'Edit keyword';
            submitBtn.textContent = 'Save changes';
            return;
        }
        modalTitle.textContent = 'Add keyword';
        submitBtn.textContent = 'Save keyword';
    };

    const buildKeywordPill = (item) => {
        const pill = document.createElement('span');
        const isActive = Boolean(item?.is_active ?? true);
        const lang = String(item?.lang || 'und');
        pill.className = `user-keyword-pill inline-flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm ${isActive ? 'bg-white/5 border-white/10 text-gray-200' : 'bg-slate-200/10 border-slate-200/20 text-gray-300'}`;
        pill.dataset.id = String(item?.id || '');
        pill.dataset.keyword = String(item?.keyword || '');
        pill.dataset.lang = lang;
        pill.dataset.active = isActive ? '1' : '0';
        pill.innerHTML = `
            <span>${escHtml(String(item?.keyword || ''))}</span>
            <span class="text-[10px] uppercase tracking-[0.2em] text-gray-500">${escHtml(lang)}</span>
            ${isActive ? '' : '<span class="text-[10px] uppercase tracking-[0.2em] text-amber-400">inactive</span>'}
            <button type="button" class="user-keyword-edit rounded-md border border-white/10 px-1.5 py-0.5 text-[10px] text-gray-300 hover:bg-white/10">Edit</button>
            <button type="button" class="user-keyword-delete rounded-md border border-white/10 px-1.5 py-0.5 text-[10px] text-gray-300 hover:bg-red-500/20">Delete</button>
        `;
        return pill;
    };

    const openModal = (mode = 'add', item = null) => {
        if (mode === 'add' && limitReached) {
            showToast('Free plan keyword limit reached');
            return;
        }
        editingKeywordId = mode === 'edit' ? item?.id || null : null;
        setModalMode(mode);
        modal.classList.remove('hidden');
        modal.classList.add('flex');
        keywordInput.value = mode === 'edit' ? (item?.keyword || '') : '';
        setLanguageByCode(mode === 'edit' ? (item?.lang || UNDETERMINED_LANGUAGE_CODE) : DEFAULT_LANGUAGE_CODE, {
            silentInput: mode === 'edit' && String(item?.lang || '').toLowerCase() === UNDETERMINED_LANGUAGE_CODE,
        });
        closeLanguageMenu();
        keywordInput.focus();
    };

    const closeModal = () => {
        editingKeywordId = null;
        setModalMode('add');
        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();
    });
    langComboInput?.addEventListener('focus', openLanguageMenu);
    langComboInput?.addEventListener('input', openLanguageMenu);
    langComboInput?.addEventListener('blur', () => {
        const nextCode = resolveLanguageCode(langComboInput.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();
    });

    form?.addEventListener('submit', async (e) => {
        e.preventDefault();
        const payload = {
            emoji_slug: @json($slug),
            keyword: keywordInput.value.trim(),
            lang: langInput.value || 'und',
        };
        if (!payload.keyword) return;
        const url = editingKeywordId
            ? updateUrlTemplate.replace('__ID__', String(editingKeywordId))
            : '{{ route('dashboard.keywords.store') }}';
        const method = editingKeywordId ? 'PUT' : 'POST';
        const res = await fetch(url, {
            method,
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                ...(csrf ? { 'X-CSRF-TOKEN': csrf } : {}),
            },
            body: JSON.stringify(payload),
        });
        const data = await res.json().catch(() => null);
        if (!res.ok || !data?.ok) {
            showToast('Could not save keyword');
            return;
        }
        const item = data?.item || payload;
        const wasEditing = Boolean(editingKeywordId);
        const badge = buildKeywordPill(item);
        if (list) {
            const empty = list.querySelector('#user-keyword-empty');
            if (empty) empty.remove();
            if (wasEditing) {
                const current = list.querySelector(`.user-keyword-pill[data-id="${editingKeywordId}"]`);
                if (current) current.replaceWith(badge);
                else list.prepend(badge);
            } else {
                list.prepend(badge);
            }
        }
        closeModal();
        showToast(wasEditing ? 'Keyword updated' : 'Keyword added');
    });

    list?.addEventListener('click', async (event) => {
        const editBtn = event.target.closest('.user-keyword-edit');
        const deleteBtn = event.target.closest('.user-keyword-delete');
        const pill = event.target.closest('.user-keyword-pill');
        if (!pill) return;
        const id = pill.dataset.id;
        if (!id) return;

        if (editBtn) {
            openModal('edit', {
                id,
                keyword: pill.dataset.keyword || '',
                lang: pill.dataset.lang || 'und',
            });
            return;
        }

        if (!deleteBtn) return;
        const ok = window.dewemojiConfirm
            ? await window.dewemojiConfirm('Delete this keyword?', {
                title: 'Delete keyword',
                okText: 'Delete',
            })
            : true;
        if (!ok) return;

        const res = await fetch(deleteUrlTemplate.replace('__ID__', id), {
            method: 'DELETE',
            headers: {
                'Accept': 'application/json',
                ...(csrf ? { 'X-CSRF-TOKEN': csrf } : {}),
            },
        });
        const data = await res.json().catch(() => null);
        if (!res.ok || !data?.ok) {
            showToast('Could not delete keyword');
            return;
        }
        pill.remove();
        if (!list.querySelector('.user-keyword-pill')) {
            const empty = document.createElement('span');
            empty.id = 'user-keyword-empty';
            empty.className = 'text-sm text-gray-400';
            empty.textContent = 'No private keywords yet. Add one to personalize search.';
            list.appendChild(empty);
        }
        showToast('Keyword deleted');
    });
})();

</script>
@endpush
