import { describe, expect, it } from 'vitest';

import {
  appendWorkflowFileValues,
  buildWorkflowFileValueFromResource,
  buildWorkflowFileValueFromUpload,
  formatWorkflowFileSize,
  isWorkflowFileValue,
  normalizeWorkflowFileValues,
  validateWorkflowFileSelection,
  validateWorkflowFileValues,
} from '../workflowFileValue';

describe('workflowFileValue', () => {
  it('从上传结果构建统一文件对象', () => {
    const file = new File(['demo'], 'demo.pdf', { type: 'application/pdf' });

    const value = buildWorkflowFileValueFromUpload(file, 'https://example.com/demo.pdf');

    expect(value).toEqual({
      fileName: 'demo.pdf',
      filePath: 'https://example.com/demo.pdf',
      contentType: 'application/pdf',
      size: 4,
      url: 'https://example.com/demo.pdf',
    });
  });

  it('从素材对象构建统一文件对象', () => {
    const value = buildWorkflowFileValueFromResource({
      fileSize: '128',
      resourceName: 'manual',
      resourceUrl: 'https://example.com/manual.docx',
      suffix: 'docx',
    });

    expect(value).toEqual({
      fileName: 'manual.docx',
      filePath: 'https://example.com/manual.docx',
      contentType: '',
      size: 128,
      url: 'https://example.com/manual.docx',
    });
  });

  it('正确识别有效文件值并格式化大小', () => {
    expect(
      isWorkflowFileValue({
        fileName: 'demo.pdf',
        filePath: 'https://example.com/demo.pdf',
      }),
    ).toBe(true);
    expect(isWorkflowFileValue({ fileName: 'demo.pdf' })).toBe(false);
    expect(formatWorkflowFileSize(2048)).toBe('2.0 KB');
  });

  it('归一化并去重多文件值', () => {
    const result = normalizeWorkflowFileValues([
      {
        fileName: 'a.pdf',
        filePath: 'https://example.com/a.pdf',
      },
      {
        fileName: 'a-copy.pdf',
        filePath: 'https://example.com/a.pdf',
      },
      {
        fileName: 'b.pdf',
        filePath: 'https://example.com/b.pdf',
      },
    ]);

    expect(result).toHaveLength(2);
    expect(result[0]?.fileName).toBe('a.pdf');
    expect(result[1]?.fileName).toBe('b.pdf');
  });

  it('追加文件时按 filePath 去重', () => {
    const result = appendWorkflowFileValues(
      [
        {
          fileName: 'a.pdf',
          filePath: 'https://example.com/a.pdf',
        },
      ],
      [
        {
          fileName: 'a-duplicate.pdf',
          filePath: 'https://example.com/a.pdf',
        },
        {
          fileName: 'b.pdf',
          filePath: 'https://example.com/b.pdf',
        },
      ],
    );

    expect(result).toHaveLength(2);
    expect(result[1]?.fileName).toBe('b.pdf');
  });

  it('超出文件限制时抛出错误', () => {
    expect(() =>
      validateWorkflowFileValues(
        new Array(11).fill(null).map((_, index) => ({
          fileName: `file-${index}.pdf`,
          filePath: `https://example.com/${index}.pdf`,
          size: 1024,
        })),
      ),
    ).toThrow('最多上传 10 个文件');
  });

  it('上传前校验文件数量限制', () => {
    const currentFiles = new Array(9).fill(null).map((_, index) => ({
      fileName: `file-${index}.pdf`,
      filePath: `https://example.com/${index}.pdf`,
      size: 1024,
    }));

    expect(() =>
      validateWorkflowFileSelection(currentFiles, [
        new File(['a'], 'a.pdf'),
        new File(['b'], 'b.pdf'),
      ]),
    ).toThrow('最多上传 10 个文件');
  });

  it('上传前校验单文件大小限制', () => {
    const oversizedFile = new File([new Uint8Array(6 * 1024 * 1024)], 'large.pdf');

    expect(() =>
      validateWorkflowFileSelection([], [oversizedFile]),
    ).toThrow('单个文件不能超过 5.0 MB');
  });

  it('上传前校验总大小限制', () => {
    const currentFiles = [
      {
        fileName: 'existing.pdf',
        filePath: 'https://example.com/existing.pdf',
        size: 49 * 1024 * 1024,
      },
    ];
    const incomingFile = new File([new Uint8Array(2 * 1024 * 1024)], 'new.pdf');

    expect(() =>
      validateWorkflowFileSelection(currentFiles, [incomingFile]),
    ).toThrow('文件总大小不能超过 50.0 MB');
  });
});
