/**
 * Preservation Property Tests for Bug 1: Stock-In and Global Metrics Unchanged
 * 
 * **Validates: Requirements 5.1, 5.2, 5.3, 5.4**
 * 
 * These tests verify that the fix for Bug 1 does NOT break existing functionality:
 * - Stock-in approvals correctly increase Total Available MT
 * - getSummary() returns correct global totals across all warehouses
 * - getExpiry() aggregates batch quantities across warehouses
 * - getInventory() displays per-batch records correctly
 * 
 * IMPORTANT: These tests are run on UNFIXED code to observe baseline behavior.
 * They should PASS on unfixed code, confirming the behavior we want to preserve.
 * After implementing the fix, these tests should still PASS (no regressions).
 * 
 * Property-Based Testing Approach:
 * - Generate many test cases automatically for stronger guarantees
 * - Test across various input ranges to catch edge cases
 * - Verify behavior is consistent for all non-buggy inputs
 */

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { Test, TestingModule } from '@nestjs/testing';
import { getModelToken } from '@nestjs/mongoose';
import { Model, Types } from 'mongoose';
import { StockTransactionsService } from './stock-transactions.service';
import { InventoryService } from './inventory.service';
import { NotificationsService } from './notifications.service';
import { StockTransaction } from './schemas/stock-transaction.schema';
import { Warehouse } from './schemas/warehouse.schema';
import { Item } from './schemas/item.schema';
import { Batch } from './schemas/batch.schema';
import { InventoryBalance } from './schemas/inventory-balance.schema';
import { StockMovementSheet } from './schemas/stock-movement-sheet.schema';
import { User } from './schemas/user.schema';
import { InventoryTransaction } from './schemas/inventory-transaction.schema';

