import { describe, expect, it } from 'vitest';
import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ToastProvider, useToast } from '@/hooks/useToast';
import { ToastViewport } from '@/components/Toast';

function Pusher() {
  const { push } = useToast();
  return (
    <div>
      <button onClick={() => push('Session expirée', 'error')}>Push session</button>
    </div>
  );
}

describe('Toast', () => {
  it('renders pushed toasts and lets the user dismiss them manually', async () => {
    const user = userEvent.setup();
    render(
      <ToastProvider>
        <Pusher />
        <ToastViewport />
      </ToastProvider>,
    );

    await user.click(screen.getByRole('button', { name: /push session/i }));
    const toast = await screen.findByTestId('toast');
    expect(toast).toHaveTextContent('Session expirée');
    expect(toast).toHaveAttribute('data-kind', 'error');

    await user.click(screen.getByRole('button', { name: /dismiss/i }));
    await waitFor(() => {
      expect(screen.queryByTestId('toast')).toBeNull();
    });
  });

  it('auto-dismisses after the timeout', async () => {
    // Override the 4s default by polling the DOM up to 6s. Real timers keep
    // user-event happy; the toast hook clears itself via setTimeout.
    const user = userEvent.setup();
    render(
      <ToastProvider>
        <Pusher />
        <ToastViewport />
      </ToastProvider>,
    );

    await user.click(screen.getByRole('button', { name: /push session/i }));
    expect(await screen.findByTestId('toast')).toBeInTheDocument();

    await waitFor(
      () => {
        expect(screen.queryByTestId('toast')).toBeNull();
      },
      { timeout: 6000 },
    );
    // Quiet act() warning by flushing any pending state.
    await act(async () => {
      await Promise.resolve();
    });
  }, 10_000);
});
