import { Injectable } from '@nestjs/common';
import { PersonaFeatureKey, FactType } from '@pac/types';
import type {
  ActiveFact,
  FeatureExtractor,
  FeatureExtractorContext,
  PersonaFeatureDraft,
} from './feature.interface';

/**
 * treatment_sensitivity 治疗敏感(D.2.2)— 规则层,snapshot · 多标签
 *
 * 标签:看牙恐惧 / 晕针 / 晕血 / 密闭恐惧。治疗中特殊敏感反应,影响医生匹配/舒缓/排班。
 *
 * 数据源:EMR 病历自由文本(emr_record.content:past_history 既往史 / illness_desc 现病史 /
 *   doctor_advice / disposal …)+ profile.notes/tags。宿主未给 health_profile,EMR 既往史已承载。
 *
 * ⚠️ 关键词按真实数据精炼(全量扫描验证,排假阳):
 *   看牙恐惧:恐惧(EMR 里基本都是牙科恐惧)+ 害怕看牙/牙科焦虑/看牙紧张 等"牙科+情绪"组合;
 *            ❌ 不用裸"紧张"(实为"颏肌紧张"正畸术语)/裸"害怕""焦虑"(无牙科语境)。
 *   晕针:晕针 / 害怕打针。
 *   晕血:晕血 / 见血不适;❌ 不用裸"见血"(实为"可见血凝块/探之见血"临床所见)。
 *   密闭恐惧:幽闭 / 密闭 / 长时间张口不适;❌ 不用裸"张口受限"(实为物理开口受限,智齿/感染)。
 *   全不命中 → 不打标签。
 */
@Injectable()
export class TreatmentSensitivityFeatureExtractor implements FeatureExtractor {
  readonly key = PersonaFeatureKey.TREATMENT_SENSITIVITY;

  private static readonly RULES: Array<{ code: string; zh: string; kw: string[] }> = [
    {
      code: 'dental_fear',
      zh: '看牙恐惧',
      kw: ['恐惧', '害怕看牙', '看牙害怕', '害怕看牙医', '畏惧看牙', '牙科焦虑', '看牙焦虑', '看牙紧张', '牙科紧张'],
    },
    { code: 'needle_faint', zh: '晕针', kw: ['晕针', '害怕打针', '怕打针'] },
    { code: 'blood_faint', zh: '晕血', kw: ['晕血', '见血不适', '见血恶心', '见血晕'] },
    { code: 'claustrophobia', zh: '密闭恐惧', kw: ['幽闭', '密闭', '长时间张口不适'] },
  ];

  extract(ctx: FeatureExtractorContext): PersonaFeatureDraft | null {
    const emrs = (ctx.factsByType.get(FactType.EMR_RECORD) ?? []) as ActiveFact[];
    // per-fact 文本(保留 id,供命中 fact 入证据)
    const emrTexts: Array<{ id: string; text: string }> = emrs.map((f) => {
      const c = (f.content ?? {}) as Record<string, unknown>;
      return {
        id: f.id,
        text: [
          c.illness_desc, c.pre_illness, c.past_history, c.general_condition,
          c.exam_findings, c.diagnosis_text, c.treatment_plan, c.doctor_advice, c.disposal,
        ].map((v) => String(v ?? '')).join(' '),
      };
    });
    const profileText = `${ctx.profile?.notes ?? ''} ${(ctx.profile?.tags ?? []).join(' ')}`;
    const hay = `${emrTexts.map((t) => t.text).join(' ')} ${profileText}`;
    if (!hay.trim()) return null;

    const codes: string[] = [];
    const labels: string[] = [];
    const evidenceIds = new Set<string>();
    for (const r of TreatmentSensitivityFeatureExtractor.RULES) {
      if (!r.kw.some((k) => hay.includes(k))) continue;
      codes.push(r.code);
      labels.push(r.zh);
      // 命中的 emr fact 入证据(profile 命中无 fact id)
      for (const t of emrTexts) {
        if (r.kw.some((k) => t.text.includes(k))) evidenceIds.add(t.id);
      }
    }
    if (codes.length === 0) return null;

    return {
      key: this.key,
      description: labels.join(' / '),
      score: null,
      data: { types: codes, labels },
      evidence: { factIds: [...evidenceIds] },
    };
  }
}
