import { useEffect, useMemo, useRef, useState } from 'react';

interface EmojiEntry {
  e: string;
  k: string[]; // search keywords (incl. name)
}

interface Category {
  label: string;
  entries: EmojiEntry[];
}

// Curated emoji set — small enough to stay fast without a dependency, wide
// enough to cover everyday messaging. Keywords are the primary search
// surface; the emoji character itself is also matched so a user typing ❤️
// literally finds it.
const CATEGORIES: Category[] = [
  {
    label: 'Smileys',
    entries: [
      { e: '😀', k: ['grin', 'smile', 'happy'] },
      { e: '😃', k: ['smile', 'happy'] },
      { e: '😄', k: ['smile', 'laugh'] },
      { e: '😁', k: ['grin', 'smile'] },
      { e: '😆', k: ['laugh', 'lol'] },
      { e: '😅', k: ['sweat', 'nervous', 'laugh'] },
      { e: '🤣', k: ['lol', 'rofl', 'laugh'] },
      { e: '😂', k: ['joy', 'laugh', 'tears'] },
      { e: '🙂', k: ['smile', 'slight'] },
      { e: '🙃', k: ['upside', 'irony'] },
      { e: '😉', k: ['wink'] },
      { e: '😊', k: ['blush', 'smile'] },
      { e: '😇', k: ['angel', 'innocent'] },
      { e: '🥰', k: ['love', 'hearts'] },
      { e: '😍', k: ['love', 'heart eyes'] },
      { e: '🤩', k: ['star', 'excited'] },
      { e: '😘', k: ['kiss'] },
      { e: '😗', k: ['kiss'] },
      { e: '😚', k: ['kiss'] },
      { e: '😙', k: ['kiss'] },
      { e: '🥲', k: ['tear', 'smile'] },
      { e: '😋', k: ['yum', 'tasty'] },
      { e: '😛', k: ['tongue'] },
      { e: '😜', k: ['tongue', 'wink'] },
      { e: '🤪', k: ['zany', 'silly'] },
      { e: '😝', k: ['tongue'] },
      { e: '🤑', k: ['money'] },
      { e: '🤗', k: ['hug'] },
      { e: '🤭', k: ['giggle', 'shy'] },
      { e: '🤫', k: ['shush', 'quiet'] },
      { e: '🤔', k: ['think'] },
      { e: '🤐', k: ['zip', 'quiet'] },
      { e: '🤨', k: ['raise brow'] },
      { e: '😐', k: ['neutral'] },
      { e: '😑', k: ['expressionless'] },
      { e: '😶', k: ['speechless'] },
      { e: '😏', k: ['smirk'] },
      { e: '😒', k: ['unamused'] },
      { e: '🙄', k: ['eye roll'] },
      { e: '😬', k: ['grimace', 'awkward'] },
      { e: '🤥', k: ['lying'] },
      { e: '😔', k: ['sad', 'pensive'] },
      { e: '😪', k: ['sleepy'] },
      { e: '😴', k: ['sleep'] },
      { e: '😷', k: ['mask', 'sick'] },
      { e: '🤒', k: ['sick', 'fever'] },
      { e: '🤕', k: ['injured'] },
      { e: '🤢', k: ['nauseated'] },
      { e: '🤮', k: ['vomit'] },
      { e: '🤧', k: ['sneeze'] },
      { e: '🥵', k: ['hot'] },
      { e: '🥶', k: ['cold'] },
      { e: '🥴', k: ['dizzy', 'woozy'] },
      { e: '😵', k: ['dizzy'] },
      { e: '🤯', k: ['mind blown'] },
      { e: '🤠', k: ['cowboy'] },
      { e: '🥳', k: ['party'] },
      { e: '😎', k: ['cool', 'sunglasses'] },
      { e: '🤓', k: ['nerd'] },
      { e: '🧐', k: ['monocle'] },
      { e: '😕', k: ['confused'] },
      { e: '😟', k: ['worried'] },
      { e: '🙁', k: ['frown'] },
      { e: '☹️', k: ['frown'] },
      { e: '😮', k: ['open mouth'] },
      { e: '😯', k: ['hushed'] },
      { e: '😲', k: ['astonished'] },
      { e: '😳', k: ['flushed'] },
      { e: '🥺', k: ['pleading'] },
      { e: '😦', k: ['frowning'] },
      { e: '😧', k: ['anguished'] },
      { e: '😨', k: ['fear'] },
      { e: '😰', k: ['anxious', 'sweat'] },
      { e: '😥', k: ['sad', 'relieved'] },
      { e: '😢', k: ['cry'] },
      { e: '😭', k: ['cry', 'loud'] },
      { e: '😱', k: ['scream', 'scared'] },
      { e: '😖', k: ['confounded'] },
      { e: '😣', k: ['persevere'] },
      { e: '😞', k: ['disappointed'] },
      { e: '😓', k: ['sweat'] },
      { e: '😩', k: ['weary'] },
      { e: '😫', k: ['tired'] },
      { e: '🥱', k: ['yawn'] },
      { e: '😤', k: ['triumph'] },
      { e: '😡', k: ['angry', 'rage'] },
      { e: '😠', k: ['angry'] },
      { e: '🤬', k: ['swear', 'curse'] },
      { e: '😈', k: ['devil'] },
      { e: '👿', k: ['imp'] },
      { e: '💀', k: ['skull', 'dead'] },
      { e: '🤡', k: ['clown'] },
      { e: '👻', k: ['ghost'] },
      { e: '👽', k: ['alien'] },
      { e: '🤖', k: ['robot'] },
      { e: '💩', k: ['poop', 'shit'] },
    ],
  },
  {
    label: 'Gestures',
    entries: [
      { e: '👋', k: ['wave', 'hi'] },
      { e: '🤚', k: ['hand'] },
      { e: '🖐️', k: ['hand'] },
      { e: '✋', k: ['stop', 'high five'] },
      { e: '🖖', k: ['spock'] },
      { e: '👌', k: ['ok'] },
      { e: '🤌', k: ['pinch'] },
      { e: '🤏', k: ['small'] },
      { e: '✌️', k: ['peace', 'victory'] },
      { e: '🤞', k: ['crossed fingers'] },
      { e: '🤟', k: ['love you'] },
      { e: '🤘', k: ['rock'] },
      { e: '🤙', k: ['call me'] },
      { e: '👈', k: ['point left'] },
      { e: '👉', k: ['point right'] },
      { e: '👆', k: ['point up'] },
      { e: '🖕', k: ['middle finger', 'fuck'] },
      { e: '👇', k: ['point down'] },
      { e: '☝️', k: ['point up'] },
      { e: '👍', k: ['thumbs up', 'like'] },
      { e: '👎', k: ['thumbs down', 'dislike'] },
      { e: '✊', k: ['fist'] },
      { e: '👊', k: ['punch'] },
      { e: '🤛', k: ['fist left'] },
      { e: '🤜', k: ['fist right'] },
      { e: '👏', k: ['clap'] },
      { e: '🙌', k: ['raised hands'] },
      { e: '👐', k: ['open hands'] },
      { e: '🤲', k: ['palms'] },
      { e: '🙏', k: ['pray', 'thanks'] },
      { e: '✍️', k: ['write'] },
      { e: '💪', k: ['flex', 'strong'] },
    ],
  },
  {
    label: 'Hearts',
    entries: [
      { e: '❤️', k: ['heart', 'love'] },
      { e: '🧡', k: ['orange heart'] },
      { e: '💛', k: ['yellow heart'] },
      { e: '💚', k: ['green heart'] },
      { e: '💙', k: ['blue heart'] },
      { e: '💜', k: ['purple heart'] },
      { e: '🖤', k: ['black heart'] },
      { e: '🤍', k: ['white heart'] },
      { e: '🤎', k: ['brown heart'] },
      { e: '💔', k: ['broken heart'] },
      { e: '❣️', k: ['heart exclamation'] },
      { e: '💕', k: ['hearts'] },
      { e: '💞', k: ['revolving hearts'] },
      { e: '💓', k: ['beating heart'] },
      { e: '💗', k: ['growing heart'] },
      { e: '💖', k: ['sparkle heart'] },
      { e: '💘', k: ['cupid'] },
      { e: '💝', k: ['heart gift'] },
    ],
  },
  {
    label: 'Animals & Food',
    entries: [
      { e: '🐶', k: ['dog'] },
      { e: '🐱', k: ['cat'] },
      { e: '🐭', k: ['mouse'] },
      { e: '🐹', k: ['hamster'] },
      { e: '🐰', k: ['rabbit'] },
      { e: '🦊', k: ['fox'] },
      { e: '🐻', k: ['bear'] },
      { e: '🐼', k: ['panda'] },
      { e: '🐨', k: ['koala'] },
      { e: '🐯', k: ['tiger'] },
      { e: '🦁', k: ['lion'] },
      { e: '🐸', k: ['frog'] },
      { e: '🐵', k: ['monkey'] },
      { e: '🐔', k: ['chicken'] },
      { e: '🐧', k: ['penguin'] },
      { e: '🐦', k: ['bird'] },
      { e: '🦆', k: ['duck'] },
      { e: '🍎', k: ['apple'] },
      { e: '🍌', k: ['banana'] },
      { e: '🍕', k: ['pizza'] },
      { e: '🍔', k: ['burger'] },
      { e: '🍟', k: ['fries'] },
      { e: '🌭', k: ['hotdog'] },
      { e: '🍿', k: ['popcorn'] },
      { e: '🍣', k: ['sushi'] },
      { e: '🍩', k: ['donut'] },
      { e: '🍪', k: ['cookie'] },
      { e: '🎂', k: ['cake', 'birthday'] },
      { e: '🍰', k: ['cake'] },
      { e: '🍫', k: ['chocolate'] },
      { e: '🍺', k: ['beer'] },
      { e: '🍷', k: ['wine'] },
      { e: '🥂', k: ['cheers'] },
      { e: '☕', k: ['coffee'] },
    ],
  },
  {
    label: 'Objects & Symbols',
    entries: [
      { e: '🔥', k: ['fire', 'lit'] },
      { e: '✨', k: ['sparkle'] },
      { e: '⭐', k: ['star'] },
      { e: '🌟', k: ['star glowing'] },
      { e: '💫', k: ['dizzy'] },
      { e: '💥', k: ['boom', 'explosion'] },
      { e: '⚡', k: ['lightning'] },
      { e: '☀️', k: ['sun'] },
      { e: '🌈', k: ['rainbow'] },
      { e: '☁️', k: ['cloud'] },
      { e: '🌧️', k: ['rain'] },
      { e: '❄️', k: ['snow'] },
      { e: '🎉', k: ['party', 'tada'] },
      { e: '🎊', k: ['confetti'] },
      { e: '🎁', k: ['gift'] },
      { e: '🎈', k: ['balloon'] },
      { e: '💯', k: ['100', 'perfect'] },
      { e: '✅', k: ['check'] },
      { e: '❌', k: ['x', 'no'] },
      { e: '⚠️', k: ['warning'] },
      { e: '❓', k: ['question'] },
      { e: '❗', k: ['exclamation'] },
      { e: '💬', k: ['speech'] },
      { e: '💭', k: ['thought'] },
      { e: '👀', k: ['eyes'] },
      { e: '🚀', k: ['rocket'] },
      { e: '🎵', k: ['music'] },
      { e: '🎶', k: ['music'] },
      { e: '🔔', k: ['bell'] },
      { e: '💡', k: ['idea', 'bulb'] },
    ],
  },
];

