/**
 * BulkActionBar Component Tests
 * 
 * Tests for the BulkActionBar component that displays a floating action bar
 * when items are selected in a table.
 */

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

// Mock the Button component
vi.mock('@/ui/Button', () => ({
  Button: ({ children, onClick, variant, size, icon }: any) => (
    <button
      onClick={onClick}
      data-variant={variant}
      data-size={size}
      data-testid="button"
    >
      {children}
    </button>
  ),
}));

// Mock the BulkActions component
vi.mock('@/ui/BulkActions', () => ({
  BulkActions: ({ selectedCount, isOpen, children }: any) => (
    <div data-testid="bulk-actions" data-open={isOpen} data-count={selectedCount}>
      {children}
    </div>
  ),
}));

describe('BulkActionBar', () => {
  const defaultProps = {
    selectedCount: 0,
    actions: [],
    onClearSelection: vi.fn(),
  };

  it('should not render when no items selected', () => {
    render(<BulkActionBar {...defaultProps} />);

    expect(screen.queryByTestId('bulk-actions')).toBeFalsy();
  });

  it('should render when items are selected', () => {
    const props = {
      ...defaultProps,
      selectedCount: 3,
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByTestId('bulk-actions')).toBeTruthy();
  });

  it('should display selected count', () => {
    const props = {
      ...defaultProps,
      selectedCount: 5,
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByTestId('bulk-actions')).toHaveAttribute('data-count', '5');
  });

  it('should render with single action', () => {
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Delete',
          onClick: vi.fn(),
          variant: 'danger' as const,
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByText('Delete')).toBeTruthy();
  });

  it('should render with multiple actions', () => {
    const props = {
      ...defaultProps,
      selectedCount: 3,
      actions: [
        {
          label: 'Export',
          onClick: vi.fn(),
          variant: 'primary' as const,
        },
        {
          label: 'Archive',
          onClick: vi.fn(),
          variant: 'secondary' as const,
        },
        {
          label: 'Delete',
          onClick: vi.fn(),
          variant: 'danger' as const,
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByText('Export')).toBeTruthy();
    expect(screen.getByText('Archive')).toBeTruthy();
    expect(screen.getByText('Delete')).toBeTruthy();
  });

  it('should render cancel button', () => {
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Delete',
          onClick: vi.fn(),
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByText('Cancel')).toBeTruthy();
  });

  it('should call action onClick when clicked', () => {
    const actionOnClick = vi.fn();
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Delete',
          onClick: actionOnClick,
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    const deleteButton = screen.getByText('Delete');
    fireEvent.click(deleteButton);

    expect(actionOnClick).toHaveBeenCalled();
  });

  it('should call onClearSelection when cancel is clicked', () => {
    const onClearSelection = vi.fn();
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Delete',
          onClick: vi.fn(),
        },
      ],
      onClearSelection,
    };

    render(<BulkActionBar {...props} />);

    const cancelButton = screen.getByText('Cancel');
    fireEvent.click(cancelButton);

    expect(onClearSelection).toHaveBeenCalled();
  });

  it('should render actions with different variants', () => {
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Primary',
          onClick: vi.fn(),
          variant: 'primary' as const,
        },
        {
          label: 'Secondary',
          onClick: vi.fn(),
          variant: 'secondary' as const,
        },
        {
          label: 'Danger',
          onClick: vi.fn(),
          variant: 'danger' as const,
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByText('Primary')).toBeTruthy();
    expect(screen.getByText('Secondary')).toBeTruthy();
    expect(screen.getByText('Danger')).toBeTruthy();
  });

  it('should render actions without variant (defaults to primary)', () => {
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [
        {
          label: 'Default',
          onClick: vi.fn(),
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByText('Default')).toBeTruthy();
  });

  it('should render with empty actions array', () => {
    const props = {
      ...defaultProps,
      selectedCount: 2,
      actions: [],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByTestId('bulk-actions')).toBeTruthy();
    expect(screen.getByText('Cancel')).toBeTruthy();
  });

  it('should render with large selected count', () => {
    const props = {
      ...defaultProps,
      selectedCount: 100,
      actions: [
        {
          label: 'Delete',
          onClick: vi.fn(),
        },
      ],
    };

    render(<BulkActionBar {...props} />);

    expect(screen.getByTestId('bulk-actions')).toHaveAttribute('data-count', '100');
  });
});
