import { describe, it, expect } from 'vitest';
import { LogisticianAdapter } from './logistician.adapter';
import { LogisticianDTO as OmsLogisticianDTO } from '@generated/swagger/oms-api';

describe('LogisticianAdapter', () => {
  describe('toCatalogueFormat', () => {
    it('should convert oms logistician to catalogue format', () => {
      // Arrange
      const omsLogistician: OmsLogisticianDTO = {
        id: 1,
        logisticianNumber: 'LOG001',
        name: 'Main Logistician',
        gln: 'GLN123',
      };

      // Act
      const result = LogisticianAdapter.toCatalogueFormat(omsLogistician);

      // Assert
      expect(result.id).toBe(1);
      expect(result.logisticianNumber).toBe('LOG001');
      expect(result.name).toBe('Main Logistician');
      expect(result.gln).toBe('GLN123');
    });

    it('should throw error when logistician missing id', () => {
      // Arrange
      const invalidLogistician: OmsLogisticianDTO = {
        // id missing
        name: 'Test Logistician',
      };

      // Act & Assert
      expect(() =>
        LogisticianAdapter.toCatalogueFormat(invalidLogistician),
      ).toThrow('Logistician missing required id');
    });

    it('should preserve all logistician properties', () => {
      // Arrange
      const fullLogistician: OmsLogisticianDTO = {
        id: 5,
        logisticianNumber: 'LOG005',
        name: 'Test Logistician',
        gln: 'GLN456',
        status: 1,
        version: 2,
      };

      // Act
      const result = LogisticianAdapter.toCatalogueFormat(fullLogistician);

      // Assert
      expect(result.id).toBe(5);
      expect(result.logisticianNumber).toBe('LOG005');
      expect(result.gln).toBe('GLN456');
      expect(result.status).toBe(1);
      expect(result.version).toBe(2);
    });

    it('should handle minimal logistician with only id', () => {
      // Arrange
      const minimalLogistician: OmsLogisticianDTO = {
        id: 99,
      };

      // Act
      const result = LogisticianAdapter.toCatalogueFormat(minimalLogistician);

      // Assert
      expect(result.id).toBe(99);
      expect(Object.keys(result).length).toBe(1);
    });
  });

  describe('isValidOmsLogistician', () => {
    it('should return true for valid oms logistician', () => {
      const validLogistician: OmsLogisticianDTO = {
        id: 1,
        name: 'Test',
      };

      expect(LogisticianAdapter.isValidOmsLogistician(validLogistician)).toBe(
        true,
      );
    });

    it('should return true for logistician with only id', () => {
      const validLogistician = { id: 1 };

      expect(LogisticianAdapter.isValidOmsLogistician(validLogistician)).toBe(
        true,
      );
    });

    it('should return false for invalid types', () => {
      expect(LogisticianAdapter.isValidOmsLogistician(null)).toBe(false);
      expect(LogisticianAdapter.isValidOmsLogistician(undefined)).toBe(false);
      expect(LogisticianAdapter.isValidOmsLogistician('string')).toBe(false);
      expect(LogisticianAdapter.isValidOmsLogistician([])).toBe(false);
    });

    it('should return false for logistician without numeric id', () => {
      const invalidLogisticians = [
        { id: 'string' },
        { id: null },
        { id: undefined },
        { name: 'Test' },
      ];

      invalidLogisticians.forEach((logistician) => {
        expect(LogisticianAdapter.isValidOmsLogistician(logistician)).toBe(
          false,
        );
      });
    });
  });

  describe('isValidCatalogueLogistician', () => {
    it('should return true for valid catalogue logistician', () => {
      const validLogistician = {
        id: 1,
        additionalProp: 'value',
      };

      expect(
        LogisticianAdapter.isValidCatalogueLogistician(validLogistician),
      ).toBe(true);
    });

    it('should return true for minimal logistician with only id', () => {
      const validLogistician = { id: 1 };

      expect(
        LogisticianAdapter.isValidCatalogueLogistician(validLogistician),
      ).toBe(true);
    });

    it('should return false for invalid types', () => {
      expect(LogisticianAdapter.isValidCatalogueLogistician(null)).toBe(false);
      expect(LogisticianAdapter.isValidCatalogueLogistician(undefined)).toBe(
        false,
      );
      expect(LogisticianAdapter.isValidCatalogueLogistician('string')).toBe(
        false,
      );
    });

    it('should return false for logistician without numeric id', () => {
      const invalidLogisticians = [
        { id: 'string' },
        { id: null },
        { name: 'Test' },
      ];

      invalidLogisticians.forEach((logistician) => {
        expect(
          LogisticianAdapter.isValidCatalogueLogistician(logistician),
        ).toBe(false);
      });
    });
  });
});
