import { renderHook, act, render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ToastProvider, useToast } from './ToastContext';
import { ReactNode } from 'react';

const wrapper = ({ children }: { children: ReactNode }) => (
  <ToastProvider>{children}</ToastProvider>
);

describe('ToastContext', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should provide toast context', () => {
    const { result } = renderHook(() => useToast(), { wrapper });

    expect(result.current).toBeDefined();
    expect(result.current).toHaveProperty('addToast');
    expect(typeof result.current.addToast).toBe('function');
  });

  it('should add toast', () => {
    const TestComponent = () => {
      const { addToast } = useToast();
      return (
        <div>
          <button onClick={() => addToast('Test message', 'info')}>
            Add Toast
          </button>
        </div>
      );
    };

    render(
      <ToastProvider>
        <TestComponent />
      </ToastProvider>,
    );

    const button = screen.getByText('Add Toast');
    act(() => {
      button.click();
    });

    // Toast should be added to the DOM
    expect(screen.getByText('Test message')).toBeInTheDocument();
  });

  it('should add success toast', () => {
    const TestComponent = () => {
      const { addToast } = useToast();
      return (
        <div>
          <button onClick={() => addToast('Success!', 'success')}>
            Add Success
          </button>
        </div>
      );
    };

    render(
      <ToastProvider>
        <TestComponent />
      </ToastProvider>,
    );

    const button = screen.getByText('Add Success');
    act(() => {
      button.click();
    });

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

  it('should add error toast', () => {
    const TestComponent = () => {
      const { addToast } = useToast();
      return (
        <div>
          <button onClick={() => addToast('Error!', 'error')}>Add Error</button>
        </div>
      );
    };

    render(
      <ToastProvider>
        <TestComponent />
      </ToastProvider>,
    );

    const button = screen.getByText('Add Error');
    act(() => {
      button.click();
    });

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

  it('should use default type info when type not provided', () => {
    const TestComponent = () => {
      const { addToast } = useToast();
      return (
        <div>
          <button onClick={() => addToast('Info message')}>Add Info</button>
        </div>
      );
    };

    render(
      <ToastProvider>
        <TestComponent />
      </ToastProvider>,
    );

    const button = screen.getByText('Add Info');
    act(() => {
      button.click();
    });

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