import { Module } from '@nestjs/common';
import { TreatProviderModule } from '../treat/provider/treat-provider.module';
import { TreatModule } from '../treat/treat.module';
import { AlertAdminController } from './alert-admin.controller';
import { AlertHealthService } from './alert-health.service';
import { AlertMonitorService } from './alert-monitor.service';
import { AlertPermissionController } from './alert-permission.controller';
import { AlertSettingsService } from './alert-settings.service';
import { AlertSignalService } from './alert-signal.service';
import { ALERT_RULE, AlertRule } from './alert.entity';
import { AlertRepository } from './alert.repository';
import { AlertService } from './alert.service';
import { ApiErrorRateRule } from './rules/api-error-rate.rule';
import { InfraHealthRule } from './rules/infra-health.rule';
import { ScheduleHeartbeatRule } from './rules/schedule-heartbeat.rule';
import { SubscriptionPaymentRule } from './rules/subscription-payment.rule';
import { TreatMonitorRule } from './rules/treat-monitor.rule';
import { TreatVendorRule } from './rules/treat-vendor.rule';

//* 신규 알림 타입 추가 = 규칙 파일 1개(신규) + 이 배열에 1줄 (M6).
//*  NestJS 에는 Angular 식 `multi: true` 가 없으므로 배열을 팩토리로 모아 ALERT_RULE 에 넣는다.
//*
//* **export 하는 이유**: 설정 메타 계약 spec 이 이 배열을 그대로 전수한다. 스펙이 규칙 목록을
//*  따로 적으면 규칙이 하나 늘었을 때 계약이 그 규칙을 조용히 빼놓고 통과한다 — 표본이지 범위가
//*  아니게 된다. 등록의 사실 소스는 여기 하나다.
export const ALERT_RULES = [
  TreatMonitorRule,
  SubscriptionPaymentRule, //* A1 (M2)
  ScheduleHeartbeatRule, //* A3 (M2)
  ApiErrorRateRule, //* A4 (M2)
  InfraHealthRule, //* A6 Redis·API 축 (M2). DB 축은 AlertService.run() 폴백이 진다(§D7)
  TreatVendorRule, //* M4 — 기본 OFF 로 시드해 배포한다(§D9 · migrations/alert-vendor-rule)
];

//* 알림의 단일 발송 경로. DrizzleService 는 글로벌이라 주입 불필요.
@Module({
  imports: [TreatModule, TreatProviderModule],
  //* 권한 **판정** 엔드포인트는 별도 컨트롤러다(§D5) — 알림 설정 가드가 클래스 레벨이라
  //*  같은 컨트롤러에 두면 "아니오" 라는 답이 403 이 되어 진입 아이콘이 판정을 못 받는다.
  controllers: [AlertAdminController, AlertPermissionController],
  providers: [
    AlertService,
    AlertRepository,
    AlertSettingsService,
    AlertSignalService,
    AlertHealthService,
    AlertMonitorService, //* GET /monitor 조립부(M3 §D8). 읽기 전용이라 export 하지 않는다
    ...ALERT_RULES,
    {
      provide: ALERT_RULE,
      useFactory: (...rules: AlertRule[]) => rules,
      inject: [...ALERT_RULES],
    },
  ],
  //* AlertSignalService — main.ts 의 예외 필터·인터셉터와 스케줄러 하트비트가 app.get() 으로 꺼낸다.
  //*  AlertHealthService — AppController 의 GET /health/detail 이 쓴다.
  exports: [AlertService, AlertSignalService, AlertHealthService],
})
export class AlertModule {}
