/**
 * 用户画像打分（User Profile Scoring）V1.2 类型定义
 *
 * 说明：
 * - 本模块用于：问卷答案（可跳过）→ 用户画像（可计算、可观测、可版本化）
 * - 字段与规则以 `spec_kit/User Profile Scoring/spec.md`（V1.2）为准
 */

export type MomStageAnswer = 'expecting' | 'parenting' | 'unknown';
export type EmotionAnswer = 'low' | 'overwhelmed' | 'tired' | 'neutral' | 'calm' | 'joyful';
export type ContextAnswer = 'family' | 'work' | 'relationship' | 'friends' | 'health';
export type NeedAnswer =
  | 'emotional_support'
  | 'parenting_pressure'
  | 'self_worth'
  | 'anxiety_relief'
  | 'rest_balance';

/**
 * V1.2：每题可跳过
 * - `undefined`：字段缺失（可能是“没传”）
 * - `null`：显式跳过/无值（例如 UI 明确传 null）
 */
export type QuestionnaireAnswersV1_2 = {
  mom_stage?: MomStageAnswer | null;
  emotion?: EmotionAnswer | null;
  context?: ContextAnswer | null;
  need?: NeedAnswer | null;
};

export type ProfileAnswered = {
  stage: boolean;
  emotion: boolean;
  context: boolean;
  need: boolean;
};

export type UserStageOneHot = {
  expecting?: 0 | 1;
  parenting?: 0 | 1;
  unknown: 0 | 1;
};

export type SparseOneHot = Record<string, 1>;

export type UserProfileV1_2 = {
  profile_version: 'v1.2';
  profile_source: 'questionnaire';
  profile_generated_at: string; // ISO8601
  profile_confidence: number; // 0–1
  profile_answered: ProfileAnswered;
  stage: UserStageOneHot;
  emotion_score: number | null;
  context: SparseOneHot;
  need: SparseOneHot;
};

export type ForbiddenContentPredicate = {
  /**
   * 谓词 ID：用于可观测与回归测试
   */
  id: string;
  /**
   * 触发条件（用户侧）
   * 说明：这里刻意保持为 object，便于未来接入规则引擎时做 schema 对齐。
   */
  when_user: Record<string, unknown>;
  /**
   * 禁推条件（内容侧）
   * 说明：本模块不判断内容的 `personalization_power`，只输出可执行条件。
   */
  forbid_content: Record<string, unknown>;
};

export type HardRules = {
  forbidden_risk_flags: string[];
  forbidden_content_predicates: ForbiddenContentPredicate[];
};

export type UserProfileV1_2_Extended = UserProfileV1_2 & {
  rule_hits: string[];
  hard_rules: HardRules;
};

export type BuildUserProfileOptions = {
  /**
   * 画像生成时间；不传则使用当前时间
   */
  generatedAt?: Date | string;
  /**
   * 当前时间（用于计算 time decay）；不传则使用当前时间
   */
  now?: Date | string;
};

