'use client';

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

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

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

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

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

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