import { z } from 'zod';

/**
 * Push 事件 body 契约 — 宿主主动推送给 PAC。
 *
 * 一次请求可携带多条事件(批量推),按 occurredAt 顺序处理。
 * 每条事件 = 一个 patient_transactions 行(经过 synthesizer)。
 *
 * 字段已是 PAC canonical 命名:
 *   - subjectType(patient / appointment / encounter ...) → patient_transactions.subject_type
 *   - subjectRef → patient_transactions.subject_id
 *   - patientRef → 反查 patient.id(若 subjectType 不是 patient 本身)
 *   - sourceEventId → 幂等键
 *   - occurredAt → 时间戳
 *   - payload → 业务字段(canonical 已映射,如 appointmentAt / status / doctorId 等)
 */
export const PushEventSchema = z.object({
  subjectType: z.string().describe('CanonicalSubjectType: patient/appointment/...'),
  subjectRef: z.string().min(1).describe('宿主侧本资源的 externalId'),
  patientRef: z.string().min(1).optional().describe('关联 patient externalId;subjectType=patient 时可省'),
  clinicId: z.string().min(1).describe('发生诊所(立柱必填)'),
  action: z.string().describe('canonical Action: created/updated/canceled/...'),
  sourceEventId: z.string().min(1).describe('宿主侧唯一事件 id(幂等键)'),
  occurredAt: z.string().datetime({ offset: true }).describe('ISO 8601 with timezone'),
  eventSeq: z.number().int().nonnegative().optional().describe('递增序号,可选,用于水位'),
  payload: z.record(z.string(), z.unknown()).describe('已 canonical 化的业务字段'),
});

export type PushEvent = z.infer<typeof PushEventSchema>;

export const PushEventsRequestSchema = z.object({
  events: z.array(PushEventSchema).min(1).max(500),
});

export type PushEventsRequest = z.infer<typeof PushEventsRequestSchema>;

export const PushEventsResponseSchema = z.object({
  syncLogId: z.string().uuid(),
  accepted: z.number().int().describe('收到的事件总数'),
  transactionsWritten: z.number().int(),
  duplicates: z.number().int(),
  failed: z.number().int(),
});

export type PushEventsResponse = z.infer<typeof PushEventsResponseSchema>;
