import type { AuditEventListDTO, AuditOperation, AuditPageQuery } from './types';

const actionCodeLabels: Record<string, string> = {
  CREATE: '新增',
  DELETE: '删除',
  READ: '查询',
  SIGN: '电子签名',
  UPDATE: '修改',
};

const eventTypeLabels: Record<string, string> = {
  BIZ_ACTION: '业务动作',
  DATA_CHANGE: '数据变更',
  E_SIGNATURE: '电子签名',
};

const sourceLayerLabels: Record<number, string> = {
  0: '在线表单',
  1: '数据库变更',
  2: '业务动作',
  3: '电子签名',
};

/** Normalize one BUSINESS row and its related physical signature events. */
export function normalizeOperation(main: AuditEventListDTO): AuditOperation {
  const subEvents = Array.isArray(main.subEvents) ? main.subEvents : [];
  const eventIds = [main.id, ...subEvents.map((event) => event.id)];
  const layers = [...new Set([main, ...subEvents].flatMap((event) => (typeof event.sourceLayer === 'number' ? [event.sourceLayer] : [])))];
  const diffCount = toDiffCount(main.diffCount);

  return {
    ...main,
    correlationKey: main.operationId ?? main.clientEventId ?? `event:${main.id}`,
    diffCount,
    eventIds,
    layers,
    sourceSummary: getSourceSummary(layers, diffCount),
    subEvents,
  };
}

/** Timeline uses the same operation-level display contract as the page endpoint. */
export function groupTimelineOperations(events: AuditEventListDTO[]): AuditOperation[] {
  return events.map((event) => normalizeOperation(event));
}

/**
 * 动作名优先按 actionCode 映射：层 0 的基础三动作有稳定语义，映射后历史数据
 * （actionLabel 是 "LIMS-请验单 新建" 这种旧格式）也立刻显示对。
 * 层 2 事件的动作词是业务自定义的（"请验单 撤回"），映射表命不中，回落 actionLabel。
 */
export function getAuditActionLabel(event: Pick<AuditEventListDTO, 'actionCode' | 'actionLabel'>): string {
  const mapped = event.actionCode ? actionCodeLabels[event.actionCode] : undefined;
  return mapped || event.actionLabel || event.actionCode || '未标记操作';
}

export function getAuditEventTypeLabel(eventType?: string): string {
  if (!eventType) return '未标记类型';
  return eventTypeLabels[eventType] || eventType;
}

export function getSourceLayerLabel(sourceLayer?: number): string {
  if (sourceLayer === undefined) return '未知来源';
  return sourceLayerLabels[sourceLayer] || `采集层 ${sourceLayer}`;
}

export function getSourceSummary(layers: number[], diffCount: number): string {
  const hasBusinessAction = layers.includes(2);
  const hasElectronicSignature = layers.includes(3);
  if (hasBusinessAction) {
    return ['业务动作', hasElectronicSignature ? '电子签名' : '', diffCount > 0 ? '字段变更' : ''].filter(Boolean).join(' + ');
  }
  if (hasElectronicSignature && diffCount > 0) return '电子签名 + 字段变更';
  if (hasElectronicSignature) return '电子签名';
  if (layers.length === 1 && layers[0] === 0) return '在线表单';
  if (layers.length === 1 && layers[0] === 1) return '数据库变更';
  if (layers.includes(0) && layers.includes(1)) return '在线表单 + 数据库变更';
  return '未知来源';
}

export function normalizeAuditPageQuery(query: Record<string, unknown>): AuditPageQuery {
  const normalized: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(query)) {
    const nextValue = typeof value === 'string' ? value.trim() : value;
    if (nextValue !== '' && nextValue !== undefined && nextValue !== null) normalized[key] = nextValue;
  }
  return normalized as unknown as AuditPageQuery;
}

function toDiffCount(value?: number): number {
  return Number.isFinite(value) && Number(value) > 0 ? Number(value) : 0;
}
