/**
 * 工作流运行态单文件值。
 */
export interface WorkflowFileValue {
  fileName: string;
  filePath: string;
  contentType?: string;
  size?: number;
  url?: string;
}

/**
 * 素材对象最小字段约束。
 */
export interface WorkflowResourceLike {
  fileSize?: number | string;
  resourceName?: string;
  resourceUrl?: string;
  suffix?: string;
}

export const WORKFLOW_FILE_LIMITS = {
  maxCount: 10,
  maxSingleSize: 5 * 1024 * 1024,
  maxTotalSize: 50 * 1024 * 1024,
} as const;

/**
 * 基于上传结果构建工作流文件值。
 */
export function buildWorkflowFileValueFromUpload(
  file: File,
  path: string,
): WorkflowFileValue {
  const resolvedPath = String(path || '').trim();
  if (!resolvedPath) {
    throw new Error('上传结果缺少文件路径');
  }
  return {
    fileName: file.name,
    filePath: resolvedPath,
    contentType: file.type || '',
    size: file.size,
    url: resolvedPath,
  };
}

/**
 * 基于素材对象构建工作流文件值。
 */
export function buildWorkflowFileValueFromResource(
  resource: WorkflowResourceLike,
): WorkflowFileValue {
  const resourceUrl = String(resource?.resourceUrl || '').trim();
  if (!resourceUrl) {
    throw new Error('素材缺少 resourceUrl');
  }
  const resourceName = String(resource?.resourceName || '').trim();
  const suffix = String(resource?.suffix || '').trim();
  const fallbackFileName = resourceUrl.split('/').pop()?.split('?')[0] || '';
  return {
    fileName:
      resourceName && suffix
        ? `${resourceName}.${suffix}`
        : resourceName || fallbackFileName,
    filePath: resourceUrl,
    contentType: '',
    size: toNumber(resource?.fileSize),
    url: resourceUrl,
  };
}

/**
 * 判断是否为有效的工作流文件值。
 */
export function isWorkflowFileValue(value: unknown): value is WorkflowFileValue {
  if (!value || typeof value !== 'object') {
    return false;
  }
  const candidate = value as Partial<WorkflowFileValue>;
  return Boolean(
    String(candidate.fileName || '').trim() &&
      String(candidate.filePath || '').trim(),
  );
}

/**
 * 归一化单文件或多文件值。
 */
export function normalizeWorkflowFileValues(value: unknown): WorkflowFileValue[] {
  const candidates = Array.isArray(value) ? value : [value];
  const result: WorkflowFileValue[] = [];
  const seen = new Set<string>();
  for (const candidate of candidates) {
    if (!isWorkflowFileValue(candidate)) {
      continue;
    }
    const key = String(candidate.filePath).trim();
    if (!key || seen.has(key)) {
      continue;
    }
    seen.add(key);
    result.push(candidate);
  }
  return result;
}

/**
 * 追加文件并按 filePath 去重。
 */
export function appendWorkflowFileValues(
  currentValue: unknown,
  incomingValues: WorkflowFileValue[],
): WorkflowFileValue[] {
  return normalizeWorkflowFileValues([
    ...normalizeWorkflowFileValues(currentValue),
    ...incomingValues,
  ]);
}

/**
 * 在上传前基于原生 File 列表校验文件限制，避免无效文件先落库。
 */
export function validateWorkflowFileSelection(
  currentValue: unknown,
  incomingFiles: File[],
) {
  const currentFiles = normalizeWorkflowFileValues(currentValue);
  const totalCount = currentFiles.length + incomingFiles.length;
  if (totalCount > WORKFLOW_FILE_LIMITS.maxCount) {
    throw new Error(`最多上传 ${WORKFLOW_FILE_LIMITS.maxCount} 个文件`);
  }

  let totalSize = currentFiles.reduce((sum, item) => sum + Number(item.size || 0), 0);
  for (const file of incomingFiles) {
    if (file.size > WORKFLOW_FILE_LIMITS.maxSingleSize) {
      throw new Error(`单个文件不能超过 ${formatWorkflowFileSize(WORKFLOW_FILE_LIMITS.maxSingleSize)}`);
    }
    totalSize += file.size;
  }

  if (totalSize > WORKFLOW_FILE_LIMITS.maxTotalSize) {
    throw new Error(`文件总大小不能超过 ${formatWorkflowFileSize(WORKFLOW_FILE_LIMITS.maxTotalSize)}`);
  }
}

/**
 * 校验最终文件列表是否满足工作流限制。
 */
export function validateWorkflowFileValues(values: WorkflowFileValue[]) {
  const normalized = normalizeWorkflowFileValues(values);
  if (normalized.length > WORKFLOW_FILE_LIMITS.maxCount) {
    throw new Error(`最多上传 ${WORKFLOW_FILE_LIMITS.maxCount} 个文件`);
  }
  let totalSize = 0;
  for (const item of normalized) {
    const size = Number(item.size || 0);
    if (size > WORKFLOW_FILE_LIMITS.maxSingleSize) {
      throw new Error(`单个文件不能超过 ${formatWorkflowFileSize(WORKFLOW_FILE_LIMITS.maxSingleSize)}`);
    }
    totalSize += size;
  }
  if (totalSize > WORKFLOW_FILE_LIMITS.maxTotalSize) {
    throw new Error(`文件总大小不能超过 ${formatWorkflowFileSize(WORKFLOW_FILE_LIMITS.maxTotalSize)}`);
  }
}

/**
 * 友好格式化文件大小。
 */
export function formatWorkflowFileSize(size?: number): string {
  if (!size || Number.isNaN(size) || size <= 0) {
    return '-';
  }
  if (size < 1024) {
    return `${size} B`;
  }
  if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(1)} KB`;
  }
  if (size < 1024 * 1024 * 1024) {
    return `${(size / (1024 * 1024)).toFixed(1)} MB`;
  }
  return `${(size / (1024 * 1024 * 1024)).toFixed(1)} GB`;
}

function toNumber(value?: number | string) {
  if (typeof value === 'number') {
    return value;
  }
  if (typeof value === 'string' && value.trim()) {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : undefined;
  }
  return undefined;
}
