/**
 * UserFilters Component Tests
 * 
 * Tests for the UserFilters component that provides search and filter
 * functionality for user management.
 */

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

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

// Mock the Icon component
vi.mock('@/ui/Icon', () => ({
  Icon: ({ icon, size, intent }: any) => (
    <span data-testid="icon" data-size={size} data-intent={intent}>Icon</span>
  ),
}));

// Mock the Input component
vi.mock('@/ui/Input', () => ({
  Input: ({ type, placeholder, value, onChange, fullWidth }: any) => (
    <input
      type={type}
      placeholder={placeholder}
      value={value}
      onChange={onChange}
      data-full-width={fullWidth}
      data-testid="input"
    />
  ),
}));

// Mock the Select component
vi.mock('@/ui/Select', () => ({
  Select: ({ value, onChange, options }: any) => (
    <select value={value} onChange={onChange} data-testid="select">
      {options.map((opt: any) => (
        <option key={opt.value} value={opt.value}>{opt.label}</option>
      ))}
    </select>
  ),
}));

// Mock the Text component
vi.mock('@/ui/Text', () => ({
  Text: ({ children, weight, variant }: any) => (
    <span data-weight={weight} data-variant={variant}>{children}</span>
  ),
}));

// Mock the Box component
vi.mock('@/ui/Box', () => ({
  Box: ({ children, width }: any) => <div data-width={width}>{children}</div>,
}));

// Mock the Group component
vi.mock('@/ui/Group', () => ({
  Group: ({ children, gap }: any) => <div data-gap={gap}>{children}</div>,
}));

// Mock the AdminToolbar component
vi.mock('./AdminToolbar', () => ({
  AdminToolbar: ({ leftContent, children }: any) => (
    <div data-testid="admin-toolbar">
      {leftContent && <div data-testid="left-content">{leftContent}</div>}
      <div data-testid="children">{children}</div>
    </div>
  ),
}));

describe('UserFilters', () => {
  const defaultProps = {
    search: '',
    roleFilter: '',
    statusFilter: '',
    onSearch: vi.fn(),
    onFilterRole: vi.fn(),
    onFilterStatus: vi.fn(),
    onClearFilters: vi.fn(),
  };

  it('should render search input', () => {
    render(<UserFilters {...defaultProps} />);

    expect(screen.getByPlaceholderText('Search by email or name...')).toBeTruthy();
  });

  it('should render role filter select', () => {
    render(<UserFilters {...defaultProps} />);

    const selects = screen.getAllByTestId('select');
    expect(selects[0]).toBeTruthy();
  });

  it('should render status filter select', () => {
    render(<UserFilters {...defaultProps} />);

    const selects = screen.getAllByTestId('select');
    expect(selects[1]).toBeTruthy();
  });

  it('should render filter icon and label', () => {
    render(<UserFilters {...defaultProps} />);

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

  it('should render clear all button when filters are applied', () => {
    const props = {
      ...defaultProps,
      search: 'test',
    };

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

    expect(screen.getByText('Clear all')).toBeTruthy();
  });

  it('should not render clear all button when no filters are applied', () => {
    render(<UserFilters {...defaultProps} />);

    expect(screen.queryByText('Clear all')).toBeFalsy();
  });

  it('should call onSearch when search input changes', () => {
    const onSearch = vi.fn();
    const props = {
      ...defaultProps,
      onSearch,
    };

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

    const searchInput = screen.getByPlaceholderText('Search by email or name...');
    fireEvent.change(searchInput, { target: { value: 'john' } });

    expect(onSearch).toHaveBeenCalledWith('john');
  });

  it('should call onFilterRole when role select changes', () => {
    const onFilterRole = vi.fn();
    const props = {
      ...defaultProps,
      onFilterRole,
    };

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

    const roleSelect = screen.getAllByTestId('select')[0];
    fireEvent.change(roleSelect, { target: { value: 'admin' } });

    expect(onFilterRole).toHaveBeenCalledWith('admin');
  });

  it('should call onFilterStatus when status select changes', () => {
    const onFilterStatus = vi.fn();
    const props = {
      ...defaultProps,
      onFilterStatus,
    };

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

    const statusSelect = screen.getAllByTestId('select')[1];
    fireEvent.change(statusSelect, { target: { value: 'active' } });

    expect(onFilterStatus).toHaveBeenCalledWith('active');
  });

  it('should call onClearFilters when clear all button is clicked', () => {
    const onClearFilters = vi.fn();
    const props = {
      ...defaultProps,
      search: 'test',
      onClearFilters,
    };

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

    const clearButton = screen.getByText('Clear all');
    fireEvent.click(clearButton);

    expect(onClearFilters).toHaveBeenCalled();
  });

  it('should display current search value', () => {
    const props = {
      ...defaultProps,
      search: 'john@example.com',
    };

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

    const searchInput = screen.getByPlaceholderText('Search by email or name...');
    expect(searchInput).toHaveValue('john@example.com');
  });

  it('should display current role filter value', () => {
    const props = {
      ...defaultProps,
      roleFilter: 'admin',
    };

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

    const roleSelect = screen.getAllByTestId('select')[0];
    expect(roleSelect).toHaveValue('admin');
  });

  it('should display current status filter value', () => {
    const props = {
      ...defaultProps,
      statusFilter: 'suspended',
    };

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

    const statusSelect = screen.getAllByTestId('select')[1];
    expect(statusSelect).toHaveValue('suspended');
  });

  it('should render all role options', () => {
    render(<UserFilters {...defaultProps} />);

    const roleSelect = screen.getAllByTestId('select')[0];
    expect(roleSelect).toHaveTextContent('All Roles');
    expect(roleSelect).toHaveTextContent('Owner');
    expect(roleSelect).toHaveTextContent('Admin');
    expect(roleSelect).toHaveTextContent('User');
  });

  it('should render all status options', () => {
    render(<UserFilters {...defaultProps} />);

    const statusSelect = screen.getAllByTestId('select')[1];
    expect(statusSelect).toHaveTextContent('All Status');
    expect(statusSelect).toHaveTextContent('Active');
    expect(statusSelect).toHaveTextContent('Suspended');
    expect(statusSelect).toHaveTextContent('Deleted');
  });

  it('should render clear button when only search is applied', () => {
    const props = {
      ...defaultProps,
      search: 'test',
    };

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

    expect(screen.getByText('Clear all')).toBeTruthy();
  });

  it('should render clear button when only role filter is applied', () => {
    const props = {
      ...defaultProps,
      roleFilter: 'admin',
    };

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

    expect(screen.getByText('Clear all')).toBeTruthy();
  });

  it('should render clear button when only status filter is applied', () => {
    const props = {
      ...defaultProps,
      statusFilter: 'active',
    };

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

    expect(screen.getByText('Clear all')).toBeTruthy();
  });

  it('should render clear button when all filters are applied', () => {
    const props = {
      ...defaultProps,
      search: 'test',
      roleFilter: 'admin',
      statusFilter: 'active',
    };

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

    expect(screen.getByText('Clear all')).toBeTruthy();
  });
});
