'use client';

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

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

export function useGuildRoles(guildId: string): {
  roles: DiscordRoleOption[];
  loading: boolean;
  error: boolean;
  reload: () => void;
} {
  const [roles, setRoles] = useState<DiscordRoleOption[]>(() => 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) {
      setRoles(cached);
      setLoading(false);
      setError(false);
      return;
    }

    setLoading(true);
    setError(false);
    void fetch(`/api/guilds/${guildId}/roles`)
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`Roles request failed with ${response.status}`);
        }
        const data = (await response.json()) as DiscordRoleOption[];
        if (!Array.isArray(data)) {
          throw new Error('Roles response was not an array');
        }
        return data;
      })
      .then((data) => {
        if (cancelled) {
          return;
        }
        // Only cache successful non-empty payloads so a one-off failure
        // cannot stick the picker on "Keine Treffer".
        if (data.length > 0) {
          cache.set(guildId, data);
        } else {
          cache.delete(guildId);
        }
        setRoles(data);
        setError(false);
      })
      .catch(() => {
        if (!cancelled) {
          cache.delete(guildId);
          setRoles([]);
          setError(true);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoading(false);
        }
      });

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

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