import { Injectable, Logger } from '@nestjs/common';
import { Action, FactKind, FactStatus, FactType } from '@pac/types';
import type { FactDraft, Parser, ParserContext } from './parser.interface';

/**
 * EmrParser — `emr_submitted` / `emr_rejected` 解析器
 *
 * 产 1 个 `emr_record`(actual);质控信息(原 emr_quality_record)塞 content.qualityCheck。
 *
 * 关联接诊:content.encounter_external_id(由 canonical 提供)— 召回算法
 * 可按"哪份 EMR 关联哪次接诊"反查。
 */
@Injectable()
export class EmrParser implements Parser {
  readonly name = Action.EMR_SUBMITTED;
  private readonly logger = new Logger(EmrParser.name);

  /// 规整为文本:examine/dispose 在 host 是 JSON 文本,但 CH 读取层会把像 JSON 的
  /// String 自动 parse 成 object/array。这里统一存回 JSON 原文字符串(content schema 要 string,
  /// Layer C 后续自己 parse)。纯文本字段经此原样返回。
  private asText(v: unknown): string | null {
    if (v == null) return null;
    if (typeof v === 'string') return v;
    return JSON.stringify(v);
  }

  parse(ctx: ParserContext): FactDraft[] {
    const c = ctx.canonicalRow;
    const externalId = String(c.externalId ?? ctx.transaction.subjectId).trim();
    if (!externalId) {
      this.logger.warn(
        `emr parser: missing externalId for transaction=${ctx.transaction.id};skip`,
      );
      return [];
    }

    const encounterExternalId = (c.encounterExternalId as string | undefined) ?? null;
    const qualityStatus = (c.qualityStatus as string | undefined) ?? null;
    const rejected = ctx.transaction.action === Action.EMR_REJECTED;

    return [
      {
        subjectId: `${FactType.EMR_RECORD}:${externalId}`,
        kind: FactKind.ACTUAL,
        type: FactType.EMR_RECORD,
        status: rejected ? FactStatus.INVALIDATED : FactStatus.ACTIVE,
        clinicId: ctx.transaction.clinicId,
        // 用 transaction.occurredAt(= emr.yaml occurredAtField=createdAt,精确就诊时刻),
        // 跟 diagnosis/treatment/encounter parser 一致。原来用 submittedAt(=rq 纯日期)→ 同日多医生
        // (转诊场景)时间打平、病历快读排序错乱。
        occurredAt: ctx.transaction.occurredAt,
        title: `电子病历 ${externalId}${rejected ? '(质控打回)' : ''}`,
        summary: encounterExternalId ? `关联接诊:${encounterExternalId}` : null,
        content: {
          emr_external_id: externalId,
          encounter_external_id: encounterExternalId,
          doctor_id: this.asText(c.doctorId), // host user_id(医生),与 settlement.doctor_id 同源
          doctor_name: this.asText(c.doctorName), // 接诊医生名(快照,PAC 不建医生表)
          // SOAP 自由文本段落(canonical 字段由 emr.yaml field_mapping 翻译)
          // PAC 标准病历字段全集(宿主映射不上的自然 null,如瑞尔的 diagnosis_text/treatment_plan)
          illness_desc: this.asText(c.illnessDesc),
          pre_illness: this.asText(c.preIllness),
          past_history: this.asText(c.pastHistory),
          general_condition: this.asText(c.generalCondition),
          exam_findings: this.asText(c.examFindings), // host examine 原文(JSON,带牙位)
          diagnosis_text: this.asText(c.diagnosisText), // 结构化宿主留 null,自由文本宿主有值
          treatment_plan: this.asText(c.treatmentPlan), // 同上
          disposal: this.asText(c.disposal), // host dispose 原文(JSON)
          doctor_advice: this.asText(c.doctorAdvice), // host doc_order
          quality_check: qualityStatus
            ? {
                status: qualityStatus,
                rejected,
                reject_reason: c.rejectReason ?? null,
              }
            : null,
        },
      },
    ];
  }
}
