// GraphQL client (urql)
// 依据：02-architecture-design.md §4.2 GraphQL 接入、F9 裁决（首次即 GraphQL）
// 端点：POST /api/v1/parent/graphql（经 api-gateway 代理到 parent-bff）
// 认证：Authorization: Bearer <token>（F12 localStorage token）
// 刷新：401 时触发 refreshAccessToken，重试原请求

import { Client, fetchExchange, cacheExchange } from "urql";
import { getAuthHeaders, refreshAccessToken, getToken } from "./auth";

const GRAPHQL_ENDPOINT =
  process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || "/api/v1/parent/graphql";

/**
 * 自定义 fetch：注入 Authorization header + 401 刷新重试
 */
async function authedFetch(
  input: RequestInfo | URL,
  init?: RequestInit,
): Promise<Response> {
  const authHeaders = getAuthHeaders();
  const headers = new Headers(init?.headers || {});
  for (const [k, v] of Object.entries(authHeaders)) {
    headers.set(k, v);
  }
  headers.set("X-Requested-With", "XMLHttpRequest");

  let response = await fetch(input, { ...init, headers });

  // 401 → 刷新 token 后重试一次
  if (response.status === 401) {
    const newToken = await refreshAccessToken();
    if (newToken) {
      headers.set("Authorization", `Bearer ${newToken}`);
      response = await fetch(input, { ...init, headers });
    }
  }

  return response;
}

/**
 * 创建 urql client（单例）
 */
export function createGraphQLClient(): Client {
  return new Client({
    url: GRAPHQL_ENDPOINT,
    fetch: authedFetch as unknown as typeof fetch,
    exchanges: [cacheExchange, fetchExchange],
    fetchOptions: (): RequestInit => {
      const token = getToken();
      const headers: Record<string, string> = {};
      if (token) {
        headers.Authorization = `Bearer ${token}`;
      }
      return { headers };
    },
  });
}

// 全局单例（SSR 安全：仅客户端创建）
let client: Client | null = null;

export function getGraphQLClient(): Client {
  if (typeof window === "undefined") {
    // SSR：每次创建新实例（避免请求间状态泄漏）
    return createGraphQLClient();
  }
  if (!client) {
    client = createGraphQLClient();
  }
  return client;
}
