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

describe('FocusTrap Component', () => {
  beforeEach(() => {
    // Reset focus before each test
    document.body.focus();
  });

  it('renders children', () => {
    render(
      <FocusTrap>
        <button>Button 1</button>
        <button>Button 2</button>
      </FocusTrap>,
    );

    expect(screen.getByText('Button 1')).toBeInTheDocument();
    expect(screen.getByText('Button 2')).toBeInTheDocument();
  });

  it('focuses first element when active', () => {
    render(
      <FocusTrap active={true}>
        <button>Button 1</button>
        <button>Button 2</button>
      </FocusTrap>,
    );

    const button1 = screen.getByText('Button 1');
    expect(document.activeElement).toBe(button1);
  });

  it('traps focus with Tab key', () => {
    render(
      <FocusTrap active={true}>
        <button>Button 1</button>
        <button>Button 2</button>
      </FocusTrap>,
    );

    const button1 = screen.getByText('Button 1');
    const button2 = screen.getByText('Button 2');

    // Focus the last element
    button2.focus();
    expect(document.activeElement).toBe(button2);

    // Tab from last element should wrap to first
    fireEvent.keyDown(document, { key: 'Tab' });
    expect(document.activeElement).toBe(button1);
  });

  it('traps focus with Shift+Tab key', () => {
    render(
      <FocusTrap active={true}>
        <button>Button 1</button>
        <button>Button 2</button>
      </FocusTrap>,
    );

    const button1 = screen.getByText('Button 1');
    const button2 = screen.getByText('Button 2');

    button1.focus();
    fireEvent.keyDown(document, { key: 'Tab', shiftKey: true });

    // Should wrap to last button
    expect(document.activeElement).toBe(button2);
  });

  it('calls onEscape when Escape key is pressed', () => {
    const mockOnEscape = vi.fn();

    render(
      <FocusTrap active={true} onEscape={mockOnEscape}>
        <button>Button 1</button>
      </FocusTrap>,
    );

    fireEvent.keyDown(document, { key: 'Escape' });

    expect(mockOnEscape).toHaveBeenCalled();
  });

  it('does not trap focus when active is false', () => {
    render(
      <FocusTrap active={false}>
        <button>Button 1</button>
      </FocusTrap>,
    );

    const button1 = screen.getByText('Button 1');
    // Focus should not be automatically set
    expect(document.activeElement).not.toBe(button1);
  });
});
