/**
 * OpenTelemetry browser SDK 初始化（P6 硬化）
 *
 * - 自动埋点 fetch / XHR / document load
 * - 导出到 OTLP collector（endpoint 从环境变量读取）
 * - 条件初始化（NEXT_PUBLIC_OTEL_ENABLED=true 时）
 * - 使用动态 import 加载 @opentelemetry/* 包，避免未安装包导致构建失败
 *
 * 关联：02-architecture-design.md §12 可观测性 / project_rules §12 可观测性规范
 */

import { getObservabilityConfig } from "@/lib/observability/env";

/**
 * OTel SDK 的最小类型声明（仅声明使用的 API 子集）。
 * 避免对未安装包的静态类型依赖。
 */
interface OTelAutoInstrumentationType {
  registerInstrumentations(options: { instrumentations: unknown[] }): void;
}

interface OTelExporterType {
  OTLPTraceExporter: new (config: { url: string }) => unknown;
  BatchSpanProcessor: new (exporter: unknown) => unknown;
  WebTracerProvider: new () => unknown;
}

interface ZoneContextManagerType {
  ZoneContextManager: new () => { enable(): unknown };
}

/** 初始化状态标记 */
let initialized = false;

/**
 * 初始化 OpenTelemetry browser SDK。
 *
 * 条件初始化：仅在 NEXT_PUBLIC_OTEL_ENABLED=true 且 endpoint 已配置时启用。
 * 使用动态 import 加载 @opentelemetry/* 各包。
 *
 * @returns 是否成功初始化
 */
export async function initOTel(): Promise<boolean> {
  if (initialized) return false;

  const config = getObservabilityConfig();
  if (!config.otelEnabled) {
    initialized = true;
    return false;
  }
  if (config.otelEndpoint === null) {
    if (typeof console !== "undefined") {
      console.warn(
        "[parent-portal] OTel 已启用但未配置 NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT，跳过初始化",
      );
    }
    initialized = true;
    return false;
  }

  try {
    // 动态加载 OTel 各包（运行时按需加载）
    // webpackIgnore: true 让 webpack 跳过这些模块的静态分析，
    // 这样即使 @opentelemetry/* 未安装（optionalDependencies）也能构建成功
    const instrumentation = (await import(
      /* webpackIgnore: true */ "@opentelemetry/instrumentation"
    )) as unknown as OTelAutoInstrumentationType;
    const fetchInstrumentationMod = await import(
      /* webpackIgnore: true */ "@opentelemetry/instrumentation-fetch"
    );
    const xhrInstrumentationMod = await import(
      /* webpackIgnore: true */ "@opentelemetry/instrumentation-xml-http-request"
    );
    const documentLoadMod = await import(
      /* webpackIgnore: true */ "@opentelemetry/instrumentation-document-load"
    );
    const webTracerMod = (await import(
      /* webpackIgnore: true */ "@opentelemetry/sdk-trace-web"
    )) as unknown as OTelExporterType;
    const exporterMod = (await import(
      /* webpackIgnore: true */ "@opentelemetry/exporter-trace-otlp-http"
    )) as unknown as OTelExporterType;
    const contextManagerMod = (await import(
      /* webpackIgnore: true */ "@opentelemetry/context-zone"
    )) as unknown as ZoneContextManagerType;

    // 构造 FetchInstrumentation
    const FetchInstrumentation = (
      fetchInstrumentationMod as unknown as {
        FetchInstrumentation: new (config: unknown) => unknown;
      }
    ).FetchInstrumentation;
    const XHRInstrumentation = (
      xhrInstrumentationMod as unknown as {
        XMLHttpRequestInstrumentation: new (config: unknown) => unknown;
      }
    ).XMLHttpRequestInstrumentation;
    const DocumentLoadInstrumentation = (
      documentLoadMod as unknown as {
        DocumentLoadInstrumentation: new () => unknown;
      }
    ).DocumentLoadInstrumentation;

    const contextManager = new contextManagerMod.ZoneContextManager();
    (contextManager as unknown as { enable(): unknown }).enable();

    const exporter = new exporterMod.OTLPTraceExporter({
      url: config.otelEndpoint,
    });

    const provider = new webTracerMod.WebTracerProvider();
    const processor = new webTracerMod.BatchSpanProcessor(exporter);

    // 注册 provider（类型宽松处理：OTel SDK 内部多态）
    (
      provider as unknown as {
        addSpanProcessor: (processor: unknown) => void;
        register: (options: { contextManager: unknown }) => void;
      }
    ).addSpanProcessor(processor);
    (
      provider as unknown as {
        register: (options: { contextManager: unknown }) => void;
      }
    ).register({ contextManager });

    // 注册自动埋点
    instrumentation.registerInstrumentations({
      instrumentations: [
        new FetchInstrumentation({
          propagateTraceHeaderCorsUrls: ["*"],
        }),
        new XHRInstrumentation({}),
        new DocumentLoadInstrumentation(),
      ],
    });

    initialized = true;

    if (
      typeof console !== "undefined" &&
      config.environment === "development"
    ) {
      console.info("[parent-portal] OTel browser SDK 已初始化", {
        endpoint: config.otelEndpoint,
      });
    }

    return true;
  } catch (err) {
    // @opentelemetry/* 包未安装或加载失败，降级到无追踪
    if (typeof console !== "undefined") {
      console.warn("[parent-portal] OTel 加载失败，降级到无追踪", err);
    }
    initialized = true;
    return false;
  }
}

/** OTel 是否已初始化 */
export function isOTelInitialized(): boolean {
  return initialized;
}
