import { useCallback, useEffect, useState } from 'react';
import { exchangeApi, settlementApi } from '../../config/dex';

export type MoneySupply = {
  asOf?: string;
  officeId?: number;
  fineractLive?: boolean;
  fineractConnected?: boolean;
  interoffice?: { dueFromHeadOffice?: string; gl1410?: string };
  M0?: { gl1050?: string; backingRatio?: number };
  M1?: { circulating?: string; gl2100?: string };
  M2?: { broadMoney?: string; gl2200?: string; metaFiatPending?: string };
};

async function fetchJson<T>(url: string): Promise<T | null> {
  try {
    const res = await fetch(url);
    return res.ok ? ((await res.json()) as T) : null;
  } catch {
    return null;
  }
}

async function loadMoneySupply(): Promise<MoneySupply | null> {
  for (const path of ['/public/money-supply', '/money-supply/public', '/health/ledger']) {
    const data = await fetchJson<MoneySupply>(settlementApi(path));
    if (data) return data;
  }

  const health = await fetchJson<{ moneySupply?: MoneySupply }>(
    `${settlementApi('/health')}?ledger=1`,
  );
  if (health?.moneySupply) return health.moneySupply;

  const apiKey = import.meta.env.VITE_OMNL_API_KEY;
  if (!apiKey) return null;

  const authRes = await fetch(settlementApi('/money-supply'), {
    headers: { Authorization: `Bearer ${apiKey}` },
  });
  return authRes.ok ? authRes.json() : null;
}

export function useCentralBank() {
  const [health, setHealth] = useState<Record<string, unknown> | null>(null);
  const [office, setOffice] = useState<Record<string, unknown> | null>(null);
  const [moneySupply, setMoneySupply] = useState<MoneySupply | null>(null);
  const [tokenCount, setTokenCount] = useState(0);
  const [monitor, setMonitor] = useState<Record<string, unknown> | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const refresh = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [h, o, m2, mon, ms] = await Promise.all([
        fetchJson<Record<string, unknown>>(settlementApi('/health')),
        fetchJson<Record<string, unknown>>(settlementApi('/office')),
        fetchJson<{ tokens?: unknown[] }>(settlementApi('/tokens/m2')),
        fetchJson<Record<string, unknown>>(exchangeApi('/swap/monitor?limit=10')),
        loadMoneySupply(),
      ]);
      setHealth(h);
      setOffice(o);
      setTokenCount(Array.isArray(m2?.tokens) ? m2.tokens.length : 0);
      setMonitor(mon);
      setMoneySupply(
        ms ??
          (h?.status === 'ok'
            ? { fineractConnected: true, fineractLive: false, officeId: 24 }
            : null),
      );
      if (!h && !o) {
        setError('Settlement middleware unreachable');
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to load central bank data');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    refresh();
    const id = setInterval(refresh, 30000);
    return () => clearInterval(id);
  }, [refresh]);

  return { health, office, moneySupply, tokenCount, monitor, loading, error, refresh };
}
