import {
  Module,
  Inject,
  type OnModuleInit,
  type OnModuleDestroy,
} from "@nestjs/common";
import { ClientsModule } from "../../clients/clients.module.js";
import type { MsgClient } from "../../clients/msg.client.js";
import type { PushHttpClient } from "../../clients/http/push-http.client.js";
import { logger } from "../observability/logger.js";
import { createKafkaConsumer, KafkaEventConsumer } from "./kafka.consumer.js";
import { NotificationPushHandler } from "./handlers/notification-push.handler.js";
import { CacheInvalidationHandler } from "./handlers/cache-invalidation.handler.js";

/**
 * Kafka 事件订阅模块（P5，对齐 02-architecture-design.md §5.3）。
 *
 * Handler 注册矩阵：
 * | Topic                          | PushHandler | CacheHandler |
 * |--------------------------------|:-----------:|:------------:|
 * | edu.notification.sent          | ✅          | —            |
 * | edu.notification.read          | —           | ✅           |
 * | edu.notification.recalled      | —           | ✅           |
 * | edu.teaching.grade.recorded    | ✅          | ✅           |
 * | edu.teaching.homework.graded   | ✅          | ✅           |
 * | edu.teaching.exam.published    | ✅          | ✅           |
 *
 * lifecycle：
 * - OnModuleInit：start() 启动消费者
 * - OnModuleDestroy：stop() 优雅关闭
 *
 * KAFKA_BROKERS 未配置时不启动消费者（DEV_MODE 兼容）。
 */
@Module({
  imports: [ClientsModule],
  providers: [
    {
      provide: "KAFKA_CONSUMER",
      useFactory: (
        msgClient: MsgClient,
        pushClient: PushHttpClient,
      ): KafkaEventConsumer | null => {
        const consumer = createKafkaConsumer();
        if (!consumer) return null;

        const pushHandler = new NotificationPushHandler(msgClient, pushClient);
        const cacheHandler = new CacheInvalidationHandler();

        // 通知事件
        consumer.registerHandler("edu.notification.sent", pushHandler);
        consumer.registerHandler("edu.notification.read", cacheHandler);
        consumer.registerHandler("edu.notification.recalled", cacheHandler);

        // 教学事件（双 handler：推送 + 缓存失效）
        consumer.registerHandler("edu.teaching.grade.recorded", pushHandler);
        consumer.registerHandler("edu.teaching.grade.recorded", cacheHandler);
        consumer.registerHandler("edu.teaching.homework.graded", pushHandler);
        consumer.registerHandler("edu.teaching.homework.graded", cacheHandler);
        consumer.registerHandler("edu.teaching.exam.published", pushHandler);
        consumer.registerHandler("edu.teaching.exam.published", cacheHandler);

        return consumer;
      },
      inject: ["MSG_CLIENT", "PUSH_HTTP_CLIENT"],
    },
  ],
})
export class KafkaModule implements OnModuleInit, OnModuleDestroy {
  constructor(
    @Inject("KAFKA_CONSUMER")
    private readonly consumer: KafkaEventConsumer | null,
  ) {}

  async onModuleInit(): Promise<void> {
    if (this.consumer) {
      await this.consumer.start();
      logger.info("KafkaModule: consumer started");
    } else {
      logger.info("KafkaModule: consumer disabled (KAFKA_BROKERS not set)");
    }
  }

  async onModuleDestroy(): Promise<void> {
    if (this.consumer) {
      await this.consumer.stop();
    }
  }
}
