'use client';

import type { DiscordEmojiOption } from '@nexumi/shared';
import { useCallback, useEffect, useState } from 'react';

const cache = new Map<string, DiscordEmojiOption[]>();

export function useGuildEmojis(guildId: string): {
  emojis: DiscordEmojiOption[];
  loading: boolean;
  error: boolean;
  reload: () => void;
} {
  const [emojis, setEmojis] = useState<DiscordEmojiOption[]>(() => cache.get(guildId) ?? []);
  const [loading, setLoading] = useState(!cache.has(guildId));
  const [error, setError] = useState(false);
  const [reloadToken, setReloadToken] = useState(0);

  const reload = useCallback(() => {
    cache.delete(guildId);
    setReloadToken((token) => token + 1);
  }, [guildId]);

  useEffect(() => {
    let cancelled = false;
    const cached = reloadToken === 0 ? cache.get(guildId) : undefined;
    if (cached) {
      setEmojis(cached);
      setLoading(false);
      setError(false);
      return;
    }

    setLoading(true);
    setError(false);
    void fetch(`/api/guilds/${guildId}/emojis`)
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`Emojis request failed with ${response.status}`);
        }
        const data = (await response.json()) as DiscordEmojiOption[];
        if (!Array.isArray(data)) {
          throw new Error('Emojis response was not an array');
        }
        return data;
      })
      .then((data) => {
        if (cancelled) {
          return;
        }
        if (data.length > 0) {
          cache.set(guildId, data);
        } else {
          cache.delete(guildId);
        }
        setEmojis(data);
        setError(false);
      })
      .catch(() => {
        if (!cancelled) {
          cache.delete(guildId);
          setEmojis([]);
          setError(true);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoading(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [guildId, reloadToken]);

  return { emojis, loading, error, reload };
}
