import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useAuth } from "@/app/auth/AuthProvider.jsx";
import { listAdminApps } from "@/features/app-registry/api";
import { getSelectedAppCode, setSelectedAppCode as setRequestAppCode } from "@/shared/api/request";
import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js";

const AppScopeContext = createContext(null);
const fallbackAppCode = "lalu";
const emptyAppState = { items: [], total: 0 };

export function AppScopeProvider({ children }) {
  const { user } = useAuth();
  const queryClient = useQueryClient();
  const [appCode, setAppCodeState] = useState(() => getSelectedAppCode() || fallbackAppCode);
  const { data = emptyAppState, error, loading } = useAdminQuery(() => listAdminApps(), {
    enabled: Boolean(user),
    errorMessage: "加载 App 列表失败",
    initialData: emptyAppState,
    queryKey: ["admin-apps"],
    staleTime: 5 * 60 * 1000
  });
  const apps = useMemo(() => data?.items || [], [data?.items]);

  const applyAppCode = useCallback(
    async (nextAppCode, options = {}) => {
      const normalized = normalizeAppCode(nextAppCode) || fallbackAppCode;
      setRequestAppCode(normalized);
      setAppCodeState(normalized);
      if (!options.skipRefresh) {
        await queryClient.invalidateQueries({ refetchType: "active" });
      }
    },
    [queryClient]
  );

  useEffect(() => {
    if (!apps.length) {
      return;
    }
    const selectedExists = apps.some((item) => normalizeAppCode(item.appCode) === normalizeAppCode(appCode));
    if (!selectedExists) {
      void applyAppCode(apps[0].appCode, { skipRefresh: false });
    }
  }, [appCode, applyAppCode, apps]);

  const value = useMemo(
    () => ({
      appCode,
      apps,
      error,
      loading,
      setAppCode: applyAppCode
    }),
    [appCode, applyAppCode, apps, error, loading]
  );

  return <AppScopeContext.Provider value={value}>{children}</AppScopeContext.Provider>;
}

export function useAppScope() {
  const context = useContext(AppScopeContext);
  if (!context) {
    throw new Error("useAppScope must be used inside AppScopeProvider");
  }
  return context;
}

function normalizeAppCode(value) {
  return String(value || "").trim().toLowerCase();
}
