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[];
    const parts: string[] = [];
    for (const f of emrs) {
      const c = (f.content ?? {}) as Record<string, unknown>;
      parts.push(
        String(c.illness_desc ?? ''),
        String(c.pre_illness ?? ''),
        String(c.past_history ?? ''),
        String(c.general_condition ?? ''),
        String(c.exam_findings ?? ''),
        String(c.diagnosis_text ?? ''),
        String(c.treatment_plan ?? ''),
        String(c.doctor_advice ?? ''),
        String(c.disposal ?? ''),
      );
    }
    parts.push(ctx.profile?.notes ?? '', (ctx.profile?.tags ?? []).join(' '));
    const hay = parts.join(' ');
    if (!hay.trim()) return null;

    const codes: string[] = [];
    const labels: string[] = [];
    for (const r of TreatmentSensitivityFeatureExtractor.RULES) {
      if (r.kw.some((k) => hay.includes(k))) {
        codes.push(r.code);
        labels.push(r.zh);
      }
    }
    if (codes.length === 0) return null;

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