'use client';

import type {
  ListPlansQuery,
  ListPlansResponse,
  PlanActionAck,
  PlanCountsResponse,
  ReleaseReason,
} from '@pac/types';
import { api } from '@/lib/api-client';
import type { PlanDetailData } from '@/components/plan-detail/plan-detail-types';

export const plansApi = {
  list: (q: Partial<ListPlansQuery>) =>
    api.get<ListPlansResponse>('/pac/v1/plans', {
      query: {
        view: q.view,
        scenario: q.scenario,
        status: q.status,
        targetClinicId: q.targetClinicId,
        // 诊所多选:逗号串上线(后端 preprocess 拆数组);空则不带
        targetClinicIds: q.targetClinicIds?.length ? q.targetClinicIds.join(',') : undefined,
        assigneeUserId: q.assigneeUserId,
        keyword: q.keyword,
        // 画像标签筛选("key:value" 逗号串,维度见 PERSONA_TAG_FILTER_DIMS)
        personaTags: q.personaTags,
        // 只看真实号码:布尔上线成 'true'(后端 preprocess 还原);undefined 不带
        phoneVerified: q.phoneVerified === undefined ? undefined : String(q.phoneVerified),
        sort: q.sort,
        page: q.page ?? 1,
        pageSize: q.pageSize ?? 20,
      },
    }),

  /** 「上次医生 / 偏好医生」筛选的候选名单(后端缓存 6h;前端在它上面做客户端模糊匹配)*/
  doctors: () => api.get<{ doctors: string[] }>('/pac/v1/plans/doctors'),

  /** KPI / Tab badge 聚合计数 — 一次拉齐(替代之前 5 个并发 list 请求)*/
  counts: () => api.get<PlanCountsResponse>('/pac/v1/plans/counts'),

  /** 聚合详情:plan + patient + profile + persona + chains + facts(给 PlanDetailApp 用)*/
  getAggregate: (planId: string) =>
    api.get<PlanDetailData>(`/pac/v1/plans/${encodeURIComponent(planId)}/full`),

  /** PV/UV 埋点:上报一次 plan 详情页浏览。**尽力而为**,失败不影响页面(调用方吞异常)*/
  reportView: (planId: string) =>
    api.post<{ ok: boolean }>(`/pac/v1/plans/${encodeURIComponent(planId)}/view`, {}),

  /** 回访历史一句话摘要(有则取、无则当场生成;无回访记录 status='empty')*/
  getRecallSummary: (planId: string) =>
    api.get<{ summary: string | null; status: 'ready' | 'empty'; source?: string }>(
      `/pac/v1/plans/${encodeURIComponent(planId)}/recall-summary`,
    ),

  /** 画像标签一句话重点(有则取、无则当场生成;无 persona/feature status='empty')*/
  getPersonaSummary: (planId: string) =>
    api.get<{ summary: string | null; status: 'ready' | 'empty'; source?: string }>(
      `/pac/v1/plans/${encodeURIComponent(planId)}/persona-summary`,
    ),

  /** 本次召回一句话简报(谁/解决什么/到诊做什么;有则取、无则当场生成;无召回原因 status='empty')*/
  getRecallBrief: (planId: string) =>
    api.get<{ summary: string | null; status: 'ready' | 'empty'; source?: string }>(
      `/pac/v1/plans/${encodeURIComponent(planId)}/recall-brief`,
    ),

  /** 认领 / 指派 — POST /plans/{id}/assign { assigneeUserId } */
  assign: (planId: string, assigneeUserId: string) =>
    api.post<PlanActionAck>(`/pac/v1/plans/${encodeURIComponent(planId)}/assign`, {
      assigneeUserId,
    }),

  /**
   * 退回 / 回收 — POST /plans/{id}/recycle(mine → pool,plan 仍 active)。
   *
   * ⚠️ 入参从自由文本 `reason` 换成了结构化 `releaseReason`(2026-08):
   * 旧字段服务端**从来没读过**(controller 写作 `@Body() _dto`),客服填了等于没填。
   * 结构化才能聚合出"退回原因分布",那是主管调整分配策略的输入。
   * `other` 必须带 releaseNote,服务端会拦(不是前端校验就够了)。
   */
  recycle: (planId: string, releaseReason?: ReleaseReason, releaseNote?: string) =>
    api.post<PlanActionAck>(`/pac/v1/plans/${encodeURIComponent(planId)}/recycle`, {
      releaseReason,
      releaseNote,
    }),

  /** 拉患者明文手机号(reveal,需 PATIENT_VIEW 权限) — GET /patients/{id}/phone-reveal */
  revealPhone: (patientId: string) =>
    api.get<{ phone: string | null }>(
      `/pac/v1/patients/${encodeURIComponent(patientId)}/phone-reveal`,
    ),

  /** W4 末:话术 thumbs up/down 反馈("本段是否好用")
   *  - POST /pac/v1/plans/:id/script-feedback { feedback: 'up'|'down' }
   *  - 写入 agent_invocations.user_feedback;同 invocation 反复点会覆盖以最新为准 */
  submitScriptFeedback: (planId: string, feedback: 'up' | 'down') =>
    api.post<{ ok: boolean; invocationId?: string; reason?: string }>(
      `/pac/v1/plans/${encodeURIComponent(planId)}/script-feedback`,
      { feedback },
    ),

  /** 召回反馈(plan 级)— 详情页标题栏拇指 + 文字("这条召回准不准")
   *  - POST /pac/v1/plans/:id/recall-feedback { feedback: 'up'|'down', note? }
   *  - 写入 followup_plans.recall_feedback(+note/at/by);反复点覆盖以最新为准 */
  submitRecallFeedback: (planId: string, feedback: 'up' | 'down', note?: string) =>
    api.post<{ ok: boolean; feedback?: 'up' | 'down'; reason?: string }>(
      `/pac/v1/plans/${encodeURIComponent(planId)}/recall-feedback`,
      { feedback, note },
    ),

  /** W4 末:单患者按需刷新(从 DW 直连重拉该 patient 全量,触发 persona+plan recompute)
   *  - POST /sync/patient/:id/refresh
   *  - 跟 daily incremental cursor 完全隔离(resource='patient_refresh')
   *  - 返回新 plansCreated:0 = plan 已消失(scenario 不再命中),前端应跳列表 */
  refreshPatient: (patientId: string) =>
    api.post<{
      syncLogId: string;
      status: string;
      transactionsWritten?: number;
      factsEmitted?: number;
      plansCreated?: number;
    }>(`/pac/v1/sync/patient/${encodeURIComponent(patientId)}/refresh`),
};
