/**
 * Property-Based Test: Section Header Count Accuracy
 *
 * Feature: queue-collapsible-sections, Property 4: Section Header Count Accuracy
 * **Validates: Requirements 3.1, 3.2**
 *
 * For every section in the grouped output, the items array length equals the count
 * that would be displayed in the header. The sum of all section item counts equals
 * the total input array length.
 */
import fc from 'fast-check';

// Replicate the grouping logic inline (utility file not yet extracted)
function groupQueueItems(visibleItems) {
  const INVENTORY_TYPES = new Set(['CARD', 'GRANITE', 'DECOM']);
  const inventoryItems = [];
  const vendorMap = new Map();
  for (const item of visibleItems) {
    if (INVENTORY_TYPES.has(item.workflow_type)) {
      inventoryItems.push(item);
    } else {
      const vendor = item.vendor?.trim() || 'Unknown';
      if (!vendorMap.has(vendor)) vendorMap.set(vendor, []);
      vendorMap.get(vendor).push(item);
    }
  }
  const sections = [];
  if (inventoryItems.length > 0) {
    sections.push({ key: 'inventory', label: 'Inventory', type: 'inventory', items: inventoryItems });
  }
  const sortedVendors = [...vendorMap.entries()].sort((a, b) => a[0].localeCompare(b[0]));
  for (const [vendor, items] of sortedVendors) {
    sections.push({ key: `vendor:${vendor}`, label: vendor, type: 'vendor', items });
  }
  return sections;
}

// Generator for queue items with realistic workflow types and vendor names
const workflowTypeArb = fc.constantFrom('CARD', 'GRANITE', 'DECOM', 'FP', 'Archer');
const vendorArb = fc.oneof(
  fc.constantFrom('Microsoft', 'Adobe', 'Cisco', 'Oracle', 'VMware', 'Apple'),
  fc.constant(''),
  fc.constant(null),
  fc.constant(undefined)
);

const queueItemArb = fc.record({
  id: fc.uuid(),
  workflow_type: workflowTypeArb,
  vendor: vendorArb,
  hostname: fc.string({ minLength: 1, maxLength: 20 }),
  status: fc.constant('pending'),
});

const queueItemsArb = fc.array(queueItemArb, { minLength: 1, maxLength: 50 });

describe('Queue Grouping — Property 4: Section Header Count Accuracy', () => {
  it('each section items.length is a positive integer (the displayed count)', () => {
    fc.assert(
      fc.property(queueItemsArb, (items) => {
        const sections = groupQueueItems(items);

        for (const section of sections) {
          // items.length is the count that would be displayed in the header
          expect(Number.isInteger(section.items.length)).toBe(true);
          expect(section.items.length).toBeGreaterThan(0);
        }
      }),
      { numRuns: 200 }
    );
  });

  it('sum of all section item counts equals total input array length', () => {
    fc.assert(
      fc.property(queueItemsArb, (items) => {
        const sections = groupQueueItems(items);

        const totalItemsInSections = sections.reduce(
          (sum, section) => sum + section.items.length,
          0
        );

        expect(totalItemsInSections).toBe(items.length);
      }),
      { numRuns: 200 }
    );
  });
});
