import { describe, it, expect } from 'vitest';
import { hasOrderTypeFeature } from './has-order-type-feature.helper';
import { OrderType } from '../models';

describe('hasOrderTypeFeature', () => {
  describe('when features is undefined', () => {
    it('should return false', () => {
      // Act
      const result = hasOrderTypeFeature(undefined, [OrderType.Delivery]);

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

  describe('when features is empty', () => {
    it('should return false', () => {
      // Arrange
      const features = {};

      // Act
      const result = hasOrderTypeFeature(features, [OrderType.Delivery]);

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

  describe('when orderType feature is not present', () => {
    it('should return false', () => {
      // Arrange
      const features = { someOtherFeature: 'value' };

      // Act
      const result = hasOrderTypeFeature(features, [OrderType.Delivery]);

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

  describe('when orderType feature is invalid', () => {
    it('should return false', () => {
      // Arrange
      const features = { orderType: 'InvalidOrderType' };

      // Act
      const result = hasOrderTypeFeature(features, [OrderType.Delivery]);

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

  describe('when orderType feature matches one of the provided types', () => {
    it('should return true for Delivery in delivery types', () => {
      // Arrange
      const features = { orderType: OrderType.Delivery };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
      ]);

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

    it('should return true for DigitalShipping in delivery types', () => {
      // Arrange
      const features = { orderType: OrderType.DigitalShipping };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
      ]);

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

    it('should return true for B2BShipping in delivery types', () => {
      // Arrange
      const features = { orderType: OrderType.B2BShipping };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
      ]);

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

    it('should return true for InStore in branch types', () => {
      // Arrange
      const features = { orderType: OrderType.InStore };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.InStore,
        OrderType.Pickup,
      ]);

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

    it('should return true for Pickup in branch types', () => {
      // Arrange
      const features = { orderType: OrderType.Pickup };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.InStore,
        OrderType.Pickup,
      ]);

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

    it('should return true for Download when checked alone', () => {
      // Arrange
      const features = { orderType: OrderType.Download };

      // Act
      const result = hasOrderTypeFeature(features, [OrderType.Download]);

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

  describe('when orderType feature does not match any provided types', () => {
    it('should return false for Delivery when checking branch types', () => {
      // Arrange
      const features = { orderType: OrderType.Delivery };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.InStore,
        OrderType.Pickup,
      ]);

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

    it('should return false for InStore when checking delivery types', () => {
      // Arrange
      const features = { orderType: OrderType.InStore };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
      ]);

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

    it('should return false for Download when checking delivery types', () => {
      // Arrange
      const features = { orderType: OrderType.Download };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
      ]);

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

  describe('when checking against empty order types array', () => {
    it('should return false', () => {
      // Arrange
      const features = { orderType: OrderType.Delivery };

      // Act
      const result = hasOrderTypeFeature(features, []);

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

  describe('when checking against all order types', () => {
    it('should return true for any valid order type', () => {
      // Arrange
      const features = { orderType: OrderType.Delivery };

      // Act
      const result = hasOrderTypeFeature(features, [
        OrderType.InStore,
        OrderType.Pickup,
        OrderType.Delivery,
        OrderType.DigitalShipping,
        OrderType.B2BShipping,
        OrderType.Download,
      ]);

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