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

import { copyTextToClipboard } from '@easyflow/utils';

import { ElMessage } from 'element-plus';
import { afterEach, describe, expect, it, vi } from 'vitest';

import ChatMessageActionBar from './ChatMessageActionBar.vue';

vi.mock('@easyflow/utils', () => ({
  copyTextToClipboard: vi.fn(),
}));

vi.mock('element-plus', () => ({
  ElMessage: {
    error: vi.fn(),
  },
}));

describe('chat message action bar', () => {
  afterEach(() => {
    vi.clearAllMocks();
    vi.useRealTimers();
  });

  it('shows a check icon after copying and restores the copy icon', async () => {
    vi.useFakeTimers();
    vi.mocked(copyTextToClipboard).mockResolvedValue('clipboard-api');
    const wrapper = mount(ChatMessageActionBar, {
      props: {
        allowCopy: true,
        copyText: '消息内容',
      },
    });

    await wrapper.get('[aria-label="复制消息"]').trigger('click');
    await flushPromises();

    expect(copyTextToClipboard).toHaveBeenCalledWith('消息内容');
    expect(wrapper.get('button').attributes('aria-label')).toBe('复制成功');
    expect(wrapper.get('button').classes()).not.toContain('is-copied');
    expect(ElMessage.error).not.toHaveBeenCalled();

    await vi.advanceTimersByTimeAsync(1600);

    expect(wrapper.get('button').attributes('aria-label')).toBe('复制消息');
  });

  it('keeps the copy icon and shows the existing warning on failure', async () => {
    vi.spyOn(console, 'error').mockImplementation(() => undefined);
    vi.mocked(copyTextToClipboard).mockRejectedValue(new Error('copy denied'));
    const wrapper = mount(ChatMessageActionBar, {
      props: {
        allowCopy: true,
        copyErrorMessage: '复制失败，请重试',
        copyText: '消息内容',
      },
    });

    await wrapper.get('[aria-label="复制消息"]').trigger('click');
    await flushPromises();

    expect(wrapper.get('button').attributes('aria-label')).toBe('复制消息');
    expect(ElMessage.error).toHaveBeenCalledWith('复制失败，请重试');
  });
});
