import { z } from 'zod';

/**
 * DraftPlanScript AiCall 的 Zod 输出 schema。
 *
 * 设计原则(B 方案 · 2026-05-24):
 *   - 4 段直出 markdown,每段一个字段,LLM 自由写 markdown 但格式契约由 .describe() 强约束
 *   - generateObject 会把 schema 转 JSON Schema 注入 prompt;LLM 强制按此 shape 输出
 *   - 流式时每段是 string 字段,partial 阶段 LLM 还没写完的段为 undefined → orchestrator 透 ''
 *   - .describe() 写清楚段内 markdown 子结构格式(目的 / 正文 / 注意 / 异议预判 / 回写要点)
 *
 * 跟前端 mock-data.ts mockScript.sections 完全对齐(4 段 id),前端零改动接 4 段。
 */
export const DraftPlanScriptSchema = z.object({
  tone: z
    .enum(['warm', 'professional', 'urgent'])
    .describe('整体语气标签:warm=温和家常 / professional=专业稳重 / urgent=有时效紧迫'),

  opening: z
    .string()
    .min(60)
    .max(700)
    .describe(
      [
        '【开场段 markdown,必须严格按以下 3 部分格式】',
        '第 1 部分:`**目的**:xxx` — 一句话讲清开场目的(15-40 字)',
        '第 2 部分:空行后 `> "通话片段..."` blockquote — 客服开场白完整一段(80-200 字),包含:自报家门(诊所+岗位)+ 来电原因(必须提具体临床事实)+ 礼貌征询是否方便',
        '第 3 部分:空行后 `**注意**` 标题 + 2-3 条 `- xxx` bullet — 客服执行注意点(称呼/时段/口吻)',
        '禁止:加 ### 标题、加表情符号、blockquote 里使用排比抒情体',
      ].join('\n'),
    ),

  followup: z
    .string()
    .min(120)
    .max(1000)
    .describe(
      [
        '【切入话题段 markdown,必须严格按以下 3 部分格式】',
        '第 1 部分:`**目的**:xxx` — 一句话讲本段任务(15-40 字)',
        '第 2 部分:空行后 1-2 段 `> "..."` blockquote — 先讲临床事实+风险(治疗阶段/牙位号/上次诊断),再给具体行动选项(必须含"这次只是评估,30 分钟"这类降低门槛话术,可加粗关键信息)',
        '第 3 部分:空行后 `**异议预判**` 标题 + 2-4 条 `- "trigger" → action` bullet — 列患者可能的反对+对应处理思路',
        '禁止:在本段写完整异议应对话术(那是 objection 段的事)',
      ].join('\n'),
    ),

  objection: z
    .string()
    .min(150)
    .max(1400)
    .describe(
      [
        '【异议处理段 markdown,必须严格按以下格式】',
        '3-4 个子条目,每个子条目:',
        '  - `### A. "我再考虑考虑"` 子标题(A/B/C/D 顺序)',
        '  - 紧跟一行 blockquote `> "应对话术..."`(30-100 字,要给具体时间选项或具体方案)',
        '  - 可选追加一行 `> → 提交结果选「xxx」` 指明客服回写动作',
        '常见异议优先覆盖:再考虑 / 价格贵 / 没时间 / 已在外院 / 治疗冲突等',
        '禁止:把所有异议合并成一个长段、用 bullet 列举(必须 ### 子标题分块)',
      ].join('\n'),
    ),

  close: z
    .string()
    .min(80)
    .max(700)
    .describe(
      [
        '【结束·信息确认段 markdown,必须严格按以下 2 部分格式】',
        '第 1 部分:`> "确认话术..."` blockquote — 复述敲定的安排:示例时间 + 医生名 + 提醒方式(短信/企微)+ 礼貌结尾',
        '  ⭐ 时间措辞要求(call 时段 PAC 无排班 API,LLM 给的具体时间只是 example,实际以诊所排班为准):',
        '   - 必须含"待确认"语义短语之一:"具体时段以诊所排班为准" / "稍后跟前台确认后短信通知您实际时间" / "实际时间稍后短信确认" / "我先按 X 登记,排班确认后告知"',
        '   - 出现具体时间时(如"周六上午10点"),**两种方式标记为示例,任选一**:',
        '       方式 A: 不加粗,紧跟 `(示例)` 后缀 → "周六上午10点(示例)"',
        '       方式 B: 用方向词代替具体点 → "周六上午这个方向"',
        '   - ⚠️ 严禁 `**周六上午10点**` 这种加粗具体时间 — 加粗读作"已确认重点",会让患者误以为时间真定了',
        '   - 严禁说"我已为您约好 X" / "已成功预约 X" / "约定 X" / "敲定 X" 这种确定承诺',
        '   - close 段只给 1 个时间示例 + 弱化短语,不要罗列多个备选(close 是收尾,不是商量)',
        '第 2 部分:空行后 `**回写要点**` 标题 + 2-4 条 `- xxx → 提交结果选「xxx」` bullet — 列不同通话结果对应的客服回写动作',
        '禁止:省略具体时间敲定、省略回写要点、加粗具体时间、用承诺式"已为您约好/约定/敲定"',
      ].join('\n'),
    ),
});

export type DraftPlanScriptOutputZ = z.infer<typeof DraftPlanScriptSchema>;
