import type {
  ExportFieldMeta,
  ExportGranularity,
} from '#/views/business/order/product-order/config/exportFields';
import { getExportFields } from '#/views/business/order/product-order/config/exportFields';

/** 「金额」分组字段 key，保持 exportFields 定义顺序 */
export function getAmountFieldKeys(granularity: ExportGranularity): string[] {
  return getExportFields(granularity)
    .filter((f) => f.group === '金额')
    .map((f) => f.key);
}

/** 全量字段 canonical 顺序 */
export function getCanonicalFieldOrder(granularity: ExportGranularity): string[] {
  return getExportFields(granularity).map((f) => f.key);
}

/**
 * 将已选金额字段聚合为连续块，块内按金额组定义序排列。
 * 块插入位置：原序中第一个已选金额字段的位置。
 */
export function clusterAmountFields(
  keys: string[],
  granularity: ExportGranularity,
): string[] {
  const amountKeys = getAmountFieldKeys(granularity);
  const amountSet = new Set(amountKeys);
  const selectedAmount = amountKeys.filter((k) => keys.includes(k));
  if (selectedAmount.length <= 1) {
    return [...keys];
  }

  const nonAmount = keys.filter((k) => !amountSet.has(k));

  let firstAmountIdx = keys.length;
  for (let i = 0; i < keys.length; i++) {
    if (amountSet.has(keys[i]!)) {
      firstAmountIdx = i;
      break;
    }
  }

  let nonAmountBefore = 0;
  for (let i = 0; i < firstAmountIdx; i++) {
    if (!amountSet.has(keys[i]!)) {
      nonAmountBefore++;
    }
  }

  const result = [...nonAmount];
  result.splice(nonAmountBefore, 0, ...selectedAmount);
  return result;
}

/** canonical 过滤 + 费用聚合 */
export function buildDefaultOrderedKeys(
  selectedKeys: string[],
  granularity: ExportGranularity,
): string[] {
  const selectedSet = new Set(selectedKeys);
  const ordered = getCanonicalFieldOrder(granularity).filter((k) =>
    selectedSet.has(k),
  );
  return clusterAmountFields(ordered, granularity);
}

/**
 * 勾选变更时同步有序列表。
 * customized=false：重建默认序（含费用聚合）
 * customized=true：仅增删，新增字段按 canonical 位置插入
 */
export function syncOrderedSelectedKeys(
  selectedKeys: string[],
  prevOrdered: string[],
  granularity: ExportGranularity,
  customized: boolean,
): string[] {
  const selectedSet = new Set(selectedKeys);

  if (!customized) {
    return buildDefaultOrderedKeys(selectedKeys, granularity);
  }

  let ordered = prevOrdered.filter((k) => selectedSet.has(k));
  const orderedSet = new Set(ordered);
  const added = selectedKeys.filter((k) => !orderedSet.has(k));

  if (added.length === 0) {
    return ordered;
  }

  const canonical = getCanonicalFieldOrder(granularity);
  for (const key of added) {
    const canonicalIdx = canonical.indexOf(key);
    let insertAt = ordered.length;
    for (let i = 0; i < ordered.length; i++) {
      const existingIdx = canonical.indexOf(ordered[i]!);
      if (existingIdx > canonicalIdx) {
        insertAt = i;
        break;
      }
    }
    ordered = [...ordered.slice(0, insertAt), key, ...ordered.slice(insertAt)];
  }

  return ordered;
}

export function formatFieldOrderPreview(
  keys: string[],
  fieldMeta: ExportFieldMeta[],
): string {
  const labelMap = new Map(fieldMeta.map((f) => [f.key, f.label]));
  return keys.map((k) => labelMap.get(k) ?? k).join(' → ');
}
