import { z } from 'zod';
import { ToneEnum, TONE_DESCRIBE } from '../../shared/tone';

/**
 * 深度档 3 步各自的输出 schema(都过 AiCallRunner 的 generateObject 强约束)。
 */

// ── 步骤1:规划 ──
export const DeepPlanSchema = z.object({
  sections: z
    .array(
      z.object({
        key: z.string().min(1).max(24).describe('段标识(英文短,仅内部串联,如 opening/missed_11/review/close)'),
        title: z.string().min(2).max(20).describe('中文小标题(自然口语,贴这通电话)'),
        intent: z.string().min(4).max(60).describe('这段要达成什么(一句话)'),
        points: z
          .array(z.string().min(2).max(120))
          .min(1)
          .max(5)
          .describe('要点(口语化,**每条都须来自给定患者信息/病历事实**,不编造)'),
      }),
    )
    .min(3)
    .max(7)
    .describe('话术大纲:按这通电话需要拆几段(开场→切入本次问题→可顺带的其他关心→复查邀约→结束;段数你定,3-7 段)'),
});
export type DeepPlanZ = z.infer<typeof DeepPlanSchema>;

// ── 步骤2:写(多段不定) ──
export const DeepWriteSchema = z.object({
  tone: ToneEnum.describe(TONE_DESCRIBE),
  sections: z
    .array(
      z.object({
        title: z.string().min(2).max(20).describe('段小标题(贴这段内容,自然口语,别用刻板模板名)'),
        markdown: z
          .string()
          .min(20)
          .max(900)
          .describe('该段话术正文。短句分行、行首 `•`;接地病历、不编造;时间用【时间段】占位;无大标题/表情'),
      }),
    )
    .min(3)
    .max(7)
    .describe('按规划写出的多段话术(段数跟随规划)'),
});
export type DeepWriteZ = z.infer<typeof DeepWriteSchema>;

// ── 步骤3:独立对抗校验 ──
export const DeepVerifySchema = z.object({
  pass: z.boolean().describe('草稿每句都能追到给定事实、且无安全越界 → true;否则 false'),
  issues: z
    .array(
      z.object({
        section: z.string().min(1).max(30).describe('出问题的段标题或序号'),
        problem: z.string().min(4).max(160).describe('问题:编造/接地不实(追不到事实)/安全越界(报价/承诺/写死时间/≤18拍片)'),
        fix: z.string().min(4).max(160).describe('修法建议(回喂改写)'),
      }),
    )
    .describe('逐条列出有问题的点;全部 OK 则空数组'),
  // ⭐ 质量评分(1-5)—— **只评好不好,跟 pass 无关**(pass 只看接地+安全)。仅落账供 eval / 版本对比,不卡生成。
  quality: z
    .object({
      natural: z.number().int().min(1).max(5).describe('口语自然度:像真人一来一回,不书面/机器腔/念稿'),
      warmth: z.number().int().min(1).max(5).describe('关怀温度:医疗关怀感,不冷淡也不推销'),
      focus: z.number().int().min(1).max(5).describe('聚焦:紧扣本次问题、主线清晰,不发散'),
      nonPushy: z.number().int().min(1).max(5).describe('不推销:邀约自然,不促单 / 不报价 / 不施压'),
      overall: z.number().min(1).max(5).describe('综合质量分(1-5,可含半分,如 4.5)'),
    })
    .describe('质量细项打分(1-5);只评质量,不影响 pass/issues'),
});
export type DeepVerifyZ = z.infer<typeof DeepVerifySchema>;
