/**
 * Loads the four dictionary endpoints and returns the transformed, ready-to-use
 * IDictionaries object. Every component that needs a name lookup
 * (`useCityName`, `useStationDisplayName`, etc.) eventually calls this
 * hook, so we cache the underlying network request at module scope — a
 * single GET burst per client, no matter how many consumers subscribe.
 *
 * Previously every `useCityName` call fired its own `fetchDictionaries`,
 * producing 6–10 duplicate requests for the same 4 dictionary endpoints
 * on a single render (once for each StationDisplay, PopularRequestItem,
 * mini-list row, etc.). The network cost was an order of magnitude
 * higher than needed and flooded the console with duplicate 403s when
 * the WAF was angry.
 */

import { useEffect, useState } from "react";
import type { ApiClient } from "@/shared/api/client.js";
import { useApiClient } from "@/shared/api/provider.js";
import { fetchDictionaries } from "./api.js";
import { transformDictionaries } from "./transform.js";
import type { IDictionariesState, IRawDictionaries } from "./types.js";

// Module-level single-flight cache keyed by ApiClient instance. The cache
// stores the in-flight Promise, so concurrent callers await the same
// resolution. We intentionally do NOT bust the cache on error — a second
// call would just re-fail; let the caller retry by remounting with a
// fresh ApiClient if it wants a retry.
const rawCache = new WeakMap<ApiClient, Promise<IRawDictionaries>>();

function getRawDictionaries(client: ApiClient): Promise<IRawDictionaries> {
  const existing = rawCache.get(client);
  if (existing) return existing;
  const promise = fetchDictionaries(client);
  rawCache.set(client, promise);
  return promise;
}

export function useDictionaries(lang: string): IDictionariesState {
  const client = useApiClient();
  const [state, setState] = useState<IDictionariesState>({
    dictionaries: null,
    loading: true,
    error: null,
  });

  useEffect(() => {
    let cancelled = false;

    getRawDictionaries(client)
      .then((raw) => {
        if (cancelled) return;
        const dictionaries = transformDictionaries(raw, lang);
        setState({ dictionaries, loading: false, error: null });
      })
      .catch((err: Error) => {
        if (cancelled) return;
        setState({ dictionaries: null, loading: false, error: err });
      });

    return () => {
      cancelled = true;
    };
  }, [client, lang]);

  return state;
}