describe('Bug 1 Preservation: Stock-In and Global Metrics Unchanged', () => {
  let stockTxService: StockTransactionsService;
  let inventoryService: InventoryService;
  let txModel: Model<any>;
  let warehouseModel: Model<any>;
  let itemModel: Model<any>;
  let batchModel: Model<any>;
  let balanceModel: Model<any>;
  let sheetModel: Model<any>;
  let userModel: Model<any>;
  let inventoryTxModel: Model<any>;
  let notificationsService: NotificationsService;

  beforeEach(async () => {
    // Create mock models
    const mockTxModel = {
      create: vi.fn(),
      findById: vi.fn(),
      find: vi.fn(),
      countDocuments: vi.fn(),
    };

    const mockWarehouseModel = {
      findById: vi.fn(),
      find: vi.fn(),
    };

    const mockItemModel = {
      findById: vi.fn(),
      find: vi.fn(),
    };

    const mockBatchModel = {
      findById: vi.fn(),
      findOne: vi.fn(),
      create: vi.fn(),
      find: vi.fn(),
    };

    const mockBalanceModel = {
      findOne: vi.fn(),
      create: vi.fn(),
      find: vi.fn(),
    };

    const mockSheetModel = {
      find: vi.fn(),
    };

    const mockUserModel = {
      find: vi.fn(),
    };

    const mockInventoryTxModel = {
      aggregate: vi.fn(),
    };

    const mockNotificationsService = {
      notifyManagers: vi.fn(),
      notifyUser: vi.fn(),
    };

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        StockTransactionsService,
        InventoryService,
        {
          provide: getModelToken(StockTransaction.name),
          useValue: mockTxModel,
        },
        {
          provide: getModelToken(Warehouse.name),
          useValue: mockWarehouseModel,
        },
        {
          provide: getModelToken(Item.name),
          useValue: mockItemModel,
        },
        {
          provide: getModelToken(Batch.name),
          useValue: mockBatchModel,
        },
        {
          provide: getModelToken(InventoryBalance.name),
          useValue: mockBalanceModel,
        },
        {
          provide: getModelToken(StockMovementSheet.name),
          useValue: mockSheetModel,
        },
        {
          provide: getModelToken(User.name),
          useValue: mockUserModel,
        },
        {
          provide: getModelToken(InventoryTransaction.name),
          useValue: mockInventoryTxModel,
        },
        {
          provide: NotificationsService,
          useValue: mockNotificationsService,
        },
      ],
    }).compile();

    stockTxService = module.get<StockTransactionsService>(StockTransactionsService);
    inventoryService = module.get<InventoryService>(InventoryService);
    txModel = module.get<Model<any>>(getModelToken(StockTransaction.name));
    warehouseModel = module.get<Model<any>>(getModelToken(Warehouse.name));
    itemModel = module.get<Model<any>>(getModelToken(Item.name));
    batchModel = module.get<Model<any>>(getModelToken(Batch.name));
    balanceModel = module.get<Model<any>>(getModelToken(InventoryBalance.name));
    sheetModel = module.get<Model<any>>(getModelToken(StockMovementSheet.name));
    userModel = module.get<Model<any>>(getModelToken(User.name));
    inventoryTxModel = module.get<Model<any>>(getModelToken(InventoryTransaction.name));
    notificationsService = module.get<NotificationsService>(NotificationsService);
  });

  afterEach(() => {
    vi.clearAllMocks();
  });

  /**
   * Property 2.1: Stock-In Approvals Increase Total Available MT
   * 
   * **Validates: Requirement 5.1**
   * 
   * For all stock-in transactions, Total Available MT increases by the stocked-in quantity.
   * This is the baseline behavior that must be preserved after fixing Bug 1.
   * 
   * Property-based approach: Test with various quantities (100 MT to 5000 MT)
   */
  describe('Property 2.1: Stock-In Approvals Increase Total Available MT', () => {
    const testQuantities = [100, 500, 1000, 2500, 5000];

    testQuantities.forEach((quantityMt) => {
      it(`should increase Total Available MT by ${quantityMt} MT when stock-in is approved`, async () => {
        // Setup: Initial state
        const mockWarehouseId = new Types.ObjectId();
        const mockItemId = new Types.ObjectId();
        const mockBatchId = new Types.ObjectId();
        const mockTransactionId = new Types.ObjectId();

        const initialBalance = {
          _id: new Types.ObjectId(),
          warehouseId: mockWarehouseId,
          itemId: mockItemId,
          batchId: mockBatchId,
          currentQuantityMt: 10000, // Initial available MT
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
          save: vi.fn().mockResolvedValue(undefined),
        };

        // Mock balance query
        (balanceModel.findOne as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue(initialBalance),
        });

        (balanceModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue([initialBalance]),
          }),
        });

        // Mock batch
        const mockBatch = {
          _id: mockBatchId,
          warehouseId: mockWarehouseId,
          itemId: mockItemId,
          batchNumber: 'BATCH-STOCKIN',
          expiryDate: '2025-12-31',
          stockedOut: false,
          save: vi.fn().mockResolvedValue(undefined),
        };

        (batchModel.findById as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue(mockBatch),
        });

        (sheetModel.find as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue([]),
        });

        // Mock stock-in transaction
        const mockTransaction = {
          _id: mockTransactionId,
          type: 'inbound', // Stock-in (NOT outbound, so not Bug Condition 1)
          warehouseId: mockWarehouseId,
          itemId: mockItemId,
          batchId: mockBatchId,
          quantityMt: quantityMt,
          transactionDate: '2024-01-15',
          approvalStatus: 'pending_approval',
          submittedBy: 'user1',
          createdAt: new Date().toISOString(),
          save: vi.fn().mockResolvedValue(undefined),
          toObject: vi.fn().mockReturnThis(),
        };

        (txModel.findById as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue(mockTransaction),
        });

        (userModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue([]),
          }),
        });

        // Calculate initial Total Available MT and Total Empty MT
        const totalAvailableBefore = 10000;
        const totalEmptyBefore = 26000 - totalAvailableBefore; // 16,000 MT

        // Act: Approve the stock-in transaction
        await stockTxService.approve(mockTransactionId.toString(), 'manager1');

        // Assert: Verify Total Available MT increased by quantityMt
        const expectedTotalAvailableAfter = totalAvailableBefore + quantityMt;
        expect(initialBalance.currentQuantityMt).toBe(expectedTotalAvailableAfter);

        // Verify Total Empty MT decreased by quantityMt
        const actualTotalEmptyAfter = 26000 - initialBalance.currentQuantityMt;
        const expectedTotalEmptyAfter = totalEmptyBefore - quantityMt;
        expect(actualTotalEmptyAfter).toBe(expectedTotalEmptyAfter);

        // Verify the preservation property:
        // For stock-in (NOT Bug Condition 1), Total Available MT increases correctly
        expect(initialBalance.currentQuantityMt).toBe(totalAvailableBefore + quantityMt);
        expect(actualTotalEmptyAfter).toBe(26000 - initialBalance.currentQuantityMt);

        // Verify transaction was marked as approved
        expect(mockTransaction.approvalStatus).toBe('approved');
        expect(mockTransaction.save).toHaveBeenCalled();
      });
    });
  });

  /**
   * Property 2.2: getSummary() Returns Correct Global Totals
   * 
   * **Validates: Requirement 5.2**
   * 
   * For all inventory summary queries, global metrics display correctly.
   * getSummary() should calculate Total Available MT and Total Empty MT correctly
   * based on the sum of all inventory_balance records.
   * 
   * Property-based approach: Test with various balance configurations
   */
  describe('Property 2.2: getSummary() Returns Correct Global Totals', () => {
    const testConfigurations = [
      { balances: [5000, 10000, 6000], expectedTotal: 21000, expectedEmpty: 5000 },
      { balances: [3000, 2000, 1000], expectedTotal: 6000, expectedEmpty: 20000 },
      { balances: [15000, 8000, 3000], expectedTotal: 26000, expectedEmpty: 0 },
      { balances: [100, 200, 300], expectedTotal: 600, expectedEmpty: 25400 },
      { balances: [0, 0, 0], expectedTotal: 0, expectedEmpty: 26000 },
    ];

    testConfigurations.forEach(({ balances, expectedTotal, expectedEmpty }, index) => {
      it(`should calculate correct global totals for configuration ${index + 1}`, async () => {
        // Setup: Create multiple balance records
        const mockBalances = balances.map((qty, i) => ({
          _id: new Types.ObjectId(),
          warehouseId: new Types.ObjectId(),
          itemId: new Types.ObjectId(),
          batchId: new Types.ObjectId(),
          currentQuantityMt: qty,
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
        }));

        (balanceModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue(mockBalances),
          }),
        });

        (sheetModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue([]),
          }),
        });

        (txModel.countDocuments as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue(0),
        });

        // Act: Get summary
        const summary = await inventoryService.getSummary();

        // Assert: Verify global totals are correct
        expect(summary.totalAvailableMt).toBe(expectedTotal);
        expect(summary.totalEmptyMt).toBe(expectedEmpty);
        expect(summary.thresholdTargetMt).toBe(26000);

        // Verify the preservation property:
        // getSummary() calculates totals correctly across all warehouses
        expect(summary.totalAvailableMt + summary.totalEmptyMt).toBe(26000);
        expect(summary.totalEmptyMt).toBe(Math.max(0, 26000 - summary.totalAvailableMt));
      });
    });
  });

  /**
   * Property 2.3: getExpiry() Aggregates Batch Quantities Across Warehouses
   * 
   * **Validates: Requirement 5.3**
   * 
   * For all expiry queries, batch quantities aggregate across warehouses.
   * getExpiry() should show the total MT for each batch across all warehouses,
   * not warehouse-specific quantities.
   * 
   * Property-based approach: Test with batches distributed across multiple warehouses
   */
  describe('Property 2.3: getExpiry() Aggregates Batch Quantities Across Warehouses', () => {
    it('should aggregate batch quantities across all warehouses', async () => {
      // Setup: Create approved sheets with batches in multiple warehouses
      const mockWarehouse1 = new Types.ObjectId();
      const mockWarehouse2 = new Types.ObjectId();
      const mockWarehouse3 = new Types.ObjectId();

      (warehouseModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue([
            { _id: mockWarehouse1, name: 'Warehouse A' },
            { _id: mockWarehouse2, name: 'Warehouse B' },
            { _id: mockWarehouse3, name: 'Warehouse C' },
          ]),
        }),
      });

      const approvedSheets = [
        {
          _id: new Types.ObjectId(),
          approvalStatus: 'approved',
          lineItems: [
            {
              itemCode: 'RICE-25',
              itemName: 'Rice 25kg',
              batchNumber: 'BATCH-001',
              expiryDate: '2024-06-30',
              totalMt: 1900,
              warehouseBags: {
                [mockWarehouse1.toString()]: 76, // 1,900 MT
              },
            },
          ],
        },
        {
          _id: new Types.ObjectId(),
          approvalStatus: 'approved',
          lineItems: [
            {
              itemCode: 'RICE-25',
              itemName: 'Rice 25kg',
              batchNumber: 'BATCH-001',
              expiryDate: '2024-06-30',
              totalMt: 8100,
              warehouseBags: {
                [mockWarehouse2.toString()]: 324, // 8,100 MT
              },
            },
          ],
        },
        {
          _id: new Types.ObjectId(),
          approvalStatus: 'approved',
          lineItems: [
            {
              itemCode: 'RICE-25',
              itemName: 'Rice 25kg',
              batchNumber: 'BATCH-001',
              expiryDate: '2024-06-30',
              totalMt: 8000,
              warehouseBags: {
                [mockWarehouse3.toString()]: 320, // 8,000 MT
              },
            },
          ],
        },
      ];

      (sheetModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue(approvedSheets),
        }),
      });

      (batchModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue([]),
        }),
      });

      // Act: Get expiry data
      const expiryData = await inventoryService.getExpiry(6);

      // Assert: Verify batch quantities are aggregated across warehouses
      const batch001 = expiryData.find((row) => row.batchNumber === 'BATCH-001');
      expect(batch001).toBeDefined();
      
      if (batch001) {
        // Total MT should be the sum across all warehouses: 1,900 + 8,100 + 8,000 = 18,000
        expect(batch001.availableMt).toBe(18000);
        
        // Warehouse field should list all warehouses
        expect(batch001.warehouse).toContain('Warehouse A');
        expect(batch001.warehouse).toContain('Warehouse B');
        expect(batch001.warehouse).toContain('Warehouse C');

        // Verify the preservation property:
        // getExpiry() aggregates quantities across all warehouses, not warehouse-specific
        expect(batch001.availableMt).toBeGreaterThan(1900); // More than any single warehouse
        expect(batch001.availableMt).toBe(1900 + 8100 + 8000);
      }
    });

    it('should aggregate multiple batches across warehouses', async () => {
      // Setup: Multiple batches in multiple warehouses
      const mockWarehouse1 = new Types.ObjectId();
      const mockWarehouse2 = new Types.ObjectId();

      (warehouseModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue([
            { _id: mockWarehouse1, name: 'Warehouse X' },
            { _id: mockWarehouse2, name: 'Warehouse Y' },
          ]),
        }),
      });

      const approvedSheets = [
        {
          _id: new Types.ObjectId(),
          approvalStatus: 'approved',
          lineItems: [
            {
              itemCode: 'WHEAT-50',
              itemName: 'Wheat 50kg',
              batchNumber: 'BATCH-A',
              expiryDate: '2024-05-15',
              totalMt: 500,
              warehouseBags: {
                [mockWarehouse1.toString()]: 10,
              },
            },
            {
              itemCode: 'WHEAT-50',
              itemName: 'Wheat 50kg',
              batchNumber: 'BATCH-B',
              expiryDate: '2024-07-20',
              totalMt: 1000,
              warehouseBags: {
                [mockWarehouse1.toString()]: 20,
              },
            },
          ],
        },
        {
          _id: new Types.ObjectId(),
          approvalStatus: 'approved',
          lineItems: [
            {
              itemCode: 'WHEAT-50',
              itemName: 'Wheat 50kg',
              batchNumber: 'BATCH-A',
              expiryDate: '2024-05-15',
              totalMt: 1500,
              warehouseBags: {
                [mockWarehouse2.toString()]: 30,
              },
            },
          ],
        },
      ];

      (sheetModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue(approvedSheets),
        }),
      });

      (batchModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue([]),
        }),
      });

      // Act: Get expiry data
      const expiryData = await inventoryService.getExpiry(6);

      // Assert: Verify each batch aggregates across warehouses
      const batchA = expiryData.find((row) => row.batchNumber === 'BATCH-A');
      const batchB = expiryData.find((row) => row.batchNumber === 'BATCH-B');

      expect(batchA).toBeDefined();
      expect(batchB).toBeDefined();

      if (batchA) {
        // BATCH-A: 500 (Warehouse X) + 1,500 (Warehouse Y) = 2,000 MT
        expect(batchA.availableMt).toBe(2000);
        expect(batchA.warehouse).toContain('Warehouse X');
        expect(batchA.warehouse).toContain('Warehouse Y');
      }

      if (batchB) {
        // BATCH-B: 1,000 MT (only in Warehouse X)
        expect(batchB.availableMt).toBe(1000);
        expect(batchB.warehouse).toContain('Warehouse X');
      }
    });
  });

  /**
   * Property 2.4: getInventory() Displays Per-Batch Records Correctly
   * 
   * **Validates: Requirement 5.4**
   * 
   * For all inventory table queries, per-batch records display correctly.
   * getInventory() should show each batch's current quantity from inventory_balance.
   * 
   * Property-based approach: Test with various batch configurations
   */
  describe('Property 2.4: getInventory() Displays Per-Batch Records Correctly', () => {
    it('should display per-batch inventory records correctly', async () => {
      // Setup: Create multiple balance records for different batches
      const mockWarehouse = new Types.ObjectId();
      const mockItem = new Types.ObjectId();
      const mockBatch1 = new Types.ObjectId();
      const mockBatch2 = new Types.ObjectId();
      const mockBatch3 = new Types.ObjectId();

      const mockBalances = [
        {
          _id: new Types.ObjectId(),
          warehouseId: mockWarehouse,
          itemId: mockItem,
          batchId: mockBatch1,
          currentQuantityMt: 5000,
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
        },
        {
          _id: new Types.ObjectId(),
          warehouseId: mockWarehouse,
          itemId: mockItem,
          batchId: mockBatch2,
          currentQuantityMt: 10000,
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
        },
        {
          _id: new Types.ObjectId(),
          warehouseId: mockWarehouse,
          itemId: mockItem,
          batchId: mockBatch3,
          currentQuantityMt: 3000,
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
        },
      ];

      (balanceModel.find as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue(mockBalances),
        }),
      });

      (warehouseModel.findById as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue({ _id: mockWarehouse, name: 'Main Warehouse' }),
        }),
      });

      (itemModel.findById as vi.Mock).mockReturnValue({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue({ _id: mockItem, itemCode: 'RICE-25', itemName: 'Rice 25kg' }),
        }),
      });

      (batchModel.findById as vi.Mock).mockImplementation((id) => ({
        lean: vi.fn().mockReturnValue({
          exec: vi.fn().mockResolvedValue({
            _id: id,
            batchNumber: id.toString() === mockBatch1.toString() ? 'BATCH-001' :
                         id.toString() === mockBatch2.toString() ? 'BATCH-002' : 'BATCH-003',
            expiryDate: '2025-12-31',
          }),
        }),
      }));

      (inventoryTxModel.aggregate as vi.Mock).mockResolvedValue([{ _id: null, total: 0 }]);

      // Act: Get inventory
      const inventory = await inventoryService.getInventory();

      // Assert: Verify per-batch records are displayed correctly
      expect(inventory).toHaveLength(3);

      const batch1Record = inventory.find((rec) => rec.batchNumber === 'BATCH-001');
      const batch2Record = inventory.find((rec) => rec.batchNumber === 'BATCH-002');
      const batch3Record = inventory.find((rec) => rec.batchNumber === 'BATCH-003');

      expect(batch1Record).toBeDefined();
      expect(batch2Record).toBeDefined();
      expect(batch3Record).toBeDefined();

      if (batch1Record) {
        expect(batch1Record.availableMt).toBe(5000);
        expect(batch1Record.warehouse).toBe('Main Warehouse');
        expect(batch1Record.itemCode).toBe('RICE-25');
      }

      if (batch2Record) {
        expect(batch2Record.availableMt).toBe(10000);
      }

      if (batch3Record) {
        expect(batch3Record.availableMt).toBe(3000);
      }

      // Verify the preservation property:
      // getInventory() displays per-batch records with correct quantities
      inventory.forEach((rec) => {
        expect(rec.availableMt).toBeGreaterThanOrEqual(0);
        expect(rec.thresholdTargetMt).toBe(26000);
        expect(rec.thresholdProgressPct).toBeGreaterThanOrEqual(0);
        expect(rec.thresholdProgressPct).toBeLessThanOrEqual(100);
      });
    });
  });

  /**
   * Property 2.5: No Total Empty MT Calculation When No Stock-Out Approval
   * 
   * **Validates: Requirement 5.2**
   * 
   * When no stock transactions are pending or approved, Total Empty MT should be
   * calculated correctly as (26,000 MT - current Total Available MT).
   * 
   * This verifies that the baseline calculation works correctly without any transactions.
   */
  describe('Property 2.5: Total Empty MT Calculation Without Transactions', () => {
    const testScenarios = [
      { totalAvailable: 21000, expectedEmpty: 5000 },
      { totalAvailable: 10000, expectedEmpty: 16000 },
      { totalAvailable: 26000, expectedEmpty: 0 },
      { totalAvailable: 0, expectedEmpty: 26000 },
      { totalAvailable: 15500, expectedEmpty: 10500 },
    ];

    testScenarios.forEach(({ totalAvailable, expectedEmpty }) => {
      it(`should calculate Total Empty MT as ${expectedEmpty} when Total Available MT is ${totalAvailable}`, async () => {
        // Setup: Create balance with specific total available MT
        const mockBalance = {
          _id: new Types.ObjectId(),
          warehouseId: new Types.ObjectId(),
          itemId: new Types.ObjectId(),
          batchId: new Types.ObjectId(),
          currentQuantityMt: totalAvailable,
          thresholdTargetMt: 26000,
          lastUpdated: new Date().toISOString(),
        };

        (balanceModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue([mockBalance]),
          }),
        });

        (sheetModel.find as vi.Mock).mockReturnValue({
          lean: vi.fn().mockReturnValue({
            exec: vi.fn().mockResolvedValue([]),
          }),
        });

        (txModel.countDocuments as vi.Mock).mockReturnValue({
          exec: vi.fn().mockResolvedValue(0),
        });

        // Act: Get summary
        const summary = await inventoryService.getSummary();

        // Assert: Verify Total Empty MT is calculated correctly
        expect(summary.totalAvailableMt).toBe(totalAvailable);
        expect(summary.totalEmptyMt).toBe(expectedEmpty);

        // Verify the preservation property:
        // Total Empty MT = 26,000 - Total Available MT (when no transactions)
        expect(summary.totalEmptyMt).toBe(Math.max(0, 26000 - totalAvailable));
        expect(summary.totalAvailableMt + summary.totalEmptyMt).toBe(26000);
      });
    });
  });
});
