import { useCallback, useRef, useState } from 'react';
import api from '../core/api';

export type SelectOption = { value: string | number; label: string };

function sourceKey(source: string, params: Record<string, unknown> = {}): string {
  const entries = Object.entries(params).filter(([, value]) => value != null && value !== '');
  if (entries.length === 0) return source;
  return `${source}?${new URLSearchParams(entries.map(([k, v]) => [k, String(v)])).toString()}`;
}

export function useSelectOptions() {
  const [options, setOptions] = useState<Record<string, SelectOption[]>>({});
  const loadedRef = useRef(new Set<string>());

  const loadSource = useCallback(async (source: string, params: Record<string, unknown> = {}) => {
    const key = sourceKey(source, params);
    if (loadedRef.current.has(key)) return;
    loadedRef.current.add(key);

    try {
      const { data } = await api.get(`/select-options/${source}`, { params });
      setOptions((prev) => ({ ...prev, [key]: Array.isArray(data) ? data : [] }));
    } catch {
      loadedRef.current.delete(key);
    }
  }, []);

  const loadSources = useCallback(async (
    sources: Array<string | { source: string; params?: Record<string, unknown> } | null | undefined>,
  ) => {
    const unique = [...new Set(sources.filter(Boolean))];
    await Promise.all(unique.map((item) => {
      if (typeof item === 'string') return loadSource(item);
      return loadSource(item!.source, item!.params || {});
    }));
  }, [loadSource]);

  const getOptions = useCallback((source: string, params: Record<string, unknown> = {}) => {
    return options[sourceKey(source, params)] || [];
  }, [options]);

  return { options, loadSources, getOptions };
}
