import { BatchResponseArgs } from './batch-response-args';
import { ReturnValue } from './return-value';

describe('BatchResponseArgs', () => {
  describe('interface structure', () => {
    it('should support all properties', () => {
      // Arrange
      const testData: BatchResponseArgs<string> = {
        alreadyProcessed: [
          { error: false, result: 'processed1' },
          { error: false, result: 'processed2' },
        ],
        ambiguous: ['ambiguous1', 'ambiguous2'],
        completed: true,
        duplicates: [
          { key: 'key1', value: 1 },
          { key: 'key2', value: 2 },
        ],
        error: false,
        failed: [
          { error: true, message: 'Failed', result: 'failed1' },
        ],
        invalidProperties: { field1: 'Invalid value' },
        message: 'Success',
        requestId: 12345,
        successful: [
          { key: 'key1', value: 'value1' },
          { key: 'key2', value: 'value2' },
        ],
        total: 10,
        unknown: [
          { error: false, result: 'unknown1' },
        ],
      };

      // Assert
      expect(testData.alreadyProcessed).toHaveLength(2);
      expect(testData.ambiguous).toHaveLength(2);
      expect(testData.completed).toBe(true);
      expect(testData.duplicates).toHaveLength(2);
      expect(testData.error).toBe(false);
      expect(testData.failed).toHaveLength(1);
      expect(testData.invalidProperties).toEqual({ field1: 'Invalid value' });
      expect(testData.message).toBe('Success');
      expect(testData.requestId).toBe(12345);
      expect(testData.successful).toHaveLength(2);
      expect(testData.total).toBe(10);
      expect(testData.unknown).toHaveLength(1);
    });

    it('should support required properties only', () => {
      // Arrange
      const testData: BatchResponseArgs<number> = {
        completed: false,
        error: true,
        total: 0,
      };

      // Assert
      expect(testData.completed).toBe(false);
      expect(testData.error).toBe(true);
      expect(testData.total).toBe(0);
      expect(testData.alreadyProcessed).toBeUndefined();
      expect(testData.ambiguous).toBeUndefined();
      expect(testData.duplicates).toBeUndefined();
      expect(testData.failed).toBeUndefined();
      expect(testData.invalidProperties).toBeUndefined();
      expect(testData.message).toBeUndefined();
      expect(testData.requestId).toBeUndefined();
      expect(testData.successful).toBeUndefined();
      expect(testData.unknown).toBeUndefined();
    });

    it('should support generic type parameter', () => {
      // Arrange
      interface TestObject {
        id: number;
        name: string;
      }

      const testData: BatchResponseArgs<TestObject> = {
        completed: true,
        error: false,
        total: 1,
        successful: [
          { key: { id: 1, name: 'test' }, value: { id: 1, name: 'test' } },
        ],
      };

      // Assert
      expect(testData.successful?.[0].key.id).toBe(1);
      expect(testData.successful?.[0].key.name).toBe('test');
      expect(testData.successful?.[0].value.id).toBe(1);
      expect(testData.successful?.[0].value.name).toBe('test');
    });

    it('should support ReturnValue arrays', () => {
      // Arrange
      const returnValue: ReturnValue<string> = {
        error: false,
        result: 'test result',
        message: 'Success',
      };

      const testData: BatchResponseArgs<string> = {
        completed: true,
        error: false,
        total: 1,
        alreadyProcessed: [returnValue],
        failed: [returnValue],
        unknown: [returnValue],
      };

      // Assert
      expect(testData.alreadyProcessed?.[0]).toEqual(returnValue);
      expect(testData.failed?.[0]).toEqual(returnValue);
      expect(testData.unknown?.[0]).toEqual(returnValue);
    });

    it('should support empty arrays', () => {
      // Arrange
      const testData: BatchResponseArgs<string> = {
        completed: true,
        error: false,
        total: 0,
        alreadyProcessed: [],
        ambiguous: [],
        duplicates: [],
        failed: [],
        successful: [],
        unknown: [],
      };

      // Assert
      expect(testData.alreadyProcessed).toHaveLength(0);
      expect(testData.ambiguous).toHaveLength(0);
      expect(testData.duplicates).toHaveLength(0);
      expect(testData.failed).toHaveLength(0);
      expect(testData.successful).toHaveLength(0);
      expect(testData.unknown).toHaveLength(0);
    });
  });
});