import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { Toast } from './Toast';

describe('Toast Component', () => {
  const mockOnClose = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    vi.useFakeTimers();
  });

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

  it('renders toast with message', () => {
    render(
      <Toast id="1" type="info" message="Test message" onClose={mockOnClose} />,
    );

    expect(screen.getByText('Test message')).toBeInTheDocument();
  });

  it('renders success toast', () => {
    render(
      <Toast id="1" type="success" message="Success!" onClose={mockOnClose} />,
    );

    expect(screen.getByText('Success!')).toBeInTheDocument();
  });

  it('renders error toast', () => {
    render(
      <Toast id="1" type="error" message="Error!" onClose={mockOnClose} />,
    );

    expect(screen.getByText('Error!')).toBeInTheDocument();
  });

  it('calls onClose when close button is clicked', () => {
    render(<Toast id="1" type="info" message="Test" onClose={mockOnClose} />);

    const closeButton = screen.getByRole('button');
    fireEvent.click(closeButton);

    expect(mockOnClose).toHaveBeenCalledWith('1');
  });

  it('calls onClose automatically after 4 seconds', async () => {
    render(<Toast id="1" type="info" message="Test" onClose={mockOnClose} />);

    vi.advanceTimersByTime(4000);

    // With fake timers, we need to flush pending timers
    await vi.runAllTimersAsync();

    expect(mockOnClose).toHaveBeenCalledWith('1');
  });

  it('applies correct styles for success variant', () => {
    const { container } = render(
      <Toast id="1" type="success" message="Test" onClose={mockOnClose} />,
    );

    const toast = container.firstChild as HTMLElement;
    expect(toast.className).toContain('border-kodo-lime');
  });

  it('applies correct styles for error variant', () => {
    const { container } = render(
      <Toast id="1" type="error" message="Test" onClose={mockOnClose} />,
    );

    const toast = container.firstChild as HTMLElement;
    expect(toast.className).toContain('border-kodo-red');
  });

  it('applies correct styles for info variant', () => {
    const { container } = render(
      <Toast id="1" type="info" message="Test" onClose={mockOnClose} />,
    );

    const toast = container.firstChild as HTMLElement;
    expect(toast.className).toContain('border-kodo-cyan');
  });
});
