import type { RearrangeDraft, RearrangeSubmitResponse } from '@pac/types';

/**
 * rearrange-facts —— 把一版调整单投影成**给模型的结构化事实**。
 *
 * ⚠️ 纪律与 `assignment-facts` 完全一致,⛔ 别在这儿放宽:
 *   ⛔ **一个字的指令都不许有**（「请照抄」「不要说成…」之类）。事实归事实,规范归提示词。
 *   ⛔ 不含 planId / 患者姓名 —— 那些走侧信道给界面,模型手里不该有。
 *      (客服姓名可以给:模型要用它组织「谁手上多少」这句话,确认单那边同样给。)
 *   ⚠️ 键名用中文:模型照着键名说就是对的。
 *
 * ⛔ 这里**不给成品句子**。唯一的例外是 `没落上的` 那一句 —— 它来自服务端的
 *   `summarizeSkipped`,口径必须与界面完全一致(两边各拼一份必然对不上)。
 */

/** 出一版调整单之后回给模型的事实 */
export function rearrangeFacts(d: RearrangeDraft): Record<string, unknown> {
  const perAgent = d.agents
    .filter((a) => a.inHand > 0)
    .sort((x, y) => y.inHand - x.inHand)
    .map((a) => ({
      客服: a.name ?? '未知客服',
      在手: a.inHand,
      已超期: a.overdue,
      // 「这些大概要打几天」—— 与确认单同一把换算尺(每人每天几通)
      约几天的量: Math.ceil(a.inHand / d.dailyCalls),
    }));

  return {
    调整单已呈现: true,
    这一版是: {
      范围:
        d.scope === 'all'
          ? '这家诊所全部客服此刻在手的单'
          : `点名的 ${d.scopedAgentUserIds.length} 位客服此刻在手的单`,
      // ⚠️ 事实,不是指令:告诉它这一版**没被动过**,免得它顺口说成"我已经排好了"
      内容: '原样 —— 谁手上什么样就摆成什么样,没有做过任何调整',
      在手合计: d.total,
      其中已超期: d.overdueTotal,
      涉及客服: perAgent.length,
      换算尺: `每人每天 ${d.dailyCalls} 通`,
    },
    每位客服: perAgent,
    // 只在真的截断时出现 —— ⛔ 静默截断等于让主管以为"这就是全部"
    ...(d.truncated > 0
      ? {
          没装下的: {
            条数: d.truncated,
            原因: '单次调整最多装 500 条,超出的这一版没有列进来',
          },
        }
      : {}),
    他可以让你做的事: ['把某几位患者换给别的客服', '改某几条的时限', '把某几条移出(收回池子)'],
    这一步不写数据: true,
    要生效得他在调整单上点确认: true,
  };
}

/** 界面把调整提交完之后,回报给模型的事实(界面自己发进对话,这里是备用投影) */
export function rearrangeResultFacts(r: RearrangeSubmitResponse): Record<string, unknown> {
  return {
    调整已生效: !r.duplicate,
    重复提交: r.duplicate,
    改派: r.moved,
    改时限: r.expiryChanged,
    移出: r.removed,
    没落上的条数: r.skipped.length,
    // ⚠️ 成品句子,口径与界面同源(服务端 summarizeSkipped)——⛔ 别让模型自己归并原因
    没落上的: r.note,
  };
}
