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

/**
 * family_structure 家庭构成(A.3.1)— 规则层,snapshot
 *
 * 口径(图):基于直系亲属社交关系反推家庭结构(家庭套餐 / 儿牙营销用)。
 *   数据来源:PAC PatientRelation 边表(摄入自 fact_customer_referee_out;relationship 已归一)。
 *   直系:spouse(配偶)/ child·grandchild(子女晚辈)/ father·mother·grandparent(长辈);
 *         sibling(同辈)/ friend / other 视为非直系/推荐人噪音,不计入。
 *
 *   判定(图 + 可行补全,长辈优先 = 跨代):
 *     有长辈 → 多代之家(跨代家庭)
 *     否则 有子女 → 多口之家(含单亲)
 *     否则 有配偶 → 两口之家
 *     否则 有非直系边(sibling/friend/other)→ 单身家庭(有社交数据但无直系)
 *     否则 无任何关系边 → 不打标签(数据缺,不臆断为单身)
 *
 *   ⚠️ 数据完整性:依赖关系边覆盖。当前样本仅少数患者有边(且 fact_customer_referee_out
 *      混推荐人噪音)→ 覆盖偏低;全量 + 完整社交关系维护后更准。
 */
@Injectable()
export class FamilyStructureFeatureExtractor implements FeatureExtractor {
  readonly key = PersonaFeatureKey.FAMILY_STRUCTURE;

  private static readonly ELDER = new Set(['father', 'mother', 'grandparent']);
  private static readonly YOUNGER = new Set(['child', 'grandchild']);

  extract(ctx: FeatureExtractorContext): PersonaFeatureDraft | null {
    const rels = ctx.relations ?? [];
    if (rels.length === 0) return null; // 无任何关系边 → 不臆断

    let hasSpouse = false;
    let hasChild = false;
    let hasElder = false;
    for (const r of rels) {
      const t = r.relationship;
      if (t === 'spouse') hasSpouse = true;
      else if (FamilyStructureFeatureExtractor.YOUNGER.has(t)) hasChild = true;
      else if (FamilyStructureFeatureExtractor.ELDER.has(t)) hasElder = true;
    }

    let code: string;
    let zh: string;
    if (hasElder) {
      code = 'multigen';
      zh = '多代之家';
    } else if (hasChild) {
      code = 'nuclear';
      zh = '多口之家';
    } else if (hasSpouse) {
      code = 'couple';
      zh = '两口之家';
    } else {
      code = 'single'; // 有边(sibling/friend/other)但无直系
      zh = '单身家庭';
    }

    return {
      key: this.key,
      description: zh,
      score: null,
      data: { structure: code, label: zh, hasSpouse, hasChild, hasElder, relationCount: rels.length },
      evidence: { factIds: [] }, // 来自关系边表(非 fact)
    };
  }
}
