import type { ChatDocumentAttachment } from '@easyflow/common-ui';

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { loadAgentChatDocument } from './mediaApi';

const requestApi = vi.hoisted(() => ({
  download: vi.fn(),
}));

vi.mock('#/api/request', () => ({
  api: requestApi,
}));

const documentAttachment: ChatDocumentAttachment = {
  downloadUrl:
    '/api/v1/agent/media/document/content?reference=document:attachment',
  name: '需求说明.docx',
  status: 'ready',
};

describe('agent chat document download', () => {
  beforeEach(() => {
    vi.useFakeTimers();
    vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:document');
    vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined);
    vi.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(
      () => undefined,
    );
  });

  afterEach(() => {
    vi.useRealTimers();
    vi.restoreAllMocks();
    requestApi.download.mockReset();
  });

  it('downloads a non-empty blob and revokes its URL after the browser takes over', async () => {
    requestApi.download.mockResolvedValue(new Blob(['document']));

    await loadAgentChatDocument(documentAttachment);

    expect(requestApi.download).toHaveBeenCalledWith(
      documentAttachment.downloadUrl,
    );
    expect(URL.createObjectURL).toHaveBeenCalledTimes(1);
    expect(HTMLAnchorElement.prototype.click).toHaveBeenCalledTimes(1);
    expect(URL.revokeObjectURL).not.toHaveBeenCalled();

    await vi.advanceTimersByTimeAsync(1000);

    expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:document');
  });

  it('rejects an empty response before creating a damaged download', async () => {
    requestApi.download.mockResolvedValue(new Blob([]));

    await expect(loadAgentChatDocument(documentAttachment)).rejects.toThrow(
      '下载内容为空，请稍后重试',
    );

    expect(URL.createObjectURL).not.toHaveBeenCalled();
    expect(HTMLAnchorElement.prototype.click).not.toHaveBeenCalled();
  });
});
