/**
 * BulkActions Component Tests
 *
 * Comprehensive tests for the bulk actions toolbar component.
 */

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BulkActions } from '@/features/issues/components/BulkActions';

describe('BulkActions', () => {
  const defaultProps = {
    selectedCount: 3,
    onChangeStatus: jest.fn(),
    onAssign: jest.fn(),
    onAddLabels: jest.fn(),
    onDelete: jest.fn(),
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Visibility', () => {
    it('renders when selectedCount > 0', () => {
      render(<BulkActions {...defaultProps} />);
      expect(screen.getByRole('toolbar')).toBeInTheDocument();
    });

    it('does not render when selectedCount is 0', () => {
      render(<BulkActions {...defaultProps} selectedCount={0} />);
      expect(screen.queryByRole('toolbar')).not.toBeInTheDocument();
    });
  });

  describe('Selected count display', () => {
    it('displays the selected count', () => {
      render(<BulkActions {...defaultProps} selectedCount={5} />);
      expect(screen.getByText('5 selected')).toBeInTheDocument();
    });

    it('displays singular count correctly', () => {
      render(<BulkActions {...defaultProps} selectedCount={1} />);
      expect(screen.getByText('1 selected')).toBeInTheDocument();
    });

    it('displays large count correctly', () => {
      render(<BulkActions {...defaultProps} selectedCount={100} />);
      expect(screen.getByText('100 selected')).toBeInTheDocument();
    });
  });

  describe('Action buttons', () => {
    it('renders Change Status button', () => {
      render(<BulkActions {...defaultProps} />);
      expect(screen.getByRole('button', { name: 'Change Status' })).toBeInTheDocument();
    });

    it('renders Assign button', () => {
      render(<BulkActions {...defaultProps} />);
      expect(screen.getByRole('button', { name: 'Assign' })).toBeInTheDocument();
    });

    it('renders Add Labels button', () => {
      render(<BulkActions {...defaultProps} />);
      expect(screen.getByRole('button', { name: 'Add Labels' })).toBeInTheDocument();
    });

    it('renders Delete button', () => {
      render(<BulkActions {...defaultProps} />);
      expect(screen.getByRole('button', { name: /delete/i })).toBeInTheDocument();
    });
  });

  describe('Button callbacks', () => {
    it('calls onChangeStatus when Change Status is clicked', async () => {
      const user = userEvent.setup();
      render(<BulkActions {...defaultProps} />);

      await user.click(screen.getByRole('button', { name: 'Change Status' }));
      expect(defaultProps.onChangeStatus).toHaveBeenCalledTimes(1);
    });

    it('calls onAssign when Assign is clicked', async () => {
      const user = userEvent.setup();
      render(<BulkActions {...defaultProps} />);

      await user.click(screen.getByRole('button', { name: 'Assign' }));
      expect(defaultProps.onAssign).toHaveBeenCalledTimes(1);
    });

    it('calls onAddLabels when Add Labels is clicked', async () => {
      const user = userEvent.setup();
      render(<BulkActions {...defaultProps} />);

      await user.click(screen.getByRole('button', { name: 'Add Labels' }));
      expect(defaultProps.onAddLabels).toHaveBeenCalledTimes(1);
    });

    it('calls onDelete when Delete is clicked', async () => {
      const user = userEvent.setup();
      render(<BulkActions {...defaultProps} />);

      await user.click(screen.getByRole('button', { name: /delete/i }));
      expect(defaultProps.onDelete).toHaveBeenCalledTimes(1);
    });
  });

  describe('Accessibility', () => {
    it('has accessible toolbar role', () => {
      render(<BulkActions {...defaultProps} />);
      const toolbar = screen.getByRole('toolbar');
      expect(toolbar).toHaveAttribute('aria-label', 'Bulk actions for selected issues');
    });

    it('delete icon has aria-hidden', () => {
      render(<BulkActions {...defaultProps} />);
      const icons = document.querySelectorAll('[aria-hidden="true"]');
      expect(icons.length).toBeGreaterThan(0);
    });
  });

  describe('Styling', () => {
    it('applies custom className', () => {
      render(<BulkActions {...defaultProps} className="custom-toolbar-class" />);
      expect(screen.getByRole('toolbar')).toHaveClass('custom-toolbar-class');
    });

    it('delete button has destructive styling', () => {
      render(<BulkActions {...defaultProps} />);
      const deleteButton = screen.getByRole('button', { name: /delete/i });
      expect(deleteButton).toHaveClass('text-destructive');
    });
  });

  describe('Edge cases', () => {
    it('handles rapid clicks on all buttons', async () => {
      const user = userEvent.setup();
      render(<BulkActions {...defaultProps} />);

      await user.click(screen.getByRole('button', { name: 'Change Status' }));
      await user.click(screen.getByRole('button', { name: 'Assign' }));
      await user.click(screen.getByRole('button', { name: 'Add Labels' }));
      await user.click(screen.getByRole('button', { name: /delete/i }));

      expect(defaultProps.onChangeStatus).toHaveBeenCalledTimes(1);
      expect(defaultProps.onAssign).toHaveBeenCalledTimes(1);
      expect(defaultProps.onAddLabels).toHaveBeenCalledTimes(1);
      expect(defaultProps.onDelete).toHaveBeenCalledTimes(1);
    });

    it('works with very large selected count', () => {
      render(<BulkActions {...defaultProps} selectedCount={999999} />);
      expect(screen.getByText('999999 selected')).toBeInTheDocument();
    });
  });
});
