import type { ChatDocumentAttachment } from '../types';

import { flushPromises, mount } from '@vue/test-utils';

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

import ChatDocumentAttachments from '../ChatDocumentAttachments.vue';

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

describe('chat document attachments', () => {
  it('downloads a ready document through the authenticated loader', async () => {
    const loader = vi.fn().mockResolvedValue(undefined);
    const wrapper = mount(ChatDocumentAttachments, {
      props: {
        documentLoader: loader,
        items: [document],
      },
    });

    await wrapper.get('.chat-document-attachments__main').trigger('click');

    expect(loader).toHaveBeenCalledWith(document);
    expect(wrapper.text()).toContain('需求说明.docx');
    expect(wrapper.text()).toContain('2 KB');
  });

  it('exposes retry and remove actions for a failed document', async () => {
    const failed = {
      ...document,
      error: '读取失败',
      status: 'error' as const,
    };
    const wrapper = mount(ChatDocumentAttachments, {
      props: {
        items: [failed],
        removable: true,
        retryable: true,
      },
    });

    await wrapper.get('[aria-label="重新读取文档"]').trigger('click');
    await wrapper.get('[aria-label="移除文档"]').trigger('click');

    expect(wrapper.emitted('retry')?.[0]).toEqual([failed]);
    expect(wrapper.emitted('remove')?.[0]).toEqual([failed]);
    expect(wrapper.text()).toContain('读取失败');
  });

  it('uses compact type-specific icons for supported document formats', () => {
    const items: ChatDocumentAttachment[] = [
      { ...document, name: 'paper.pdf', mimeType: 'application/pdf' },
      { ...document, name: 'report.docx' },
      { ...document, name: 'table.xlsx' },
      { ...document, name: 'slides.pptx' },
      { ...document, name: 'notes.txt' },
      { ...document, name: 'readme.md' },
      { ...document, name: 'archive.bin' },
    ];
    const wrapper = mount(ChatDocumentAttachments, {
      props: { items },
    });

    const types = wrapper
      .findAll('.chat-document-attachments__item')
      .map((item) => item.attributes('data-document-type'));

    expect(types).toEqual([
      'pdf',
      'word',
      'spreadsheet',
      'presentation',
      'text',
      'markdown',
      'generic',
    ]);
    expect(
      wrapper
        .find(
          '[data-document-type="text"] .chat-document-attachments__icon-box',
        )
        .classes(),
    ).toContain('is-text');
    expect(wrapper.text()).toContain('PDF · 2 KB');
    expect(wrapper.text()).toContain('TXT · 2 KB');
  });

  it('preserves a long filename for the ellipsis tooltip', () => {
    const longName =
      '这是一个用于验证固定宽度附件卡片标题省略行为的超长产品需求说明文档.docx';
    const wrapper = mount(ChatDocumentAttachments, {
      props: {
        items: [{ ...document, name: longName }],
      },
    });

    const filename = wrapper.get('.chat-document-attachments__name');
    expect(filename.attributes('title')).toBe(longName);
    expect(filename.text()).toBe(longName);
  });

  it('shows a recoverable download error without triggering another file', async () => {
    const loader = vi
      .fn()
      .mockRejectedValue(new Error('下载内容为空，请稍后重试'));
    const wrapper = mount(ChatDocumentAttachments, {
      props: {
        documentLoader: loader,
        items: [document],
      },
    });

    await wrapper.get('.chat-document-attachments__main').trigger('click');
    await flushPromises();

    expect(wrapper.text()).toContain('下载内容为空，请稍后重试');
    expect(wrapper.get('.chat-document-attachments__item').classes()).toContain(
      'has-download-error',
    );
  });
});
