import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { loadAccountTokenUsage, loadAccountUsage, loadAccountUsageHistory, useAccountResetCredit } from "./status-api.js";

export function useUsageOverview(accounts, trendDays) {
  const [entries, setEntries] = useState({});
  const [refreshing, setRefreshing] = useState(false);
  const mountedRef = useRef(true);
  const trendDaysRef = useRef(trendDays);
  trendDaysRef.current = trendDays;
  const accountsRef = useRef(accounts);
  accountsRef.current = accounts;
  const accountKey = useMemo(() => accounts.map((account) => account.id).sort().join("|"), [accounts]);

  useEffect(() => {
    mountedRef.current = true;
    return () => { mountedRef.current = false; };
  }, []);

  const loadAccount = useCallback(async (accountId) => {
    setEntries((current) => ({ ...current, [accountId]: { ...current[accountId], loading: true, error: "" } }));
    const usageResult = await Promise.allSettled([loadAccountUsage(accountId)]).then(([result]) => result);
    const historyResult = await Promise.allSettled([loadAccountUsageHistory(accountId, trendDays)]).then(([result]) => result);
    const tokenResult = await Promise.allSettled([loadAccountTokenUsage(accountId)]).then(([result]) => result);
    if (!mountedRef.current || trendDaysRef.current !== trendDays) return;
    setEntries((current) => ({
      ...current,
      [accountId]: {
        ...current[accountId],
        usage: usageResult.status === "fulfilled" ? usageResult.value : current[accountId]?.usage ?? null,
        points: historyResult.status === "fulfilled" ? historyResult.value.points ?? [] : current[accountId]?.points ?? [],
        tokenUsage: tokenResult.status === "fulfilled" ? tokenResult.value : current[accountId]?.tokenUsage ?? null,
        loading: false,
        error: usageResult.status === "rejected" ? usageError(usageResult.reason) : "",
        historyError: historyResult.status === "rejected",
        tokenError: tokenResult.status === "rejected"
      }
    }));
  }, [trendDays]);

  const reload = useCallback(async () => {
    if (mountedRef.current) setRefreshing(true);
    await Promise.allSettled(accountsRef.current.map((account) => loadAccount(account.id)));
    if (mountedRef.current) setRefreshing(false);
  }, [loadAccount]);

  useEffect(() => {
    void reload();
    const timer = setInterval(reload, 60000);
    return () => clearInterval(timer);
  }, [accountKey, reload]);

  async function reset(accountId) {
    if (entries[accountId]?.resetPending) return null;
    setEntries((current) => ({ ...current, [accountId]: { ...current[accountId], resetPending: true } }));
    try {
      const result = await useAccountResetCredit(accountId);
      await loadAccount(accountId);
      return result;
    } finally {
      if (mountedRef.current) setEntries((current) => ({ ...current, [accountId]: { ...current[accountId], resetPending: false } }));
    }
  }

  return { entries, refreshing, reload, reset };
}

function usageError(error) {
  return error?.message === "pc_unreachable" ? "pc_unreachable" : "usage_unavailable";
}
