import { filterCheckboxOptionsHelper } from './filter-checkbox-options.helper';
import { CheckboxFilterInputOption } from '../core';

describe('filterCheckboxOptionsHelper', () => {
  const mockOptions: CheckboxFilterInputOption[] = [
    {
      path: ['category', 'electronics'],
      key: 'electronics',
      label: 'Electronics',
      values: [
        {
          path: ['category', 'electronics', 'laptops'],
          key: 'laptops',
          label: 'Laptops',
        },
        {
          path: ['category', 'electronics', 'phones'],
          key: 'phones',
          label: 'Mobile Phones',
        },
      ],
    },
    {
      path: ['category', 'clothing'],
      key: 'clothing',
      label: 'Clothing',
      values: [
        {
          path: ['category', 'clothing', 'shirts'],
          key: 'shirts',
          label: 'Shirts',
        },
        {
          path: ['category', 'clothing', 'pants'],
          key: 'pants',
          label: 'Pants',
        },
      ],
    },
    {
      path: ['category', 'books'],
      key: 'books',
      label: 'Books',
    },
  ];

  it('should return all options when query is empty', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, '');

    // Assert
    expect(result).toEqual(mockOptions);
  });

  it('should return all options when query is empty string', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, '');

    // Assert
    expect(result).toEqual(mockOptions);
  });

  it('should filter options by top-level label match', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'clothing');

    // Assert
    expect(result).toHaveLength(1);
    expect(result[0].label).toBe('Clothing');
    expect(result[0].values).toHaveLength(2); // Should keep all children
  });

  it('should filter options by child label match and keep parent', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'laptops');

    // Assert
    expect(result).toHaveLength(1);
    expect(result[0].label).toBe('Electronics');
    expect(result[0].values).toHaveLength(1);
    expect(result[0].values?.[0].label).toBe('Laptops');
  });

  it('should be case insensitive', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'ELECTRONICS');

    // Assert
    expect(result).toHaveLength(1);
    expect(result[0].label).toBe('Electronics');
  });

  it('should filter by partial matches', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'phone');

    // Assert
    expect(result).toHaveLength(1);
    expect(result[0].label).toBe('Electronics');
    expect(result[0].values).toHaveLength(1);
    expect(result[0].values?.[0].label).toBe('Mobile Phones');
  });

  it('should return empty array when no matches found', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'nonexistent');

    // Assert
    expect(result).toEqual([]);
  });

  it('should handle options without children', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 'books');

    // Assert
    expect(result).toHaveLength(1);
    expect(result[0].label).toBe('Books');
    expect(result[0].values).toBeUndefined();
  });

  it('should filter multiple matching options', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper(mockOptions, 's'); // Should match "Electronics", "Shirts", "Pants", "Books"

    // Assert - The actual behavior returns all 3 items:
    // 1. Electronics (label contains 's')
    // 2. Clothing (has children "Shirts" and "Pants" that contain 's')
    // 3. Books (label contains 's')
    expect(result).toHaveLength(3);
    expect(result.find((r) => r.label === 'Electronics')).toBeTruthy();
    expect(result.find((r) => r.label === 'Clothing')?.values).toHaveLength(2);
    expect(result.find((r) => r.label === 'Books')).toBeTruthy();
  });

  it('should handle empty options array', () => {
    // Arrange & Act
    const result = filterCheckboxOptionsHelper([], 'test');

    // Assert
    expect(result).toEqual([]);
  });
});
