export interface EmojiEntry {
  emoji: string;
  label: string;
  tags: string[];
  shortcodes: string[];
}

export interface EmojiGroup {
  name: string;
  emojis: EmojiEntry[];
}

interface RawEmoji {
  hexcode: string;
  unicode: string;
  label: string;
  group?: number;
  order?: number;
  tags?: string[];
}

const GROUP_NAMES: Record<number, string> = {
  0: 'Smileys & emotion',
  1: 'People & body',
  3: 'Animals & nature',
  4: 'Food & drink',
  5: 'Travel & places',
  6: 'Activities',
  7: 'Objects',
  8: 'Symbols',
  9: 'Flags'
};

let loading: Promise<EmojiGroup[]> | null = null;

export function loadEmoji(): Promise<EmojiGroup[]> {
  loading ??= (async () => {
    const [compact, codes] = await Promise.all([
      import('emojibase-data/en/compact.json'),
      import('emojibase-data/en/shortcodes/emojibase.json')
    ]);
    const shortcodes = codes.default as Record<string, string | string[]>;
    const byGroup = new Map<number, EmojiEntry[]>();
    for (const raw of compact.default as RawEmoji[]) {
      if (raw.group === undefined || !(raw.group in GROUP_NAMES)) continue;
      const code = shortcodes[raw.hexcode];
      const entry: EmojiEntry = {
        emoji: raw.unicode,
        label: raw.label,
        tags: raw.tags ?? [],
        shortcodes: code === undefined ? [] : Array.isArray(code) ? code : [code]
      };
      const list = byGroup.get(raw.group) ?? [];
      list.push(entry);
      byGroup.set(raw.group, list);
    }
    return Object.entries(GROUP_NAMES).flatMap(([id, name]) => {
      const emojis = byGroup.get(Number(id));
      return emojis ? [{ name, emojis }] : [];
    });
  })().catch((e) => {
    loading = null;
    throw e;
  });
  return loading;
}

export function matchesEmoji(entry: EmojiEntry, query: string): boolean {
  const q = query.trim().toLowerCase().replace(/^:|:$/g, '');
  if (!q) return true;
  return (
    entry.label.toLowerCase().includes(q) ||
    entry.tags.some((t) => t.toLowerCase().includes(q)) ||
    entry.shortcodes.some((s) => s.toLowerCase().includes(q))
  );
}

export function searchEmoji(groups: EmojiGroup[], query: string): EmojiGroup[] {
  return groups
    .map((g) => ({ name: g.name, emojis: g.emojis.filter((e) => matchesEmoji(e, query)) }))
    .filter((g) => g.emojis.length > 0);
}
