/**
 * student-bff DownstreamClient NestJS Module.
 *
 * 仲裁依据: coord-final-decisions §2 B8 (3 BFF 复用 shared-ts 抽象)
 *
 * 提供:
 *   - 全局共享 DownstreamClient 实例 (@Injectable)
 *   - 启动时注入 mock 数据提供器 (env.MOCK_UPSTREAM=true 时)
 *   - OnModuleDestroy 优雅关闭 gRPC 连接 (G9)
 */
import { Global, Module, OnModuleDestroy, OnModuleInit } from "@nestjs/common";
import { DownstreamClient } from "@edu/shared-ts/bff";
import { downstreamClientConfig } from "../../config/downstream.js";
import { studentBffMockProvider } from "../../config/mock-data.js";
import { logger } from "../observability/logger.js";

export const DOWNSTREAM_CLIENT = Symbol("DOWNSTREAM_CLIENT");

@Global()
@Module({
  providers: [
    {
      provide: DOWNSTREAM_CLIENT,
      useFactory: (): DownstreamClient => {
        const client = new DownstreamClient(downstreamClientConfig);
        if (downstreamClientConfig.mockUpstream) {
          client.setMockProvider(studentBffMockProvider);
          logger.warn(
            "MOCK_UPSTREAM=true, all downstream calls return mock data",
          );
        }
        return client;
      },
    },
    {
      provide: DownstreamClient,
      useExisting: DOWNSTREAM_CLIENT,
    },
  ],
  exports: [DownstreamClient, DOWNSTREAM_CLIENT],
})
export class DownstreamModule implements OnModuleInit, OnModuleDestroy {
  constructor() {}

  async onModuleInit(): Promise<void> {
    const enabled = downstreamClientConfig.services
      .filter((s) => s.enabled)
      .map((s) => s.name);
    logger.info(
      { enabled, mock: downstreamClientConfig.mockUpstream },
      "DownstreamClient initialized",
    );
  }

  async onModuleDestroy(): Promise<void> {
    // G9 优雅关闭: 关闭所有 gRPC 连接
    // DownstreamClient 实例由 NestJS 容器管理, 这里通过 token 获取
    // 但 Module destroy 阶段不能注入, 实际由 main.ts SIGTERM handler 统一关闭
    logger.info("DownstreamModule destroyed");
  }
}
