/**
 * teacher-portal Next.js 配置
 *
 * 角色：MF Shell 宿主（ARB-002 §2.3）
 * - exposes: AppShell + GraphQLProvider + 共享 hooks + 共享 UI 组件
 * - shared: react/react-dom/urql/graphql/@edu/* 设为 singleton
 * - remotes: P2 为空（NEXT_PUBLIC_MF_ENABLED=false），P3+ 逐步接入
 *
 * 维护者：ai13（teacher-portal）
 * 关联：ARB-002 §2.2 暴露清单、03-long-term-architecture.md §1.3 绞杀者模式
 */

/** @type {import('next').NextConfig} */

// NextFederationPlugin 动态 require，避免构建时硬依赖（MF 2.0 在 Next 14 App Router 下按需加载）
let NextFederationPlugin;
try {
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  NextFederationPlugin = require("@module-federation/nextjs-mf").NextFederationPlugin;
} catch {
  // 依赖未安装时跳过 MF 配置（如纯 typecheck 环境）
  NextFederationPlugin = null;
}

/**
 * 构建 Remote 列表（P2 为空，P3+ 按 NEXT_PUBLIC_MF_ENABLED 启用）
 *
 * ARB-002 §2.3：P2 Remote 数量 = 0，NEXT_PUBLIC_MF_ENABLED=false 默认关
 * P3 首个 Remote：student-portal（总裁 §1.3 step 4）
 */
function buildRemotes(isServer) {
  if (process.env.NEXT_PUBLIC_MF_ENABLED !== "true") return {};
  const chunkPath = isServer ? "ssr" : "chunks";
  return {
    student: `student_app@http://localhost:4001/_next/static/${chunkPath}/remoteEntry.js`,
    parent: `parent_app@http://localhost:4002/_next/static/${chunkPath}/remoteEntry.js`,
    admin: `admin_app@http://localhost:4003/_next/static/${chunkPath}/remoteEntry.js`,
  };
}

/**
 * ARB-002 §2.2 MF Shell 暴露清单
 */
function buildExposes() {
  return {
    // 1. AppShell（布局 + 导航 + 认证守卫）
    "./AppShell": "./src/components/AppShell.tsx",
    // 2. GraphQLProvider（urql client 单例，总裁 §2.17 方案 A）
    "./GraphQLProvider": "./src/app/providers.tsx",
    // 3. 共享 hooks
    "./useAuth": "./packages/hooks/src/use-auth.ts",
    "./usePermission": "./packages/hooks/src/use-permission.ts",
    "./useGraphQLClient": "./packages/hooks/src/use-graphql-client.ts",
    // 4. 共享 UI 组件
    "./ErrorBoundary": "./packages/ui-components/src/error-boundary.tsx",
    "./Loading": "./packages/ui-components/src/loading.tsx",
    "./Empty": "./packages/ui-components/src/empty.tsx",
    "./RequirePermission": "./packages/ui-components/src/require-permission.tsx",
  };
}

/**
 * ARB-002 §2.2 MF shared singleton 配置
 * 避免 Remote 多实例 + 缓存不一致
 */
function buildShared() {
  return {
    react: { singleton: true, requiredVersion: "^18.3.0" },
    "react-dom": { singleton: true, requiredVersion: "^18.3.0" },
    urql: { singleton: true, requiredVersion: "^2.2.0" },
    graphql: { singleton: true, requiredVersion: "^16.8.0" },
    "@edu/ui-tokens": { singleton: true },
    "@edu/ui-components": { singleton: true },
    "@edu/hooks": { singleton: true },
  };
}

const nextConfig = {
  reactStrictMode: true,

  // standalone 模式：Next.js 自动打包所有依赖到 .next/standalone
  // 解决 pnpm symlink 在 Docker runtime 下无法解析 react/jsx-runtime 的问题
  output: "standalone",

  // ESM 模式：transpilePackages 对齐 NestJS ESM 规范
  // @edu/hooks 等包使用 .js 后缀导入源码，需 transpile + extensionAlias
  transpilePackages: [
    "@edu/ui-components",
    "@edu/ui-tokens",
    "@edu/hooks",
    "@edu/contracts",
    "@edu/shared-ts",
  ],

  // ARB-002：MF Shell 配置（exposes + shared，P2 无 remotes）
  // 仅当 NEXT_PUBLIC_MF_ENABLED=true 时实例化 NextFederationPlugin
  // （nextjs-mf 不支持 App Directory，P2 阶段 MF 未启用时跳过避免报错）
  webpack(config, { isServer }) {
    // ESM 包使用 .js 后缀导入源码（TS 文件），需映射 .js → .ts
    config.resolve = config.resolve || {};
    config.resolve.extensionAlias = {
      ...config.resolve.extensionAlias,
      ".js": [".ts", ".tsx", ".js"],
    };

    if (
      NextFederationPlugin &&
      process.env.NEXT_PUBLIC_MF_ENABLED === "true"
    ) {
      config.plugins.push(
        new NextFederationPlugin({
          name: "teacher_app",
          filename: "static/chunks/remoteEntry.js",
          remotes: buildRemotes(isServer),
          exposes: buildExposes(),
          shared: buildShared(),
          extraOptions: {
            exposePages: false,
          },
        }),
      );
    }
    return config;
  },

  // 反向代理：/api/v1/* → api-gateway :8080
  async rewrites() {
    const gateway = process.env.API_GATEWAY_URL || "http://localhost:8080";
    return [
      {
        source: "/api/v1/:path*",
        destination: `${gateway}/api/v1/:path*`,
      },
      {
        // 登录端点（非 GraphQL，认证前提，F12: JWT 存 localStorage）
        // 映射到 iam REST controller 路径 /v1/iam/*（iam.controller.ts @Controller("v1/iam")）
        source: "/api/auth/:path*",
        destination: `${gateway}/api/v1/iam/:path*`,
      },
    ];
  },
};

module.exports = nextConfig;
