// 客户端 Providers：QueryClient + Urql + MSW + ErrorBoundary + SW + OTel + WebVitals
// 依据：02-architecture-design.md §4.3 状态管理分层、§8 MSW、§12 可观测性
// - NEXT_PUBLIC_API_MOCKING=enabled 时启动 MSW worker
// - QueryClient 单例（useState 保持稳定）
// - Urql client 单例
// - ErrorBoundary 包裹全局渲染异常兜底
// - Service Worker 注册（PWA 离线缓存，P6-5）
// - OTel browser SDK 初始化（P6-1，条件启用）
// - Web Vitals 采集初始化（P6-1，生产环境）

"use client";

import { useState, useEffect, type ReactNode } from "react";
import { QueryClientProvider } from "@tanstack/react-query";
import { Provider as UrqlProvider } from "urql";
import { createQueryClient } from "@/lib/query-client";
import { getGraphQLClient } from "@/lib/graphql-client";
import { ErrorBoundary } from "@/components/ErrorBoundary";
import { WebVitalsInitializer } from "@/components/WebVitalsInitializer";

const isMockingEnabled = process.env.NEXT_PUBLIC_API_MOCKING === "enabled";

interface ProvidersProps {
  children: ReactNode;
}

export function Providers({ children }: ProvidersProps) {
  const [queryClient] = useState(() => createQueryClient());
  const [urqlClient] = useState(() => getGraphQLClient());
  const [mswReady, setMswReady] = useState(!isMockingEnabled);

  // MSW 初始化（仅浏览器 + mock 开启时）
  useEffect(() => {
    if (!isMockingEnabled || typeof window === "undefined") return;
    let active = true;
    (async () => {
      try {
        const { worker } = await import("@/test/mocks/browser");
        await worker.start({
          onUnhandledRequest: "bypass",
          serviceWorker: {
            url: "/mockServiceWorker.js",
          },
        });
        if (active) setMswReady(true);
      } catch (err) {
        // MSW 启动失败不阻塞应用
        console.warn("[MSW] 启动失败，将使用真实 API", err);
        if (active) setMswReady(true);
      }
    })();
    return () => {
      active = false;
    };
  }, []);

  // Service Worker 注册（PWA，P6-5）
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (process.env.NODE_ENV !== "production") return;
    if (!("serviceWorker" in navigator)) return;

    const registerSW = async () => {
      try {
        // MSW 启用时不注册 PWA Service Worker（避免冲突）
        if (isMockingEnabled) return;
        await navigator.serviceWorker.register("/sw.js", { scope: "/" });
      } catch {
        // SW 注册失败不阻塞应用
      }
    };
    registerSW();
  }, []);

  // OTel browser SDK 初始化（P6-1，条件启用：NEXT_PUBLIC_OTEL_ENABLED=true）
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (process.env.NODE_ENV !== "production") return;
    void import("@/lib/observability/otel").then(({ initOTel }) => {
      void initOTel();
    });
  }, []);

  // MSW 未就绪时显示加载态（避免 mock 数据未注入时闪烁）
  if (!mswReady) {
    return (
      <div
        role="status"
        aria-live="polite"
        className="flex min-h-screen items-center justify-center"
      >
        <span className="skeleton h-8 w-48 rounded" />
      </div>
    );
  }

  return (
    <ErrorBoundary>
      <QueryClientProvider client={queryClient}>
        <UrqlProvider value={urqlClient}>
          <WebVitalsInitializer />
          {children}
        </UrqlProvider>
      </QueryClientProvider>
    </ErrorBoundary>
  );
}
