import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useAuth } from "@/app/auth/AuthProvider.jsx";
import { listVisibleAdminApps } 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 emptyAppState = { items: [], total: 0 };

export function AppScopeProvider({ children }) {
  const { user } = useAuth();
  const queryClient = useQueryClient();
  const [appCode, setAppCodeState] = useState(() => getSelectedAppCode());
  const { data = emptyAppState, error, loading } = useAdminQuery(() => listVisibleAdminApps(), {
    enabled: Boolean(user),
    errorMessage: "加载 App 列表失败",
    initialData: emptyAppState,
    // App 范围属于用户授权，缓存键必须包含用户 ID，避免同一浏览器切换账号后复用上一账号的 App 列表。
    queryKey: ["admin-apps-visible", user?.id || "anonymous"],
    staleTime: 5 * 60 * 1000
  });
  const apps = useMemo(() => data?.items || [], [data?.items]);

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

  useEffect(() => {
    if (loading) {
      return;
    }
    if (!apps.length) {
      // 零授权是合法的通用模式；必须清掉历史 localStorage，否则请求层仍会偷偷发送上一次的 X-App-Code。
      if (appCode) {
        void applyAppCode("", { skipRefresh: true });
      }
      return;
    }
    const selectedExists = apps.some((item) => normalizeAppCode(item.appCode) === normalizeAppCode(appCode));
    if (!selectedExists) {
      void applyAppCode(apps[0].appCode, { skipRefresh: false });
    }
  }, [appCode, applyAppCode, apps, loading]);

  const value = useMemo(
    () => ({
      appCode,
      apps,
      error,
      hasAppAccess: apps.length > 0,
      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();
}
