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

/**
 * do_not_contact_status 不打扰状态(合规硬约束)
 *
 * 信号(任一命中即 DNC):
 *   - patient_profiles.doNotContact = true(host 主档标记 / 客服手动)
 *   - patient_profiles.deceased = true(已故)
 *   - 存在 active 或 fulfilled complaint_record(投诉过的合规避雷)
 *
 * 任一命中 → DNC=true,Plan 引擎必须拦截。
 *
 * **注意:phone 缺失不算 DNC** — phone 缺失是数据完整性问题(host 接入未覆盖),
 *   不是合规拒触达。description 会注明"待补充电话"提示客服补,但 score 不升。
 */
@Injectable()
export class DoNotContactStatusFeatureExtractor implements FeatureExtractor {
  readonly key = PersonaFeatureKey.DO_NOT_CONTACT_STATUS;

  extract(ctx: FeatureExtractorContext): PersonaFeatureDraft | null {
    const reasons: string[] = []; // DNC 硬命中原因(算分用)
    const warnings: string[] = []; // 数据完整性提示(不算 DNC,客服可见)
    const factIds: string[] = [];

    if (ctx.profile?.doNotContact) {
      reasons.push(
        `主档标记 do_not_contact${ctx.profile.doNotContactReason ? '(' + ctx.profile.doNotContactReason + ')' : ''}`,
      );
    }
    if (ctx.profile?.deceased) reasons.push('已故');

    const complaints = ctx.factsByType.get('complaint_record') ?? [];
    for (const f of complaints) {
      factIds.push(f.id);
      if (f.status === 'active' || f.status === 'fulfilled') {
        const c = f.content as Record<string, unknown>;
        const cat = (c.category as string | undefined) ?? '?';
        reasons.push(`投诉记录(${cat})`);
        break;
      }
    }

    // phone 缺失:仅提示,不计 DNC(避免 host 不给 phone 时全员误标)
    if (!ctx.patient.phone) warnings.push('待补充电话');

    const dnc = reasons.length > 0;
    let description: string;
    if (dnc) {
      description = `[DNC] 不可触达:${reasons.join(' / ')}`;
      if (warnings.length > 0) description += ` · ${warnings.join(' / ')}`;
    } else if (warnings.length > 0) {
      description = `[contactable] 可触达(${warnings.join(' / ')})`;
    } else {
      description = '[contactable] 可触达';
    }

    return {
      key: this.key,
      description,
      score: dnc ? 1 : 0,
      evidence: { factIds },
    };
  }
}
