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

/**
 * 深度档 3 步各自的输出 schema(都过 AiCallRunner 的 generateObject 强约束)。
 *
 * ⚠️ 不加 .min()/.max()/.length()/.int() 等硬长度·范围约束 —— 段数 / 字数 / 评分范围
 *   全部只作 prompt 软引导(写在 describe 里)。理由:硬约束对中文偏严,且 qwen3.7-max 这类
 *   不强制 schema 的模型一旦长度/段数差一点就整体 fail 走兜底;形态靠 system + describe 引导即可。
 */

// ── 步骤1:规划 ──
export const DeepPlanSchema = z.object({
  sections: z
    .array(
      z.object({
        key: z.string().describe('段标识(英文短,仅内部串联,如 opening/missed_11/review/close)'),
        title: z.string().describe('中文小标题(自然口语,贴这通电话,约 2-20 字)'),
        intent: z.string().describe('这段要达成什么(一句话)'),
        points: z
          .array(z.string())
          .describe('要点(1-5 条,口语化,**每条都须来自给定患者信息/病历事实**,不编造)'),
      }),
    )
    .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().describe('段小标题(贴这段内容,自然口语,别用刻板模板名,约 2-20 字)'),
        markdown: z
          .string()
          .describe('该段话术正文(约 20-400 字)。短句分行、行首 `•`;接地病历、不编造;时间用【时间段】占位;无大标题/表情'),
      }),
    )
    .describe('按规划写出的多段话术(段数跟随规划,通常 3-7 段)'),
});
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().describe('出问题的段标题或序号'),
        problem: z.string().describe('问题:编造/接地不实(追不到事实)/安全越界(报价/承诺/写死时间/≤18拍片)'),
        fix: z.string().describe('修法建议(回喂改写)'),
      }),
    )
    .describe('逐条列出有问题的点;全部 OK 则空数组'),
  // ⭐ 质量评分(1-5)—— **只评好不好,跟 pass 无关**(pass 只看接地+安全)。仅落账供 eval / 版本对比,不卡生成。
  quality: z
    .object({
      natural: z.number().describe('口语自然度(1-5):像真人一来一回,不书面/机器腔/念稿'),
      warmth: z.number().describe('关怀温度(1-5):医疗关怀感,不冷淡也不推销'),
      focus: z.number().describe('聚焦(1-5):紧扣本次问题、主线清晰,不发散'),
      nonPushy: z.number().describe('不推销(1-5):邀约自然,不促单 / 不报价 / 不施压'),
      overall: z.number().describe('综合质量分(1-5,可含半分,如 4.5)'),
    })
    .describe('质量细项打分(1-5);只评质量,不影响 pass/issues'),
});
export type DeepVerifyZ = z.infer<typeof DeepVerifySchema>;
