import { OrderItemProcessingStatusValue } from '../../schemas';
import { ProcessingStatusState } from '../../models';
import { getProcessingStatusState } from './get-processing-status-state.helper';

describe('getProcessingStatusState', () => {
  describe('Ordered status', () => {
    it('should return Ordered when all items are Bestellt', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.Bestellt,
        OrderItemProcessingStatusValue.Bestellt,
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.Ordered);
    });
  });

  describe('Cancelled status', () => {
    it('should return Cancelled when all items are cancelled', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.StorniertKunde, // 512
        OrderItemProcessingStatusValue.Storniert, // 1024
        OrderItemProcessingStatusValue.StorniertLieferant, // 2048
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.Cancelled);
    });

    it('should return Cancelled when all items are AnsLagerNichtAbgeholt', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.AnsLagerNichtAbgeholt, // 262144
        OrderItemProcessingStatusValue.AnsLagerNichtAbgeholt, // 262144
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.Cancelled);
    });

    it('should return Cancelled when items are mix of cancelled statuses', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.StorniertKunde, // 512
        OrderItemProcessingStatusValue.AnsLagerNichtAbgeholt, // 262144
        OrderItemProcessingStatusValue.Storniert, // 1024
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.Cancelled);
    });
  });

  describe('NotFound status', () => {
    it('should return NotFound when all items are NichtLieferbar', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.NichtLieferbar, // 4096
        OrderItemProcessingStatusValue.NichtLieferbar, // 4096
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.NotFound);
    });
  });

  describe('Collected status', () => {
    it('should return Collected when all items are Abgeholt', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.Abgeholt, // 256
        OrderItemProcessingStatusValue.Abgeholt, // 256
      ];

      // Act
      const result = getProcessingStatusState(statuses);

      // Assert
      expect(result).toBe(ProcessingStatusState.Collected);
    });
  });

  describe('Undefined cases', () => {
    it('should return undefined when array is empty', () => {
      // Arrange
      const statuses: number[] = [];

      // Act
      const result = getProcessingStatusState(statuses);

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

    it('should return undefined when statuses is undefined', () => {
      // Arrange
      const statuses = undefined;

      // Act
      const result = getProcessingStatusState(statuses);

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

    it('should return undefined when items have mixed statuses', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.StorniertKunde, // 512
        OrderItemProcessingStatusValue.Abgeholt, // 256
      ];

      // Act
      const result = getProcessingStatusState(statuses);

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

    it('should return undefined when items have mix of ordered and cancelled', () => {
      // Arrange
      const statuses = [
        OrderItemProcessingStatusValue.Bestellt,
        OrderItemProcessingStatusValue.Storniert, // 1024
      ];

      // Act
      const result = getProcessingStatusState(statuses);

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