/* @vitest-environment jsdom */

import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, test, vi } from 'vitest';

import * as clipboardService from '../../services/clipboard';
import { useCopyFeedback } from './useCopyFeedback';

vi.mock('../../services/clipboard', () => ({
  copyTextToClipboard: vi.fn(),
}));

function CopyFeedbackHarness({
  value,
  resetDelayMs = 1400,
}: {
  value: string;
  resetDelayMs?: number;
}) {
  const { copyState, copyText, resetCopyState } = useCopyFeedback({
    resetDelayMs,
  });

  return (
    <div>
      <div data-testid="copy-state">{copyState}</div>
      <button
        type="button"
        onClick={() => {
          void copyText(value);
        }}
      >
        复制
      </button>
      <button type="button" onClick={resetCopyState}>
        重置
      </button>
    </div>
  );
}

afterEach(() => {
  vi.clearAllMocks();
  vi.useRealTimers();
});

describe('useCopyFeedback', () => {
  test('copies text and resets after the feedback delay', async () => {
    vi.useFakeTimers();
    vi.mocked(clipboardService.copyTextToClipboard).mockResolvedValue(true);

    render(<CopyFeedbackHarness value="作品号：PZ-1" resetDelayMs={10} />);

    fireEvent.click(screen.getByRole('button', { name: '复制' }));

    await act(async () => {
      await Promise.resolve();
    });
    expect(screen.getByTestId('copy-state').textContent).toBe('copied');
    expect(clipboardService.copyTextToClipboard).toHaveBeenCalledWith(
      '作品号：PZ-1',
    );

    act(() => {
      vi.advanceTimersByTime(10);
    });
    expect(screen.getByTestId('copy-state').textContent).toBe('idle');
  });

  test('keeps failure state until reset or timeout', async () => {
    vi.mocked(clipboardService.copyTextToClipboard).mockResolvedValue(false);

    render(<CopyFeedbackHarness value="" />);

    fireEvent.click(screen.getByRole('button', { name: '复制' }));

    await waitFor(() => {
      expect(screen.getByTestId('copy-state').textContent).toBe('failed');
    });

    fireEvent.click(screen.getByRole('button', { name: '重置' }));

    expect(screen.getByTestId('copy-state').textContent).toBe('idle');
  });
});
