"use client";

/**
 * GraphQLProvider - urql client 单例 Provider
 *
 * 总裁裁决 §2.17 方案 A：Shell（teacher-portal）暴露 GraphQLProvider，
 * Remote（student/parent/admin-portal）复用同一 client 单例。
 *
 * ARB-002 §2.2：通过 MF exposes './GraphQLProvider' 暴露给 Remote。
 *
 * MSW 启用：NEXT_PUBLIC_API_MOCKING=enabled 时在客户端注册 Service Worker
 *
 * 维护者：ai13（teacher-portal）
 */

import { useEffect, useMemo, useState } from "react";
import { Provider } from "urql";
import type { ReactNode } from "react";
import { GraphQLClientContext } from "@edu/hooks";
import { createGraphQLClient } from "@/lib/graphql";
import { initMocks } from "@/mocks";

export interface GraphQLProviderProps {
  children: ReactNode;
}

/**
 * GraphQLProvider
 *
 * 初始化 urql client 单例，通过 React Context 注入给所有子组件 + Remote。
 * MF shared singleton 配置确保 Remote 复用同一 client 实例（ARB-002 §2.2）。
 *
 * MSW 初始化在客户端渲染前异步完成，避免请求未拦截。
 */
export function GraphQLProvider({ children }: GraphQLProviderProps): ReactNode {
  const client = useMemo(() => createGraphQLClient(), []);
  const [mswReady, setMswReady] = useState(false);

  useEffect(() => {
    let mounted = true;
    initMocks().finally(() => {
      if (mounted) setMswReady(true);
    });
    return () => {
      mounted = false;
    };
  }, []);

  // MSW 未启用时直接渲染（initMocks 内部判断）
  if (!mswReady && process.env.NEXT_PUBLIC_API_MOCKING === "enabled") {
    return null;
  }

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

export default GraphQLProvider;
