export type AnnotationFieldKey =
  | 'applicant'
  | 'applicantDepartment'
  | 'applicantTime'
  | 'approver'
  | 'approverDepartment'
  | 'approveTime'
  | 'stepName';

export interface WorkflowStep {
  key: string;
  label: string;
  role: 'APPROVE' | 'START';
}

export interface FormField {
  key: string;
  label: string;
  tag?: string;
  formId?: string;
  table?: string;
  column?: string;
}

export interface AnnotationCatalog {
  formFields: FormField[];
  newFlowVersionId: string;
  revisionFlowVersionId: string;
  workflowSteps: WorkflowStep[];
}

export interface AnnotationField {
  key: AnnotationFieldKey;
  label: string;
}

export const START_FIELDS: readonly AnnotationField[] = [
  { key: 'applicant', label: '发起人' },
  { key: 'applicantDepartment', label: '发起人部门' },
  { key: 'applicantTime', label: '发起时间' },
  { key: 'stepName', label: '发起步骤名称' },
];

export const APPROVE_FIELDS: readonly AnnotationField[] = [
  { key: 'approver', label: '审核人' },
  { key: 'approverDepartment', label: '审核人部门' },
  { key: 'approveTime', label: '审核人时间' },
  { key: 'stepName', label: '审核步骤名称' },
];

export function annotationFields(step: WorkflowStep | undefined): readonly AnnotationField[] {
  return step?.role === 'START' ? START_FIELDS : step?.role === 'APPROVE' ? APPROVE_FIELDS : [];
}

export function stepKey(step: WorkflowStep): string {
  return step.key;
}

export function annotationTag(step: WorkflowStep, field: AnnotationField): string {
  if (!step.key || !field.key) {
    throw new Error('签批页标注步骤或字段无效');
  }
  return `dms.qianpiye.flow.${step.key}.${field.key}`;
}

export function annotationAlias(step: WorkflowStep, field: AnnotationField): string {
  return `${step.label}-${field.label}`;
}

export function formAnnotationTag(field: FormField): string {
  if (!field.key) {
    throw new Error('签批页标注表单字段无效');
  }
  return field.tag || `dms.qianpiye.form.${field.key}`;
}

export function formAnnotationAlias(field: FormField): string {
  return singleLineAnnotationText(displayFieldLabel(field.label));
}

export function displayFieldLabel(label: string): string {
  return label.replace(/H/g, '');
}

/** 插入文本用空格连接多行名称；按钮仍显示原始字段名称。 */
function singleLineAnnotationText(text: string): string {
  return text.replace(/\\r\\n|\\[rn]|\r\n|[\r\n]/g, ' ');
}

/** Word 文档内显示给用户的占位文本；实际解析始终使用内容控件 Tag。 */
export function annotationPlaceholder(alias: string): string {
  return `{{${singleLineAnnotationText(alias)}}}`;
}

export interface RepeatGroup {
  key: string;
  label: string;
  tag: string;
  fields: FormField[];
}

export function repeatGroups(fields: FormField[]): RepeatGroup[] {
  const groups = new Map<string, RepeatGroup>();
  for (const field of fields) {
    if (!field.formId || !field.table || !field.column) continue;
    const key = `${field.formId}.${field.table}`;
    if (!groups.has(key)) groups.set(key, {
      key, label: field.label.split('-').slice(0, -1).join('-') || field.table,
      tag: `dms.qianpiye.rows.${key}`, fields: [],
    });
    if (!groups.get(key)!.fields.some((item) => item.column === field.column)) groups.get(key)!.fields.push(field);
  }
  return [...groups.values()];
}

export function repeatFieldLabel(field: FormField): string {
  return singleLineAnnotationText(displayFieldLabel(field.label.split('-').pop() || field.label))
    .replace(/\s+/gu, ' ').trim();
}

export function repeatFieldPlaceholder(field: FormField): string {
  return `{{${repeatFieldLabel(field)}}}`;
}

export function repeatPatternUsesField(pattern: string, field: FormField): boolean {
  return pattern.includes(repeatFieldPlaceholder(field));
}

export function addRepeatPatternField(pattern: string, field: FormField): string {
  const placeholder = repeatFieldPlaceholder(field);
  if (pattern.includes(placeholder)) return pattern;
  if (!pattern) return placeholder;
  return /\s$/.test(pattern) ? `${pattern}${placeholder}` : `${pattern} ${placeholder}`;
}

export function removeRepeatPatternField(pattern: string, field: FormField): string {
  const placeholder = repeatFieldPlaceholder(field);
  let result = pattern;
  let index = result.indexOf(placeholder);
  while (index >= 0) {
    const end = index + placeholder.length;
    if (result[end] === ' ') result = result.slice(0, index) + result.slice(end + 1);
    else if (index > 0 && result[index - 1] === ' ') result = result.slice(0, index - 1) + result.slice(end);
    else result = result.slice(0, index) + result.slice(end);
    index = result.indexOf(placeholder);
  }
  return result;
}

export function repeatPatternValidationError(group: RepeatGroup, pattern: string): string {
  try {
    repeatInsertSpec(group, pattern);
    return '';
  } catch (cause) {
    return cause instanceof Error ? cause.message : '子表格式无效';
  }
}

export function repeatInsertSpec(group: RepeatGroup, pattern: string) {
  const bindings: Record<string, string> = {};
  for (const field of group.fields) {
    const label = repeatFieldLabel(field);
    if (bindings[label] && bindings[label] !== field.column) throw new Error('子表列名称重复，请先修改表单列名称');
    bindings[label] = field.column!;
  }
  const placeholders = [...pattern.matchAll(/\{\{([^{}]+)\}\}/g)];
  if (!placeholders.length) throw new Error('请至少添加一个子表字段');
  if (pattern.length > 2000 || /[\r\n]/.test(pattern)) throw new Error('每条记录的格式必须为单行且不超过 2000 字');
  for (const match of placeholders) if (!bindings[match[1]!]) throw new Error(`未找到子表字段：${match[1]}`);
  return { tag: group.tag, alias: JSON.stringify({ title: group.label, fields: bindings }), placeholder: pattern };
}
