import { getOptionKeyHelper } from './get-option-key.helper';
import { CheckboxFilterInputOption } from '../core';

describe('getOptionKeyHelper', () => {
  const createCheckboxOption = (
    key: string,
    label: string,
    path: string[] = ['test'],
    value?: string,
  ): CheckboxFilterInputOption => ({
    path,
    key,
    label,
    value,
  });

  describe('with key property', () => {
    it('should return the key when present', () => {
      // Arrange
      const option = createCheckboxOption(
        'test-key',
        'Test Label',
        ['test'],
        'test-value',
      );

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('test-key');
    });

    it('should return the key even when value and label are also present', () => {
      // Arrange
      const option = createCheckboxOption(
        'priority-key',
        'Fallback Label',
        ['test'],
        'fallback-value',
      );

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('priority-key');
    });
  });

  describe('fallback to value property', () => {
    it('should return the value when key is empty string but value is present', () => {
      // Arrange
      const option = createCheckboxOption(
        '',
        'Test Label',
        ['test'],
        'fallback-value',
      );

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('fallback-value');
    });
  });

  describe('fallback to label property', () => {
    it('should return the label when key and value are both empty strings', () => {
      // Arrange
      const option = createCheckboxOption('', 'Fallback Label', ['test'], '');

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('Fallback Label');
    });

    it('should return the label when key is empty and value is undefined', () => {
      // Arrange
      const option = createCheckboxOption('', 'Only Label Available', ['test']);

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('Only Label Available');
    });
  });

  describe('edge cases and error handling', () => {
    it('should return empty string when all identifier properties are empty strings', () => {
      // Arrange
      const option = createCheckboxOption('', '', ['test'], '');

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('');
    });

    it('should handle options with only whitespace in key property', () => {
      // Arrange
      const option = createCheckboxOption(
        '  ',
        'Clean Label',
        ['test'],
        'clean-value',
      );

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('  '); // Returns the key even with spaces
    });

    it('should prefer value over label when key is empty', () => {
      // Arrange
      const option = createCheckboxOption(
        '',
        'Available Label',
        ['test'],
        'Available Value',
      );

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('Available Value'); // value comes before label in fallback chain
    });

    it('should handle missing value property gracefully', () => {
      // Arrange - simulate scenario where helper checks for truthy key first
      const option: CheckboxFilterInputOption = {
        path: ['test'],
        key: '', // empty key should trigger fallback
        label: 'Fallback to Label',
        // value is optional and not provided
      };

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('Fallback to Label');
    });
  });

  describe('real-world scenarios', () => {
    it('should work with typical checkbox option structure', () => {
      // Arrange
      const option: CheckboxFilterInputOption = {
        path: ['category', 'electronics'],
        key: 'electronics',
        label: 'Electronics Category',
      };

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('electronics');
    });

    it('should work with options that have both key and value', () => {
      // Arrange
      const option: CheckboxFilterInputOption = {
        path: ['category', 'books'],
        key: 'books',
        label: 'Books & Literature',
        value: 'book-category',
      };

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('books'); // key takes priority
    });

    it('should work with API responses that need fallback to value', () => {
      // Arrange
      const option: CheckboxFilterInputOption = {
        path: ['filter', 'status'],
        key: '', // empty key forces fallback
        label: 'Active Items',
        value: 'active',
      };

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('active');
    });

    it('should handle complex nested path structures', () => {
      // Arrange
      const option: CheckboxFilterInputOption = {
        path: ['catalog', 'electronics', 'computers', 'laptops'],
        key: 'gaming-laptops',
        label: 'Gaming Laptops',
        value: 'laptop-gaming',
      };

      // Act
      const result = getOptionKeyHelper(option);

      // Assert
      expect(result).toBe('gaming-laptops');
    });
  });
});
