"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ReactNode,
} from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import { getAdminSettings } from "@/api/admin-settings";

/** 系统设置页一次拉取的分组（避免各卡片重复 GET） */
export const SYSTEM_SETTINGS_GROUPS = ["draw", "settlement", "frontend", "wallet"] as const;

function mergeItemsToKv(
  items: { key: string; value: unknown }[],
  into: Record<string, unknown>,
): void {
  for (const item of items) {
    into[item.key] = item.value;
  }
}

type AdminSettingsDataContextValue = {
  kv: Record<string, unknown> | null;
  loading: boolean;
  reload: () => Promise<void>;
  patchKv: (updates: Record<string, unknown>) => void;
};

const AdminSettingsDataContext = createContext<AdminSettingsDataContextValue | null>(null);

export function AdminSettingsDataProvider({ children }: { children: ReactNode }) {
  const { t } = useTranslation(["config"]);
  const [kv, setKv] = useState<Record<string, unknown> | null>(null);
  const [loading, setLoading] = useState(true);
  const tRef = useRef(t);
  tRef.current = t;

  const reload = useCallback(async () => {
    setLoading(true);
    try {
      const responses = await Promise.all(
        SYSTEM_SETTINGS_GROUPS.map((group) => getAdminSettings(group)),
      );
      const merged: Record<string, unknown> = {};
      for (const res of responses) {
        mergeItemsToKv(res.items, merged);
      }
      setKv(merged);
    } catch {
      toast.error(tRef.current("system.loadFailed", { ns: "config" }));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void reload();
  }, [reload]);

  const patchKv = useCallback((updates: Record<string, unknown>) => {
    setKv((prev) => (prev === null ? { ...updates } : { ...prev, ...updates }));
  }, []);

  const value = useMemo(
    () => ({ kv, loading, reload, patchKv }),
    [kv, loading, reload, patchKv],
  );

  return (
    <AdminSettingsDataContext.Provider value={value}>{children}</AdminSettingsDataContext.Provider>
  );
}

export function useAdminSettingsData(): AdminSettingsDataContextValue {
  const ctx = useContext(AdminSettingsDataContext);
  if (ctx === null) {
    throw new Error("useAdminSettingsData must be used within AdminSettingsDataProvider");
  }
  return ctx;
}

export function useOptionalAdminSettingsData(): AdminSettingsDataContextValue | null {
  return useContext(AdminSettingsDataContext);
}