const RECENT_KEY = 'chat.emoji.recents.v1';
const RECENT_MAX = 24;

function loadRecents(): string[] {
  try {
    const raw = localStorage.getItem(RECENT_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    if (!Array.isArray(parsed)) return [];
    return parsed.filter((x): x is string => typeof x === 'string').slice(0, RECENT_MAX);
  } catch {
    return [];
  }
}

function saveRecents(list: string[]): void {
  try {
    localStorage.setItem(RECENT_KEY, JSON.stringify(list.slice(0, RECENT_MAX)));
  } catch {
    /* ignore quota */
  }
}

interface Props {
  open: boolean;
  onPick: (emoji: string) => void;
  onClose: () => void;
}

export function EmojiPicker({ open, onPick, onClose }: Props) {
  const [query, setQuery] = useState('');
  const [recents, setRecents] = useState<string[]>(() => loadRecents());
  const rootRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        onClose();
      }
    };
    const onDown = (e: MouseEvent) => {
      const t = e.target as HTMLElement | null;
      if (
        rootRef.current &&
        t &&
        !rootRef.current.contains(t) &&
        !t.closest('[data-emoji-trigger]')
      ) {
        onClose();
      }
    };
    window.addEventListener('keydown', onKey);
    window.addEventListener('mousedown', onDown);
    return () => {
      window.removeEventListener('keydown', onKey);
      window.removeEventListener('mousedown', onDown);
    };
  }, [open, onClose]);

  useEffect(() => {
    if (open) setQuery('');
  }, [open]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return CATEGORIES;
    return CATEGORIES.map((cat) => ({
      label: cat.label,
      entries: cat.entries.filter(
        (entry) =>
          entry.e.includes(q) ||
          entry.k.some((k) => k.includes(q)) ||
          cat.label.toLowerCase().includes(q),
      ),
    })).filter((cat) => cat.entries.length > 0);
  }, [query]);

  if (!open) return null;

  const handlePick = (emoji: string) => {
    onPick(emoji);
    const next = [emoji, ...recents.filter((e) => e !== emoji)].slice(0, RECENT_MAX);
    setRecents(next);
    saveRecents(next);
  };

  return (
    <div
      ref={rootRef}
      role="dialog"
      aria-label="Emoji auswählen"
      className="absolute bottom-full right-0 z-30 mb-2 flex w-[320px] flex-col rounded-xl border border-line bg-surface-2 shadow-xl dark:bg-[#2b2d31]"
    >
      <div className="border-b border-line p-2">
        <input
          type="search"
          autoFocus
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Suchen…"
          className="w-full rounded-md border border-line bg-surface-3 px-2.5 py-1.5 text-sm text-fg placeholder-fg-muted outline-none focus:border-accent dark:bg-[#383a40]"
        />
      </div>
      <div className="max-h-[320px] overflow-y-auto p-2">
        {recents.length > 0 && !query && (
          <CategoryBlock
            label="Zuletzt"
            entries={recents.map((e) => ({ e, k: [] }))}
            onPick={handlePick}
          />
        )}
        {filtered.map((cat) => (
          <CategoryBlock
            key={cat.label}
            label={cat.label}
            entries={cat.entries}
            onPick={handlePick}
          />
        ))}
        {filtered.length === 0 && (
          <p className="py-4 text-center text-xs text-fg-muted">Keine Treffer</p>
        )}
      </div>
    </div>
  );
}

function CategoryBlock({
  label,
  entries,
  onPick,
}: {
  label: string;
  entries: EmojiEntry[];
  onPick: (emoji: string) => void;
}) {
  return (
    <div className="mb-2">
      <p className="mb-1 px-1 text-[10px] font-semibold uppercase tracking-wider text-fg-muted">
        {label}
      </p>
      <div className="grid grid-cols-8 gap-0.5">
        {entries.map((entry, idx) => (
          <button
            key={entry.e + ':' + idx}
            type="button"
            onClick={() => onPick(entry.e)}
            aria-label={entry.k[0] ?? entry.e}
            className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-md text-lg transition hover:bg-surface-3 dark:hover:bg-[#383a40]"
          >
            {entry.e}
          </button>
        ))}
      </div>
    </div>
  );
}
