import { describe, it, expect } from 'vitest';
import { BranchAdapter } from './branch.adapter';
import { BranchDTO as InventoryBranchDTO } from '@generated/swagger/inventory-api';

describe('BranchAdapter', () => {
  describe('toCatalogueFormat', () => {
    it('should convert inventory branch to catalogue format', () => {
      // Arrange
      const inventoryBranch: InventoryBranchDTO = {
        id: 1,
        branchNumber: 'B001',
        name: 'Main Branch',
        isOnline: true,
      };

      // Act
      const result = BranchAdapter.toCatalogueFormat(inventoryBranch);

      // Assert
      expect(result.id).toBe(1);
      expect(result.branchNumber).toBe('B001');
      expect(result.name).toBe('Main Branch');
      expect(result.isOnline).toBe(true);
    });

    it('should throw error when branch missing id', () => {
      // Arrange
      const invalidBranch: InventoryBranchDTO = {
        // id missing
        name: 'Test Branch',
      };

      // Act & Assert
      expect(() => BranchAdapter.toCatalogueFormat(invalidBranch)).toThrow(
        'Branch missing required id',
      );
    });

    it('should preserve all branch properties', () => {
      // Arrange
      const fullBranch: InventoryBranchDTO = {
        id: 5,
        branchNumber: 'B005',
        name: 'Test Branch',
        shortName: 'Test',
        isOnline: true,
        isOrderingEnabled: true,
        isShippingEnabled: false,
        branchType: 1,
        address: {
          street: 'Test Street',
          city: 'Test City',
        },
      };

      // Act
      const result = BranchAdapter.toCatalogueFormat(fullBranch);

      // Assert
      expect(result.id).toBe(5);
      expect(result.branchNumber).toBe('B005');
      expect(result.address).toEqual({
        street: 'Test Street',
        city: 'Test City',
      });
    });

    it('should handle minimal branch with only id', () => {
      // Arrange
      const minimalBranch: InventoryBranchDTO = {
        id: 99,
      };

      // Act
      const result = BranchAdapter.toCatalogueFormat(minimalBranch);

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

  describe('isValidInventoryBranch', () => {
    it('should return true for valid inventory branch', () => {
      const validBranch: InventoryBranchDTO = {
        id: 1,
        name: 'Test',
      };

      expect(BranchAdapter.isValidInventoryBranch(validBranch)).toBe(true);
    });

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

      expect(BranchAdapter.isValidInventoryBranch(validBranch)).toBe(true);
    });

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

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

      invalidBranches.forEach((branch) => {
        expect(BranchAdapter.isValidInventoryBranch(branch)).toBe(false);
      });
    });
  });

  describe('isValidCatalogueBranch', () => {
    it('should return true for valid catalogue branch', () => {
      const validBranch = {
        id: 1,
        additionalProp: 'value',
      };

      expect(BranchAdapter.isValidCatalogueBranch(validBranch)).toBe(true);
    });

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

      expect(BranchAdapter.isValidCatalogueBranch(validBranch)).toBe(true);
    });

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

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

      invalidBranches.forEach((branch) => {
        expect(BranchAdapter.isValidCatalogueBranch(branch)).toBe(false);
      });
    });
  });
});
