import type { PersonaFeatureKey } from '@pac/types';
import type { Prisma } from '@prisma/client';

/**
 * Feature Extractor 接口
 *
 * 输入:patient 主档 + profile + 所有 active facts
 * 输出:0 / 1 个 PersonaFeatureDraft(规则路径下通常每个 extractor 1 个 feature)
 *
 * 设计纪律:
 *   - description 是**自包含自然语言**,客服 / 主管能直接看懂,不依赖 score / evidence
 *   - score 是可选数值排序辅助,**不能替代 description 的语义**
 *   - evidence.factIds 必填 — 反查 fact → transaction → rawPayload 的证据链
 *   - 单个 extractor 失败不影响其他;Persona 整体 status=partial
 */
export interface FeatureExtractorContext {
  patient: {
    id: string;
    externalId: string;
    name: string | null;
    phone: string | null;
    gender: string | null;
    birthDate: Date | null;
    active: boolean;
  };
  profile: {
    doNotContact: boolean;
    doNotContactReason: string | null;
    deceased: boolean;
    tags: string[];
    notes: string | null;
    primaryContactType: string | null;
  } | null;
  /// 该 patient 的所有 active facts(按 type 索引方便查)
  factsByType: Map<string, ActiveFact[]>;
  /// today 锚点(测试时可注入固定时间)
  now: Date;
}

export interface ActiveFact {
  id: string;
  subjectId: string;
  type: string;
  kind: string;
  status: string;
  occurredAt: Date | null;
  plannedFor: Date | null;
  clinicId: string | null;
  content: Prisma.JsonValue;
}

export interface PersonaFeatureDraft {
  key: PersonaFeatureKey;
  description: string;
  score?: number | null;
  /// 结构化特征值(可空)→ 落 persona_features.data 列。description 人读、score 排序、
  /// data 给 scorer / UI 结构化消费(如权益身份 insurers / lastInsuranceAt / monthsSinceLast)。
  data?: Record<string, unknown> | null;
  /// 证据反查 fact + AI 调用;**不存 ruleIds 字符串常量**(版本追溯靠 git + persona.createdAt)
  evidence: {
    factIds: string[];
    agentInvocationIds?: string[];
  };
}

export interface FeatureExtractor {
  readonly key: PersonaFeatureKey;
  extract(ctx: FeatureExtractorContext): PersonaFeatureDraft | null;
}
