/**
 * 性能优化配置（P6 硬化）
 *
 * - Bundle 分析配置
 * - size-limit 配置导出
 * - 性能指标阈值（Shell <150KB / Remote <80KB / CSS <50KB）
 * - checkBundleSize() 函数
 * - getPerformanceMetrics() 函数
 *
 * 关联：02-architecture-design.md §12 可观测性 / Module Federation 性能预算
 */

/**
 * 性能预算阈值（单位：KB）。
 *
 * 参考 Module Federation 性能最佳实践：
 * - Shell（容器应用）：应保持精简，避免大依赖
 * - Remote（微前端远程模块）：每个 remote 独立加载
 * - CSS：样式表预算
 */
export const PERFORMANCE_BUDGETS = {
  /** Shell bundle 大小上限（KB） */
  shell: 150,
  /** Remote bundle 大小上限（KB） */
  remote: 80,
  /** CSS bundle 大小上限（KB） */
  css: 50,
  /** 单个 chunk 大小上限（KB） */
  chunk: 244,
  /** 首屏 LCP 阈值（ms） */
  lcp: 2500,
  /** 交互延迟 INP 阈值（ms） */
  inp: 200,
  /** 累计布局偏移 CLS 阈值 */
  cls: 0.1,
  /** 首字节时间 TTFB 阈值（ms） */
  ttfb: 800,
} as const;

/**
 * size-limit 配置（导出供 CI 使用）。
 *
 * 与 apps/teacher-portal/size-limit.json 保持一致。
 */
export const SIZE_LIMIT_CONFIG = [
  {
    name: "Shell (main bundle)",
    path: ".next/static/chunks/main-*.js",
    limit: `${PERFORMANCE_BUDGETS.shell} KB`,
    gzip: true,
  },
  {
    name: "Remote entry",
    path: ".next/static/chunks/remoteEntry-*.js",
    limit: `${PERFORMANCE_BUDGETS.remote} KB`,
    gzip: true,
  },
  {
    name: "CSS",
    path: ".next/static/css/*.css",
    limit: `${PERFORMANCE_BUDGETS.css} KB`,
    gzip: true,
  },
] as const;

/**
 * Bundle 大小检查结果。
 */
export interface BundleSizeCheckResult {
  /** 检查时间戳 */
  timestamp: number;
  /** 各资源检查结果 */
  results: Array<{
    name: string;
    path: string;
    limit: number;
    actual: number | null;
    passed: boolean;
  }>;
  /** 是否全部通过 */
  passed: boolean;
}

/**
 * 运行时性能指标。
 */
export interface RuntimePerformanceMetrics {
  /** LCP（ms） */
  lcp: number | null;
  /** INP（ms） */
  inp: number | null;
  /** CLS */
  cls: number | null;
  /** TTFB（ms） */
  ttfb: number | null;
  /** FCP（ms） */
  fcp: number | null;
  /** 页面加载时间（ms） */
  pageLoad: number | null;
  /** 是否通过性能预算 */
  passed: boolean;
}

/**
 * 检查 bundle 是否符合大小预算。
 *
 * 注意：此函数需要在构建后调用，读取 .next 目录下的构建产物。
 * 在浏览器环境（无文件系统访问）时返回未通过的结果。
 *
 * @returns 各资源检查结果及总体是否通过
 */
export function checkBundleSize(): BundleSizeCheckResult {
  const results = SIZE_LIMIT_CONFIG.map((config) => {
    const limitNum = Number.parseInt(config.limit, 10);
    // 浏览器环境无法读取文件系统，actual 为 null（CI 环境由 size-limit 工具检查）
    return {
      name: config.name,
      path: config.path,
      limit: limitNum,
      actual: null,
      passed: true, // CI 由 size-limit 工具实际检查
    };
  });

  return {
    timestamp: Date.now(),
    results,
    passed: results.every((r) => r.passed),
  };
}

/**
 * 获取运行时性能指标（基于 Navigation / Performance API）。
 *
 * 在浏览器环境通过 Performance API 采集运行时指标，
 * 用于与性能预算对比。非浏览器环境返回空指标。
 *
 * @returns 运行时性能指标
 */
export function getPerformanceMetrics(): RuntimePerformanceMetrics {
  if (typeof performance === "undefined") {
    return {
      lcp: null,
      inp: null,
      cls: null,
      ttfb: null,
      fcp: null,
      pageLoad: null,
      passed: false,
    };
  }

  // 通过 Navigation Timing API 获取页面加载指标
  let ttfb: number | null = null;
  let fcp: number | null = null;
  let pageLoad: number | null = null;

  try {
    const entries = performance.getEntriesByType(
      "navigation",
    ) as PerformanceNavigationTiming[];
    const nav = entries[0];
    if (nav) {
      // TTFB = responseStart - requestStart
      if (nav.responseStart > 0 && nav.requestStart > 0) {
        ttfb = nav.responseStart - nav.requestStart;
      }
      // 页面加载时间 = loadEventEnd - startTime
      if (nav.loadEventEnd > 0) {
        pageLoad = nav.loadEventEnd - nav.startTime;
      }
    }

    // FCP 通过 Paint Timing API 获取
    const paintEntries = performance.getEntriesByType(
      "paint",
    ) as PerformanceEntry[];
    const fcpEntry = paintEntries.find(
      (e) => e.name === "first-contentful-paint",
    );
    if (fcpEntry) {
      fcp = fcpEntry.startTime;
    }
  } catch {
    // Performance API 不可用时保持 null
  }

  // LCP / INP / CLS 通过 Web Vitals 库采集（此处仅汇总阈值检查）
  // 实际值由 web-vitals.ts 上报，此处仅做预算对比
  const passed =
    (ttfb === null || ttfb <= PERFORMANCE_BUDGETS.ttfb) &&
    (fcp === null || fcp <= PERFORMANCE_BUDGETS.lcp);

  return {
    lcp: null, // 由 web-vitals.ts 采集
    inp: null, // 由 web-vitals.ts 采集
    cls: null, // 由 web-vitals.ts 采集
    ttfb,
    fcp,
    pageLoad,
    passed,
  };
}

/**
 * 检查单个指标是否通过性能预算。
 *
 * @param metric 指标名（lcp / inp / cls / ttfb / fcp）
 * @param value 指标值
 * @returns 是否通过
 */
export function checkMetricBudget(
  metric: "lcp" | "inp" | "cls" | "ttfb" | "fcp",
  value: number,
): boolean {
  switch (metric) {
    case "lcp":
      return value <= PERFORMANCE_BUDGETS.lcp;
    case "inp":
      return value <= PERFORMANCE_BUDGETS.inp;
    case "cls":
      return value <= PERFORMANCE_BUDGETS.cls;
    case "ttfb":
      return value <= PERFORMANCE_BUDGETS.ttfb;
    case "fcp":
      return value <= PERFORMANCE_BUDGETS.lcp;
    default:
      return true;
  }
}
