import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, test, expect, vi } from 'vitest';
import '@testing-library/jest-dom/vitest';
import InfoBar from './InfoBar.js';

// Mock the lucide-react Info icon
vi.mock('lucide-react', () => ({
  Info: ({ size }: { size: number }) => (
    <svg data-testid="info-icon" width={size} height={size}>
      <circle cx="12" cy="12" r="10" />
    </svg>
  ),
}));

describe('InfoBar', () => {
  describe('Rendering', () => {
    test('renders with string children', () => {
      render(<InfoBar>Test message</InfoBar>);

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

    test('renders with React element children', () => {
      const TestElement = <span>React element message</span>;
      render(<InfoBar>{TestElement}</InfoBar>);

      expect(screen.getByText('React element message')).toBeInTheDocument();
    });

    test('renders the Info icon', () => {
      render(<InfoBar>Test message</InfoBar>);

      const icon = screen.getByTestId('info-icon');
      expect(icon).toBeInTheDocument();
      expect(icon).toHaveAttribute('width', '16');
      expect(icon).toHaveAttribute('height', '16');
    });
  });

  describe('Accessibility', () => {
    test('has proper DOM structure for screen readers', () => {
      render(<InfoBar>Important information</InfoBar>);

      const container = screen.getByText('Important information').closest('.info-bar');
      expect(container).toBeInTheDocument();

      // Check that icon and message are siblings for proper reading order
      const content = screen.getByText('Important information').closest('.info-bar__content');
      const children = content?.children;
      expect(children).toHaveLength(2);
      expect(children?.[0]).toHaveClass('info-bar__icon');
      expect(children?.[1]).toHaveClass('info-bar__message');
    });

    test('maintains proper reading order with icon first, then message', () => {
      render(<InfoBar>Test message</InfoBar>);

      const content = document.querySelector('.info-bar__content');
      const firstChild = content?.firstElementChild;
      const secondChild = content?.lastElementChild;

      expect(firstChild).toHaveClass('info-bar__icon');
      expect(secondChild).toHaveClass('info-bar__message');
    });
  });

  describe('Edge Cases', () => {
    test('handles very long messages', () => {
      const longMessage =
        'This is a very long message that might wrap to multiple lines and should still be displayed correctly in the info bar component without breaking the layout or functionality.';

      render(<InfoBar>{longMessage}</InfoBar>);

      expect(screen.getByText(longMessage)).toBeInTheDocument();
    });

    test('handles special characters in messages', () => {
      const specialMessage = 'Message with special chars: @#$%^&*()_+-=[]{}|;:,.<>?';

      render(<InfoBar>{specialMessage}</InfoBar>);

      expect(screen.getByText(specialMessage)).toBeInTheDocument();
    });

    test('handles HTML entities in string messages', () => {
      const htmlMessage = 'Message with &amp; &lt; &gt; entities';

      render(<InfoBar>{htmlMessage}</InfoBar>);

      expect(screen.getByText(htmlMessage)).toBeInTheDocument();
    });
  });

  describe('Component Integration', () => {
    test('works correctly when nested in other components', () => {
      const Wrapper = ({ children }: { children: React.ReactNode }) => (
        <div data-testid="wrapper">{children}</div>
      );

      render(
        <Wrapper>
          <InfoBar>Nested message</InfoBar>
        </Wrapper>,
      );

      expect(screen.getByTestId('wrapper')).toBeInTheDocument();
      expect(screen.getByText('Nested message')).toBeInTheDocument();
    });

    test('maintains functionality with multiple InfoBar instances', () => {
      render(
        <div>
          <InfoBar>First message</InfoBar>
          <InfoBar>Second message</InfoBar>
        </div>,
      );

      expect(screen.getByText('First message')).toBeInTheDocument();
      expect(screen.getByText('Second message')).toBeInTheDocument();
      expect(screen.getAllByTestId('info-icon')).toHaveLength(2);
    });
  });
});
