import { KeyValueOfStringAndString } from '@isa/common/data-access';
import { getEnabledCustomerFeature } from './get-enabled-customer-feature.helper';
import { CustomerFeatureKey, CustomerFeatureGroup } from '../schemas';

describe('getEnabledCustomerFeature', () => {
  it('should return undefined when no features are provided', () => {
    // Arrange
    const customerFeatures: KeyValueOfStringAndString[] = [];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

    // Assert
    expect(result).toBeUndefined();
  });

  it('should return undefined when no features are enabled', () => {
    // Arrange
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.B2B,
        value: 'test',
        enabled: false,
        description: 'test description',
        group: CustomerFeatureGroup.DCustomerType,
      },
      {
        key: CustomerFeatureKey.Staff,
        value: 'test',
        enabled: false,
        description: 'test description',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

    // Assert
    expect(result).toBeUndefined();
  });

  it('should return the only enabled feature', () => {
    // Arrange
    const enabledFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.B2B,
      value: 'test-value',
      enabled: true,
      description: 'B2B feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      enabledFeature,
      {
        key: CustomerFeatureKey.Staff,
        value: 'test',
        enabled: false,
        description: 'Staff feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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

  it('should prefer d-account when multiple features are enabled', () => {
    // Arrange
    const dAccountFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.DAccount,
      value: 'account-value',
      enabled: true,
      description: 'D-Account feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.B2B,
        value: 'b2b-value',
        enabled: true,
        description: 'B2B feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
      dAccountFeature,
      {
        key: CustomerFeatureKey.Staff,
        value: 'staff-value',
        enabled: true,
        description: 'Staff feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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

  it('should prefer d-no-account when multiple features are enabled and d-account is not present', () => {
    // Arrange
    const dNoAccountFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.DNoAccount,
      value: 'no-account-value',
      enabled: true,
      description: 'D-No-Account feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.B2B,
        value: 'b2b-value',
        enabled: true,
        description: 'B2B feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
      dNoAccountFeature,
      {
        key: CustomerFeatureKey.Webshop,
        value: 'webshop-value',
        enabled: true,
        description: 'Webshop feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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

  it('should return first enabled feature when multiple are enabled but neither d-account nor d-no-account are present', () => {
    // Arrange
    const firstEnabledFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.B2B,
      value: 'b2b-value',
      enabled: true,
      description: 'B2B feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      firstEnabledFeature,
      {
        key: CustomerFeatureKey.Staff,
        value: 'staff-value',
        enabled: true,
        description: 'Staff feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
      {
        key: CustomerFeatureKey.Webshop,
        value: 'webshop-value',
        enabled: true,
        description: 'Webshop feature',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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

  it('should handle null or undefined customerFeatures gracefully', () => {
    // Act & Assert
    expect(getEnabledCustomerFeature(null as any)).toBeUndefined();
    expect(getEnabledCustomerFeature(undefined as any)).toBeUndefined();
  });

  it('should return undefined when enabled features have no description', () => {
    // Arrange
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.B2B,
        value: 'test-value',
        enabled: true,
        description: undefined,
        group: CustomerFeatureGroup.DCustomerType,
      },
      {
        key: CustomerFeatureKey.Staff,
        value: 'test-value',
        enabled: true,
        description: '',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

    // Assert
    expect(result).toBeUndefined();
  });

  it('should only consider features with both enabled flag and description', () => {
    // Arrange
    const validFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.B2B,
      value: 'test-value',
      enabled: true,
      description: 'Valid B2B feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.Staff,
        value: 'test-value',
        enabled: true,
        description: undefined,
        group: CustomerFeatureGroup.DCustomerType,
      },
      validFeature,
      {
        key: CustomerFeatureKey.Webshop,
        value: 'test-value',
        enabled: true,
        description: '',
        group: CustomerFeatureGroup.DCustomerType,
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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

  it('should return undefined when enabled features have wrong group', () => {
    // Arrange
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.B2B,
        value: 'test-value',
        enabled: true,
        description: 'B2B feature',
        group: CustomerFeatureGroup.CustomerType,
      },
      {
        key: CustomerFeatureKey.Staff,
        value: 'test-value',
        enabled: true,
        description: 'Staff feature',
        group: 'wrong-group',
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

    // Assert
    expect(result).toBeUndefined();
  });

  it('should only consider features with d-customertype group', () => {
    // Arrange
    const validFeature: KeyValueOfStringAndString = {
      key: CustomerFeatureKey.DAccount,
      value: 'test-value',
      enabled: true,
      description: 'Valid D-Account feature',
      group: CustomerFeatureGroup.DCustomerType,
    };
    const customerFeatures: KeyValueOfStringAndString[] = [
      {
        key: CustomerFeatureKey.Staff,
        value: 'test-value',
        enabled: true,
        description: 'Staff feature',
        group: CustomerFeatureGroup.CustomerType,
      },
      validFeature,
      {
        key: CustomerFeatureKey.Webshop,
        value: 'test-value',
        enabled: true,
        description: 'Webshop feature',
        group: 'other-group',
      },
    ];

    // Act
    const result = getEnabledCustomerFeature(customerFeatures);

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