import { Injectable, Logger } from '@nestjs/common';
import { Action } from '@pac/types';
import type { Parser } from './parser.interface';
import { EncounterParser } from './encounter.parser';
import { DiagnosisParser } from './diagnosis.parser';
import { TreatmentParser } from './treatment.parser';
import { RecommendationParser } from './recommendation.parser';
import { AppointmentParser } from './appointment.parser';
import { OrderParser } from './order.parser';
import { PaymentParser } from './payment.parser';
import { EmrParser } from './emr.parser';
import { ImageParser } from './image.parser';
import { RechargeParser } from './recharge.parser';
import { ComplaintParser } from './complaint.parser';
import { ReferralParser } from './referral.parser';
import { RefundParser } from './refund.parser';
import { ConsultationParser } from './consultation.parser';
import { VisitRegistrationParser } from './visit-registration.parser';
import { VisitReceptionParser } from './visit-reception.parser';

/**
 * ParserRegistry — Action → Parser 路由
 *
 * v2.1 重塑后(canonical-fact-layer.md §四):
 *   - encounter.parser 退化只产元数据
 *   - 拆出 diagnosis / treatment / recommendation 三个独立 parser,对应新 action
 *   - treatment 类 3 个 action(planned/started/completed)共用 TreatmentParser,内部判 kind/status
 *
 * 没注册 parser 的 action 由 pipeline 直接跳过(不报错)。
 */
@Injectable()
export class ParserRegistry {
  private readonly logger = new Logger(ParserRegistry.name);
  private readonly parsers = new Map<string, Parser>();

  constructor(
    private readonly encounterParser: EncounterParser,
    private readonly diagnosisParser: DiagnosisParser,
    private readonly treatmentParser: TreatmentParser,
    private readonly recommendationParser: RecommendationParser,
    private readonly appointmentParser: AppointmentParser,
    private readonly orderParser: OrderParser,
    private readonly paymentParser: PaymentParser,
    private readonly emrParser: EmrParser,
    private readonly imageParser: ImageParser,
    private readonly rechargeParser: RechargeParser,
    private readonly complaintParser: ComplaintParser,
    private readonly referralParser: ReferralParser,
    private readonly refundParser: RefundParser,
    private readonly consultationParser: ConsultationParser,
    private readonly visitRegistrationParser: VisitRegistrationParser,
    private readonly visitReceptionParser: VisitReceptionParser,
  ) {
    // 接诊(只元数据)
    this.register(Action.DOCTOR_ENCOUNTER_STARTED, encounterParser);

    // v2.1 拆出 — 临床三件套
    this.register(Action.DIAGNOSIS_RECORDED, diagnosisParser);
    this.register(Action.TREATMENT_PLANNED, treatmentParser);
    this.register(Action.TREATMENT_STARTED, treatmentParser);
    this.register(Action.TREATMENT_COMPLETED, treatmentParser);
    this.register(Action.RECOMMENDATION_EXTRACTED, recommendationParser);

    // 预约生命周期
    this.register(Action.APPOINTMENT_CREATED, appointmentParser);
    this.register(Action.APPOINTMENT_CHANGED, appointmentParser);
    this.register(Action.APPOINTMENT_CANCELLED, appointmentParser);
    this.register(Action.APPOINTMENT_FULFILLED, appointmentParser);

    // 医嘱 / 收款 / 退费
    this.register(Action.ORDER_SUBMITTED, orderParser);
    this.register(Action.PAYMENT_RECEIVED, paymentParser);
    this.register(Action.REFUND_CREATED, refundParser);

    // 病历(提交 / 打回)
    this.register(Action.EMR_SUBMITTED, emrParser);
    this.register(Action.EMR_REJECTED, emrParser);

    // 影像
    this.register(Action.IMAGE_UPLOADED, imageParser);

    // 接待流程
    this.register(Action.VISIT_REGISTERED, visitRegistrationParser);
    this.register(Action.RECEPTION_COMPLETED, visitReceptionParser);
    this.register(Action.CONSULTATION_CREATED, consultationParser);

    // 产品收集
    this.register(Action.RECHARGE_RECEIVED, rechargeParser);
    this.register(Action.COMPLAINT_FILED, complaintParser);
    this.register(Action.COMPLAINT_RESOLVED, complaintParser);
    this.register(Action.REFERRAL_RECORDED, referralParser);
  }

  register(action: Action | string, parser: Parser): void {
    if (this.parsers.has(action)) {
      this.logger.warn(`overriding parser for action=${action}`);
    }
    this.parsers.set(action, parser);
  }

  get(action: Action | string): Parser | null {
    return this.parsers.get(action) ?? null;
  }

  has(action: Action | string): boolean {
    return this.parsers.has(action);
  }

  list(): string[] {
    return [...this.parsers.keys()];
  }
}
