import { TestBed } from '@angular/core/testing';
import { SyncImportFilterService } from './sync-import-filter.service';
import { OperationLogStoreService } from '../persistence/operation-log-store.service';
import {
  ActionType,
  Operation,
  OperationLogEntry,
  OpType,
} from '../core/operation.types';

/** Used in tests to build realistic clock sizes for pruning-related scenarios. */
const CLOCK_SIZE_10 = 10;

describe('SyncImportFilterService', () => {
  let service: SyncImportFilterService;
  let opLogStoreSpy: jasmine.SpyObj<OperationLogStoreService>;

  // Helper to create operations with UUIDv7-style IDs (lexicographically sortable by time)
  const createOp = (partial: Partial<Operation>): Operation => ({
    id: '019afd68-0000-7000-0000-000000000000', // Default UUIDv7 format
    actionType: '[Test] Action' as ActionType,
    opType: OpType.Update,
    entityType: 'TASK',
    entityId: 'entity-1',
    payload: {},
    clientId: 'client-A',
    vectorClock: { clientA: 1 },
    timestamp: Date.now(),
    schemaVersion: 1,
    ...partial,
  });

  beforeEach(() => {
    opLogStoreSpy = jasmine.createSpyObj('OperationLogStoreService', [
      'getLatestFullStateOp',
      'getLatestFullStateOpEntry',
    ]);
    // By default, no full-state ops in store
    opLogStoreSpy.getLatestFullStateOp.and.returnValue(Promise.resolve(undefined));
    opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(Promise.resolve(undefined));

    TestBed.configureTestingModule({
      providers: [
        SyncImportFilterService,
        { provide: OperationLogStoreService, useValue: opLogStoreSpy },
      ],
    });

    service = TestBed.inject(SyncImportFilterService);
  });

  describe('filterOpsInvalidatedBySyncImport', () => {
    it('should return all ops as valid when no SYNC_IMPORT is present', async () => {
      const ops: Operation[] = [
        createOp({ id: '019afd68-0001-7000-0000-000000000000', opType: OpType.Update }),
        createOp({ id: '019afd68-0002-7000-0000-000000000000', opType: OpType.Create }),
        createOp({ id: '019afd68-0003-7000-0000-000000000000', opType: OpType.Delete }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      expect(result.validOps.length).toBe(3);
      expect(result.invalidatedOps.length).toBe(0);
    });

    it('should keep SYNC_IMPORT operation itself as valid', async () => {
      const syncImportOp = createOp({
        id: '019afd68-0050-7000-0000-000000000000',
        opType: OpType.SyncImport,
        clientId: 'client-B',
      });

      const result = await service.filterOpsInvalidatedBySyncImport([syncImportOp]);

      expect(result.validOps.length).toBe(1);
      expect(result.validOps[0].opType).toBe(OpType.SyncImport);
      expect(result.invalidatedOps.length).toBe(0);
    });

    it('should filter out ops from OTHER clients created BEFORE SYNC_IMPORT', async () => {
      const ops: Operation[] = [
        // Client A's op created BEFORE the import - LESS_THAN import's clock
        createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-1',
          vectorClock: { clientA: 2 }, // LESS_THAN import's clock
        }),
        // Client B's SYNC_IMPORT with higher clock
        createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientA: 5, clientB: 3 }, // Import has knowledge of clientA up to 5
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      // SYNC_IMPORT is valid, Client A's earlier op is invalidated (LESS_THAN)
      expect(result.validOps.length).toBe(1);
      expect(result.validOps[0].opType).toBe(OpType.SyncImport);
      expect(result.invalidatedOps.length).toBe(1);
      expect(result.invalidatedOps[0].clientId).toBe('client-A');
    });

    it('should filter pre-import ops from the SAME client as SYNC_IMPORT', async () => {
      const ops: Operation[] = [
        // Client B's op created BEFORE the import - LESS_THAN import's clock
        createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          entityId: 'task-1',
          vectorClock: { clientB: 2 }, // LESS_THAN import's clock
        }),
        // Client B's SYNC_IMPORT
        createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 5 }, // Import's clock
        }),
        // Client B's ops after the import - GREATER_THAN import's clock
        createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'client-B',
          entityId: 'task-2',
          vectorClock: { clientB: 6 }, // GREATER_THAN import's clock (B saw import first)
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      // Only SYNC_IMPORT and post-import ops should be valid
      expect(result.validOps.length).toBe(2);
      expect(result.validOps.map((op) => op.id)).toContain(
        '019afd68-0050-7000-0000-000000000000',
      ); // SYNC_IMPORT
      expect(result.validOps.map((op) => op.id)).toContain(
        '019afd68-0100-7000-0000-000000000000',
      ); // Post-import

      expect(result.invalidatedOps.length).toBe(1);
      expect(result.invalidatedOps[0].id).toBe('019afd68-0001-7000-0000-000000000000'); // Pre-import
    });

    it('should preserve ops from OTHER clients created AFTER SYNC_IMPORT (by vector clock)', async () => {
      const ops: Operation[] = [
        // Client B's SYNC_IMPORT
        createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 5 }, // Import's clock
        }),
        // Client A's op created AFTER seeing the import - GREATER_THAN
        createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-1',
          vectorClock: { clientA: 1, clientB: 5 }, // A saw import (has B's clock), then created op
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      // Both should be valid - Client A's op was created after seeing the import
      expect(result.validOps.length).toBe(2);
      expect(result.invalidatedOps.length).toBe(0);
    });

    it('should handle BACKUP_IMPORT the same way as SYNC_IMPORT', async () => {
      const ops: Operation[] = [
        // Client A's op created BEFORE the backup import - LESS_THAN
        createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-1',
          vectorClock: { clientA: 2 }, // LESS_THAN import's clock
        }),
        // Client B's BACKUP_IMPORT
        createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.BackupImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientA: 5, clientB: 3 }, // Import dominates A's clock
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      expect(result.validOps.length).toBe(1);
      expect(result.validOps[0].opType).toBe(OpType.BackupImport);
      expect(result.invalidatedOps.length).toBe(1);
      expect(result.invalidatedOps[0].clientId).toBe('client-A');
    });

    it('should use the LATEST import when multiple imports exist', async () => {
      const ops: Operation[] = [
        // Client A's early op - CONCURRENT with latest import (no knowledge of imports)
        createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-1',
          vectorClock: { clientA: 1 }, // CONCURRENT with latest import
        }),
        // First SYNC_IMPORT from Client B
        createOp({
          id: '019afd68-0010-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 1 },
        }),
        // Client A's op between the two imports - still CONCURRENT with latest
        createOp({
          id: '019afd68-0020-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-2',
          vectorClock: { clientA: 2, clientB: 1 }, // Saw first import but CONCURRENT with second
        }),
        // Second SYNC_IMPORT from Client C (latest)
        createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-C',
          entityType: 'ALL',
          vectorClock: { clientB: 1, clientC: 1 }, // Latest import's clock
        }),
        // Client A's op after the latest import - GREATER_THAN (includes latest import's clock)
        createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          entityId: 'task-3',
          vectorClock: { clientA: 3, clientB: 1, clientC: 1 }, // GREATER_THAN latest import
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(ops);

      // Only imports and the op that carries clientC's import counter survive.
      expect(result.validOps.length).toBe(3); // 2 imports + post-latest Client A op
      expect(result.invalidatedOps.length).toBe(2);
    });

    it('should filter pre-import ops when SYNC_IMPORT was downloaded in a PREVIOUS sync cycle', async () => {
      // Set up the store to have a SYNC_IMPORT from a previous sync
      const existingSyncImport: Operation = {
        id: '019afd68-0050-7000-0000-000000000000',
        actionType: '[SP_ALL] Load(import) all data' as ActionType,
        opType: OpType.SyncImport,
        entityType: 'ALL',
        entityId: 'import-1',
        payload: { appDataComplete: {} },
        clientId: 'client-B',
        vectorClock: { clientB: 1 },
        timestamp: Date.now(),
        schemaVersion: 1,
      };

      // Return as an entry (remote + synced = already accepted import)
      opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
        Promise.resolve({
          seq: 1,
          op: existingSyncImport,
          source: 'remote',
          syncedAt: Date.now(),
          appliedAt: Date.now(),
        }),
      );

      // These are OLD ops from Client A, created BEFORE the import
      // They are CONCURRENT with the import (no knowledge of it)
      const oldOpsFromClientA: Operation[] = [
        {
          id: '019afd60-0001-7000-0000-000000000000',
          actionType: '[Task] Update Task' as ActionType,
          opType: OpType.Update,
          entityType: 'TASK',
          entityId: 'task-1',
          payload: { title: 'Old title' },
          clientId: 'client-A',
          vectorClock: { clientA: 5 }, // CONCURRENT - no knowledge of import
          timestamp: Date.now(),
          schemaVersion: 1,
        },
        {
          id: '019afd60-0002-7000-0000-000000000000',
          actionType: '[Task] Update Task' as ActionType,
          opType: OpType.Update,
          entityType: 'TASK',
          entityId: 'task-2',
          payload: { title: 'Another old title' },
          clientId: 'client-A',
          vectorClock: { clientA: 6 }, // CONCURRENT - no knowledge of import
          timestamp: Date.now(),
          schemaVersion: 1,
        },
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(oldOpsFromClientA);

      // Client A is unknown to the import and has no import-client counter.
      expect(result.validOps.length).toBe(0);
      expect(result.invalidatedOps.length).toBe(2);
      expect(opLogStoreSpy.getLatestFullStateOpEntry).toHaveBeenCalled();
    });

    it('should filter #7549 straggler ops from clients unknown to a stored synced import', async () => {
      const storedSyncedImport = createOp({
        id: '019dea96-94e3-7f82-9f0e-b78d7576a667',
        opType: OpType.SyncImport,
        clientId: 'B_kc2U',
        entityType: 'ALL',
        entityId: 'import-1',
        vectorClock: { ['B_kc2U']: 42 },
      });

      opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
        Promise.resolve({
          seq: 1,
          op: storedSyncedImport,
          source: 'local',
          syncedAt: Date.now(),
          appliedAt: Date.now(),
        }),
      );

      const remoteStragglers: Operation[] = [
        createOp({
          id: '019e03fa-9438-7d3f-9f7f-cd2e2010f230',
          opType: OpType.Update,
          clientId: 'A_jfjc',
          entityType: 'TASK',
          entityId: 'task-repeat-instance',
          vectorClock: { ['A_jfjc']: 240 },
        }),
        createOp({
          id: '019e03ba-433b-73f7-ad2e-577913108d4f',
          opType: OpType.Update,
          clientId: 'B_z7PQ',
          entityType: 'TASK_REPEAT_CFG',
          entityId: 'repeat-cfg',
          vectorClock: { ['B_z7PQ']: 12 },
        }),
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(remoteStragglers);

      expect(result.isLocalUnsyncedImport).toBe(false);
      expect(result.validOps.length).toBe(0);
      expect(result.invalidatedOps.map((op) => op.clientId)).toEqual(
        jasmine.arrayContaining(['A_jfjc', 'B_z7PQ']),
      );
    });

    it('should keep post-import ops when SYNC_IMPORT was downloaded in a PREVIOUS sync cycle', async () => {
      const existingSyncImport: Operation = {
        id: '019afd68-0050-7000-0000-000000000000',
        actionType: '[SP_ALL] Load(import) all data' as ActionType,
        opType: OpType.SyncImport,
        entityType: 'ALL',
        entityId: 'import-1',
        payload: { appDataComplete: {} },
        clientId: 'client-B',
        vectorClock: { clientB: 1 },
        timestamp: Date.now(),
        schemaVersion: 1,
      };

      // Return as an entry (remote + synced = already accepted import)
      opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
        Promise.resolve({
          seq: 1,
          op: existingSyncImport,
          source: 'remote',
          syncedAt: Date.now(),
          appliedAt: Date.now(),
        }),
      );

      // These ops are created AFTER the import - client A saw the import (includes clientB: 1)
      const newOpsFromClientA: Operation[] = [
        {
          id: '019afd70-0001-7000-0000-000000000000',
          actionType: '[Task] Update Task' as ActionType,
          opType: OpType.Update,
          entityType: 'TASK',
          entityId: 'task-1',
          payload: { title: 'New title' },
          clientId: 'client-A',
          vectorClock: { clientB: 1, clientA: 7 }, // GREATER_THAN import
          timestamp: Date.now(),
          schemaVersion: 1,
        },
      ];

      const result = await service.filterOpsInvalidatedBySyncImport(newOpsFromClientA);

      // Op should be valid because it has knowledge of the import
      expect(result.validOps.length).toBe(1);
      expect(result.invalidatedOps.length).toBe(0);
    });

    describe('vector clock based filtering', () => {
      it('should FILTER CONCURRENT ops from unknown client without import knowledge', async () => {
        const ops: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Offline change' },
            clientId: 'client-B',
            vectorClock: { clientA: 2, clientB: 3 }, // CONCURRENT with import
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[SP_ALL] Load(import) all data' as ActionType,
            opType: OpType.SyncImport,
            entityType: 'ALL',
            entityId: 'import-1',
            payload: { appDataComplete: {} },
            clientId: 'client-A',
            vectorClock: { clientA: 5 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        // Client B has a stale clientA counter and no causal knowledge of the import.
        expect(result.validOps.length).toBe(1); // SYNC_IMPORT only
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should filter LESS_THAN ops (dominated by import)', async () => {
        const ops: Operation[] = [
          {
            id: '019afd60-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Old change' },
            clientId: 'client-A',
            vectorClock: { clientA: 2 }, // LESS_THAN import's clock
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[SP_ALL] Load(import) all data' as ActionType,
            opType: OpType.SyncImport,
            entityType: 'ALL',
            entityId: 'import-1',
            payload: { appDataComplete: {} },
            clientId: 'client-B',
            vectorClock: { clientA: 5, clientB: 3 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        expect(result.validOps.length).toBe(1);
        expect(result.validOps[0].opType).toBe(OpType.SyncImport);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should keep GREATER_THAN ops (created after seeing import)', async () => {
        const ops: Operation[] = [
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[SP_ALL] Load(import) all data' as ActionType,
            opType: OpType.SyncImport,
            entityType: 'ALL',
            entityId: 'import-1',
            payload: { appDataComplete: {} },
            clientId: 'client-A',
            vectorClock: { clientA: 5 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Post-import change' },
            clientId: 'client-B',
            vectorClock: { clientA: 5, clientB: 1 }, // GREATER_THAN
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should keep EQUAL ops (same causal history as import)', async () => {
        const ops: Operation[] = [
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[SP_ALL] Load(import) all data' as ActionType,
            opType: OpType.SyncImport,
            entityType: 'ALL',
            entityId: 'import-1',
            payload: { appDataComplete: {} },
            clientId: 'client-A',
            vectorClock: { clientA: 5, clientB: 3 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd68-0051-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Same-clock change' },
            clientId: 'client-B',
            vectorClock: { clientA: 5, clientB: 3 }, // EQUAL to import
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should filter ops even if client clock was ahead (clock drift regression)', async () => {
        const ops: Operation[] = [
          {
            // UUIDv7 timestamp is AFTER the import (client clock was ahead!)
            id: '019afd80-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Clock-drift change' },
            clientId: 'client-B',
            vectorClock: { clientA: 2, clientB: 3 }, // But vector clock shows no knowledge of import!
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[SP_ALL] Load(import) all data' as ActionType,
            opType: OpType.SyncImport,
            entityType: 'ALL',
            entityId: 'import-1',
            payload: { appDataComplete: {} },
            clientId: 'client-A',
            vectorClock: { clientA: 5 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        // UUID time is ignored; vector clock lacks knowledge of the import.
        expect(result.validOps.length).toBe(1); // SYNC_IMPORT only
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should handle REPAIR operations the same as SYNC_IMPORT', async () => {
        const ops: Operation[] = [
          {
            id: '019afd60-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'Old change' },
            clientId: 'client-B',
            vectorClock: { clientA: 2, clientB: 3 }, // CONCURRENT with repair
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd68-0050-7000-0000-000000000000',
            actionType: '[OpLog] Repair' as ActionType,
            opType: OpType.Repair,
            entityType: 'ALL',
            entityId: 'repair-1',
            payload: { appDataComplete: {} },
            clientId: 'client-A',
            vectorClock: { clientA: 5 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        // Client B has a stale clientA counter and no causal knowledge of the repair.
        expect(result.validOps.length).toBe(1); // REPAIR only
        expect(result.invalidatedOps.length).toBe(1);
      });
    });

    describe('vector clock merge fix verification', () => {
      /**
       * These tests verify the bug fix for the vector clock merge issue.
       *
       * THE BUG:
       * When a client receives and applies a SYNC_IMPORT, the local vector clock
       * was NOT being updated to include the import's clock entries. This caused
       * subsequent local operations to have vector clocks that were CONCURRENT
       * with the import instead of GREATER_THAN, leading to incorrect filtering.
       *
       * THE FIX:
       * After applying remote operations (including SYNC_IMPORT), we now call
       * `mergeRemoteOpClocks()` to merge the remote ops' clocks into the local clock.
       * This ensures subsequent local ops will have clocks that dominate the import.
       */

      it('should correctly identify ops created AFTER clock merge as valid', async () => {
        // Scenario:
        // 1. Client A creates SYNC_IMPORT with clock {clientA: 1}
        // 2. Client B receives it, merges clocks → local clock becomes {clientA: 1, clientB: 5}
        // 3. Client B creates new op with clock {clientA: 1, clientB: 6} (GREATER_THAN import)
        // 4. This op should pass the filter

        const existingSyncImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'client-A',
          vectorClock: { clientA: 1 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        // Return as an entry (remote + synced = already accepted import)
        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: existingSyncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Op created AFTER merging import's clock - includes clientA: 1
        const postMergeOp: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'New task after merge' },
            clientId: 'client-B',
            vectorClock: { clientA: 1, clientB: 6 }, // Includes import's clock entry
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(postMergeOp);

        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should filter ops from unknown clients without import knowledge (clean slate semantics)', async () => {
        // Clean Slate Semantics: ops from clients unknown to the SYNC_IMPORT are FILTERED.
        // Rationale: the import is an explicit user action to restore ALL clients to
        // a specific state. Concurrent work is intentionally discarded.
        //
        // Scenario:
        // 1. Client A creates SYNC_IMPORT with clock {clientA: 1}
        // 2. Client B (unknown to A) creates op with clock {clientB: 6}
        // 3. Client B's op should be FILTERED (no knowledge of import)

        const existingSyncImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'client-A',
          vectorClock: { clientA: 1 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        // Return as an entry (remote + synced = already accepted import)
        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: existingSyncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Op from a client that was UNKNOWN to the import
        const unknownClientOp: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'New task from unknown client' },
            clientId: 'client-B',
            vectorClock: { clientB: 6 }, // Client B is not in import's clock
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(unknownClientOp);

        // Client B is unknown to the import and has no import-client counter.
        // Clean slate semantics filter it to prevent stale clients from resurrecting state.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should handle multiple clients scenario correctly', async () => {
        // Scenario with 3 clients:
        // 1. Client A creates SYNC_IMPORT with clock {clientA: 1}
        // 2. Client B merges → clock becomes {clientA: 1, clientB: 5}
        // 3. Client C merges → clock becomes {clientA: 1, clientC: 3}
        // 4. Both B and C create ops, both should pass filter

        const existingSyncImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'client-A',
          vectorClock: { clientA: 1 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        // Return as an entry (remote + synced = already accepted import)
        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: existingSyncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const opsFromMultipleClients: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-1',
            payload: { title: 'From client B' },
            clientId: 'client-B',
            vectorClock: { clientA: 1, clientB: 6 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
          {
            id: '019afd70-0002-7000-0000-000000000000',
            actionType: '[Task] Update Task' as ActionType,
            opType: OpType.Update,
            entityType: 'TASK',
            entityId: 'task-2',
            payload: { title: 'From client C' },
            clientId: 'client-C',
            vectorClock: { clientA: 1, clientC: 4 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result =
          await service.filterOpsInvalidatedBySyncImport(opsFromMultipleClients);

        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });
    });

    describe('BUG FIX: Vector clock pruning preserves import client', () => {
      /**
       * This test documents the bug that occurs when vector clock pruning removes
       * the SYNC_IMPORT client's entry, causing new ops to appear CONCURRENT with
       * the import instead of GREATER_THAN.
       *
       * THE BUG SCENARIO:
       * 1. Client A creates SYNC_IMPORT with clock {clientA: 1}
       * 2. Client B receives it, merges clocks → {clientA: 1, clientB: 9746, ...}
       * 3. B has 91 clients in clock, pruning triggers (limit was 10, now 20)
       * 4. clientA has counter=1 (lowest) → PRUNED by limitVectorClockSize()
       * 5. New task on B has clock {clientB: 9747} - MISSING clientA!
       * 6. Comparison: {clientA: 0 (missing)} vs {clientA: 1} → CONCURRENT
       * 7. Op is incorrectly filtered as "invalidated by import"
       *
       * THE FIX:
       * - SYNC_IMPORT now REPLACES the vector clock (not merges), so the post-import
       *   clock only contains the import's entries + the local client's increment
       * - This prevents clock bloat and ensures comparison yields GREATER_THAN
       */

      it('should correctly filter ops when SYNC_IMPORT client was NOT pruned (fix applied)', async () => {
        // This test shows CORRECT behavior when the fix is applied:
        // The import client's entry is preserved in the op's vector clock

        const existingSyncImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'clientA',
          vectorClock: { clientA: 1 }, // Import's clock
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: existingSyncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // With the fix: op's clock includes clientA (protected during pruning)
        const opWithPreservedClock: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task Shared] addTask' as ActionType,
            opType: OpType.Create,
            entityType: 'TASK',
            entityId: 'new-task-1',
            payload: { title: 'My new task' },
            clientId: 'clientB',
            // Clock includes clientA because it was protected during pruning
            vectorClock: { clientA: 1, clientB: 9747 },
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result =
          await service.filterOpsInvalidatedBySyncImport(opWithPreservedClock);

        // With preserved clock: op is GREATER_THAN import → kept
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should FILTER ops from unknown client when import entry was pruned from op clock', async () => {
        const existingSyncImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'clientA',
          vectorClock: { clientA: 1 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: existingSyncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const opWithPrunedClock: Operation[] = [
          {
            id: '019afd70-0001-7000-0000-000000000000',
            actionType: '[Task Shared] addTask' as ActionType,
            opType: OpType.Create,
            entityType: 'TASK',
            entityId: 'new-task-1',
            payload: { title: 'My new task' },
            clientId: 'clientB',
            vectorClock: { clientB: 9747 }, // clientA was pruned from op's clock
            timestamp: Date.now(),
            schemaVersion: 1,
          },
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(opWithPrunedClock);

        // FILTERED: without the import-client counter, the op cannot prove it was
        // created after the clean-slate import.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });
    });

    describe('filteringImport return field', () => {
      it('should return filteringImport when ops are filtered by SYNC_IMPORT in batch', async () => {
        const syncImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 5 },
        });
        const filteredOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          vectorClock: { clientB: 2 }, // CONCURRENT - no knowledge of import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          filteredOp,
          syncImportOp,
        ]);

        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.id).toBe('019afd68-0050-7000-0000-000000000000');
        expect(result.filteringImport!.opType).toBe(OpType.SyncImport);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should return filteringImport when ops are filtered by stored SYNC_IMPORT', async () => {
        const storedImport: Operation = {
          id: '019afd68-0050-7000-0000-000000000000',
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'client-A',
          vectorClock: { clientA: 5 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        // Return as an entry (remote + synced = already accepted import)
        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: storedImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const filteredOps: Operation[] = [
          createOp({
            id: '019afd60-0001-7000-0000-000000000000',
            opType: OpType.Update,
            clientId: 'client-B',
            vectorClock: { clientB: 2 }, // CONCURRENT
          }),
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(filteredOps);

        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.id).toBe(storedImport.id);
        expect(result.filteringImport!.clientId).toBe('client-A');
        expect(result.invalidatedOps.length).toBe(1);
        expect(result.validOps.length).toBe(0);
      });

      it('should return undefined filteringImport when no import exists', async () => {
        const ops: Operation[] = [
          createOp({ id: '019afd68-0001-7000-0000-000000000000', opType: OpType.Update }),
          createOp({ id: '019afd68-0002-7000-0000-000000000000', opType: OpType.Create }),
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        expect(result.filteringImport).toBeUndefined();
        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should return filteringImport even when no ops are actually filtered (all valid)', async () => {
        const syncImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 5 },
        });
        const validOp = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          vectorClock: { clientA: 5, clientB: 1 }, // GREATER_THAN - has knowledge of import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          syncImportOp,
          validOp,
        ]);

        // filteringImport is set because import exists, even though no ops were filtered
        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.id).toBe('019afd68-0050-7000-0000-000000000000');
        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should return the LATEST import when multiple imports exist in batch', async () => {
        const ops: Operation[] = [
          createOp({
            id: '019afd68-0010-7000-0000-000000000000',
            opType: OpType.SyncImport,
            clientId: 'client-A',
            entityType: 'ALL',
            vectorClock: { clientA: 1 },
          }),
          createOp({
            id: '019afd68-0050-7000-0000-000000000000', // Later UUIDv7 = latest
            opType: OpType.SyncImport,
            clientId: 'client-B',
            entityType: 'ALL',
            vectorClock: { clientB: 1 },
          }),
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        // Should return the latest import (by UUIDv7)
        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.id).toBe('019afd68-0050-7000-0000-000000000000');
        expect(result.filteringImport!.clientId).toBe('client-B');
      });

      it('should return stored import when it is newer than batch import', async () => {
        const storedImport: Operation = {
          id: '019afd68-0100-7000-0000-000000000000', // Newer than batch import
          actionType: '[SP_ALL] Load(import) all data' as ActionType,
          opType: OpType.SyncImport,
          entityType: 'ALL',
          entityId: 'import-1',
          payload: { appDataComplete: {} },
          clientId: 'client-A',
          vectorClock: { clientA: 10 },
          timestamp: Date.now(),
          schemaVersion: 1,
        };

        // Return as an entry (remote + synced = already accepted import)
        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: storedImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const batchImport = createOp({
          id: '019afd68-0050-7000-0000-000000000000', // Older than stored
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 1 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([batchImport]);

        // Should return stored import (newer by UUIDv7)
        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.id).toBe(storedImport.id);
        expect(result.filteringImport!.clientId).toBe('client-A');
      });

      it('should return filteringImport for BACKUP_IMPORT as well', async () => {
        const backupImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.BackupImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 5 },
        });
        const filteredOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          vectorClock: { clientB: 2 }, // CONCURRENT
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          filteredOp,
          backupImportOp,
        ]);

        expect(result.filteringImport).toBeDefined();
        expect(result.filteringImport!.opType).toBe(OpType.BackupImport);
        expect(result.invalidatedOps.length).toBe(1);
      });
    });

    describe('isLocalUnsyncedImport flag', () => {
      // Helper to create OperationLogEntry
      const createEntry = (
        op: Operation,
        source: 'local' | 'remote',
        syncedAt?: number,
      ): OperationLogEntry => ({
        seq: 1,
        op,
        source,
        syncedAt,
        appliedAt: Date.now(),
      });

      it('should set isLocalUnsyncedImport=false when no import exists', async () => {
        const ops: Operation[] = [
          createOp({ id: '019afd68-0001-7000-0000-000000000000', opType: OpType.Update }),
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        expect(result.isLocalUnsyncedImport).toBe(false);
      });

      it('should set isLocalUnsyncedImport=false when filtering import is in the batch (remote)', async () => {
        // When a SYNC_IMPORT comes in the batch, it's being downloaded from remote
        // so it's not a local unsynced import
        const syncImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 1 },
        });
        const oldOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-A',
          vectorClock: { clientA: 1 }, // CONCURRENT with import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          oldOp,
          syncImportOp,
        ]);

        expect(result.isLocalUnsyncedImport).toBe(false);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should set isLocalUnsyncedImport=true when stored import is local and unsynced', async () => {
        const storedImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.BackupImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 1 },
        });
        const storedEntry = createEntry(storedImportOp, 'local', undefined); // No syncedAt

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve(storedEntry),
        );

        // Incoming op that will be filtered
        const oldOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          vectorClock: { clientB: 1 }, // CONCURRENT with import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([oldOp]);

        expect(result.isLocalUnsyncedImport).toBe(true);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should set isLocalUnsyncedImport=false when stored import is local but already synced', async () => {
        // Once synced, the import is established — old straggler ops should be
        // silently discarded without showing the conflict dialog.
        const storedImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 1 },
        });
        const storedEntry = createEntry(storedImportOp, 'local', Date.now()); // Has syncedAt

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve(storedEntry),
        );

        const oldOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-B',
          vectorClock: { clientB: 1 }, // CONCURRENT with import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([oldOp]);

        expect(result.isLocalUnsyncedImport).toBe(false);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should set isLocalUnsyncedImport=false when stored import is remote', async () => {
        const storedImportOp = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientB: 1 },
        });
        const storedEntry = createEntry(storedImportOp, 'remote', Date.now());

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve(storedEntry),
        );

        const oldOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-C',
          vectorClock: { clientC: 1 }, // CONCURRENT with import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([oldOp]);

        expect(result.isLocalUnsyncedImport).toBe(false);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should prefer batch import over stored import when determining isLocalUnsyncedImport', async () => {
        // Even if there's a local unsynced import in the store, if a newer import
        // is in the batch, it's not a local unsynced import scenario
        const storedImportOp = createOp({
          id: '019afd68-0040-7000-0000-000000000000', // Older ID
          opType: OpType.BackupImport,
          clientId: 'client-A',
          entityType: 'ALL',
          vectorClock: { clientA: 1 },
        });
        const storedEntry = createEntry(storedImportOp, 'local', undefined);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve(storedEntry),
        );

        // Newer SYNC_IMPORT in the batch
        const batchImport = createOp({
          id: '019afd68-0050-7000-0000-000000000000', // Newer ID
          opType: OpType.SyncImport,
          clientId: 'client-B',
          entityType: 'ALL',
          vectorClock: { clientA: 1, clientB: 1 },
        });
        const oldOp = createOp({
          id: '019afd68-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'client-C',
          vectorClock: { clientC: 1 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          oldOp,
          batchImport,
        ]);

        // Batch import is used (newer), so isLocalUnsyncedImport is false
        expect(result.isLocalUnsyncedImport).toBe(false);
        expect(result.filteringImport!.id).toBe('019afd68-0050-7000-0000-000000000000');
      });
    });

    /* eslint-disable @typescript-eslint/naming-convention */
    describe('CONCURRENT ops from unknown clients', () => {
      /**
       * Unknown client IDs are not enough to preserve a CONCURRENT op.
       * The op must still prove it saw the import, either by dominating the import
       * clock or by carrying the import client's counter at or above the import op.
       */

      // Helper: build a clock with exactly N entries
      const buildClock = (entries: Record<string, number>): Record<string, number> =>
        entries;

      it('should KEEP ops from unknown client when it carries the import-client counter', async () => {
        // SYNC_IMPORT with 10 entries (< MAX=20, so no pruning possible)
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        const syncImport = createOp({
          id: '019c4290-0a51-7184-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'B_pr52',
          entityType: 'ALL',
          vectorClock: importClock,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: syncImport,
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Unknown client A_DReS carries B_pr52's import counter, proving it saw
        // the import even though A_DReS is not in the import clock.
        const mobileOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_DReS',
          entityId: 'new-task-1',
          actionType: '[Task Shared] addTask' as ActionType,
          vectorClock: buildClock({
            A_DReS: 1,
            A_bw1h: 227,
            A_wU5p: 95,
            // A_Zw6o: 88 was PRUNED by server
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([mobileOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.validOps[0].clientId).toBe('A_DReS');
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP multiple ops from unknown client when they carry the import-client counter', async () => {
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const ops = [
          createOp({
            id: '019c42a0-0001-7000-0000-000000000000',
            opType: OpType.Create,
            clientId: 'A_DReS',
            entityId: 'task-1',
            vectorClock: buildClock({
              A_DReS: 1,
              A_bw1h: 227,
              A_wU5p: 95,
              B_HSxu: 10774,
              B_pr52: 3642,
              BCL_174: 117821,
              BCLmd3: 4990,
              BCLmd4: 80215,
              BCLmdt: 653096,
              BCM_mhq: 2659,
            }),
          }),
          createOp({
            id: '019c42a0-0002-7000-0000-000000000000',
            opType: OpType.Update,
            clientId: 'A_DReS',
            entityId: 'task-1',
            vectorClock: buildClock({
              A_DReS: 2,
              A_bw1h: 227,
              A_wU5p: 95,
              B_HSxu: 10774,
              B_pr52: 3642,
              BCL_174: 117821,
              BCLmd3: 4990,
              BCLmd4: 80215,
              BCLmdt: 653096,
              BCM_mhq: 2659,
            }),
          }),
        ];

        const result = await service.filterOpsInvalidatedBySyncImport(ops);

        // Both ops carry the import client's counter.
        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP ops from unknown client even when shared keys are GREATER than import', async () => {
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client saw more ops from B_pr52 after the import
        const mobileOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_DReS',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_DReS: 3,
            A_bw1h: 227,
            A_wU5p: 95,
            B_HSxu: 10774,
            B_pr52: 3650, // GREATER than import's 3642
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([mobileOp]);

        // KEPT: op carries an import-client counter greater than the import.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should FILTER ops from unknown client with NO shared keys', async () => {
        const importClock = buildClock({
          clientA: 5,
          clientB: 10,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'clientA',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Unknown client - no shared keys with import at all
        const unknownOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'clientNew',
          entityId: 'task-1',
          vectorClock: { clientNew: 5 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([unknownOp]);

        // FILTERED: the op does not carry the import client's counter.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should FILTER ops from unknown client with shared keys but LOWER import-client value', async () => {
        const importClock = buildClock({
          clientA: 100,
          clientB: 200,
          clientC: 300,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'clientA',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client has shared keys but LOWER values than import
        // This means the client saw older ops from these clients, NOT the import
        const genuinelyConcurrentOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'clientNew',
          entityId: 'task-1',
          vectorClock: {
            clientNew: 5,
            clientA: 50, // LOWER than import's 100
            clientB: 200, // EQUAL
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          genuinelyConcurrentOp,
        ]);

        // FILTERED: clientA is the import client, and the op's clientA counter is stale.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should still FILTER ops from client that IS in import clock (not a new client)', async () => {
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Client A_bw1h IS in import's clock - this is an existing client, not new.
        // Even though shared keys are equal, the pruning-artifact heuristic should NOT apply.
        const existingClientOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'A_bw1h',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_bw1h: 228,
            A_wU5p: 95,
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
            A_Zw6o: 88,
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([existingClientOp]);

        // This should be KEPT via normal GREATER_THAN comparison (A_bw1h: 228 > 227)
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP op from unknown client even when import is in the same batch', async () => {
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        const syncImport = createOp({
          id: '019c4290-0a51-7184-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'B_pr52',
          entityType: 'ALL',
          vectorClock: importClock,
        });

        const mobileOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_DReS',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_DReS: 1,
            A_bw1h: 227,
            A_wU5p: 95,
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          syncImport,
          mobileOp,
        ]);

        expect(result.validOps.length).toBe(2); // import itself + mobile post-import op
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP op from unknown client when import has few entries', async () => {
        const importClock = buildClock({
          clientA: 100,
          clientB: 200,
          clientC: 300,
          clientD: 400,
          clientE: 500,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'clientA',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client with shared keys >= import but missing clientE → CONCURRENT.
        const newClientOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'clientNew',
          entityId: 'task-1',
          vectorClock: buildClock({
            clientNew: 1,
            clientA: 100,
            clientB: 200,
            clientC: 300,
            clientD: 400,
            // clientE missing - genuinely not seen (not pruned)
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([newClientOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP ops from unknown client when MULTIPLE entries were pruned from op clock', async () => {
        // Import has MAX entries. New client inherits clock, sees 2 more new clients,
        // resulting in MAX+3 entries. Server prunes back to MAX, dropping 3 import entries.
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });
        expect(Object.keys(importClock).length).toBe(CLOCK_SIZE_10);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client added 3 entries (A_DReS, A_newX, A_newY) making 13 total.
        // Server pruned 3 import entries (A_Zw6o, A_wU5p, BCM_mhq) back to MAX.
        // Only 7 shared keys remain (8 inherited - 1 not present = 7).
        const mobileOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_DReS',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_DReS: 1,
            A_newX: 5,
            A_newY: 3,
            A_bw1h: 227,
            // A_wU5p: 95 was PRUNED
            // A_Zw6o: 88 was PRUNED
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            // BCM_mhq: 2659 was PRUNED
          }),
        });
        expect(Object.keys(mobileOp.vectorClock).length).toBe(CLOCK_SIZE_10);

        const result = await service.filterOpsInvalidatedBySyncImport([mobileOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP op from unknown client even when op clock has fewer entries than import', async () => {
        // Import has MAX entries. New client creates an op with fewer than MAX entries
        // (e.g., server pruned heavily or client only inherited a subset).
        // compareVectorClocks returns CONCURRENT due to asymmetric keys.
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Op has only 6 entries: own clientId + 5 inherited entries
        // (heavy pruning or partial inheritance scenario)
        const mobileOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_DReS',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_DReS: 1,
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmdt: 653096,
            BCM_mhq: 2659,
          }),
        });
        expect(Object.keys(mobileOp.vectorClock).length).toBe(6); // < MAX

        const result = await service.filterOpsInvalidatedBySyncImport([mobileOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should FILTER ops from completely unknown client with NO shared keys', async () => {
        // Import has 10 entries (below MAX=20), op has zero overlap
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Completely unknown client with no shared keys.
        const unknownOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'Z_unknown',
          entityId: 'task-1',
          vectorClock: { Z_unknown: 5 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([unknownOp]);

        // FILTERED: the op does not carry the import client's counter.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should KEEP unknown client ops even if they were once concurrent (import below MAX)', async () => {
        // Import has 10 entries (below MAX=20). A_old1 is not in the import clock.
        // Since the import clock hasn't been pruned, the missing entry means the
        // import truly doesn't know about this client.
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
          B_xtra: 500,
        });
        expect(Object.keys(importClock).length).toBe(CLOCK_SIZE_10);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const concurrentOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'A_old1',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_old1: 50,
            A_bw1h: 227,
            A_wU5p: 95,
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
          }),
        });

        const result = await service.filterOpsInvalidatedBySyncImport([concurrentOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should KEEP ops from unknown client with lower non-import shared keys when import-client counter is present', async () => {
        // A_stale is not in import's clock, but the op carries B_pr52's import
        // counter. Lower counters for other shared clients do not invalidate that
        // causal proof.
        const importClock = buildClock({
          A_bw1h: 227,
          A_wU5p: 95,
          A_Zw6o: 88,
          B_HSxu: 10774,
          B_pr52: 3642,
          BCL_174: 117821,
          BCLmd3: 4990,
          BCLmd4: 80215,
          BCLmdt: 653096,
          BCM_mhq: 2659,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Unknown client with shared keys but stale values
        const staleOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'A_stale',
          entityId: 'task-1',
          vectorClock: buildClock({
            A_stale: 5,
            A_bw1h: 100, // LOWER than import's 227
            B_HSxu: 10774,
            B_pr52: 3642,
            BCL_174: 117821,
            BCLmd3: 4990,
            BCLmd4: 80215,
            BCLmdt: 653096,
            BCM_mhq: 2659,
            A_wU5p: 95,
          }),
        });
        expect(Object.keys(staleOp.vectorClock).length).toBe(CLOCK_SIZE_10);

        const result = await service.filterOpsInvalidatedBySyncImport([staleOp]);

        // KEPT: op carries the import client's counter.
        expect(result.validOps.length).toBe(1);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should FILTER unknown client ops when import clock is AT MAX_VECTOR_CLOCK_SIZE', async () => {
        // Import has exactly MAX=20 entries. Missing clientId could be a pruned entry,
        // not a truly unknown client. Conservatively filter.
        const importClock: Record<string, number> = {};
        for (let i = 0; i < 20; i++) {
          importClock[`client_${String(i).padStart(2, '0')}`] = 100 + i;
        }
        expect(Object.keys(importClock).length).toBe(20);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'client_00',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Unknown client not in MAX-size import — could be pruned
        const unknownOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'Z_unknown',
          entityId: 'task-1',
          vectorClock: { Z_unknown: 5 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([unknownOp]);

        // FILTERED: import at MAX size, missing entry might be pruned
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should FILTER unknown client ops when import clock EXCEEDS MAX_VECTOR_CLOCK_SIZE', async () => {
        // Import has more than MAX entries (e.g., from migration before pruning).
        // Missing clientId could definitely be pruned.
        const importClock: Record<string, number> = {};
        for (let i = 0; i < 25; i++) {
          importClock[`client_${String(i).padStart(2, '0')}`] = 100 + i;
        }
        expect(Object.keys(importClock).length).toBe(25);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 3,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'client_00',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        const unknownOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'Z_unknown',
          entityId: 'task-1',
          vectorClock: { Z_unknown: 5 },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([unknownOp]);

        // FILTERED: import exceeds MAX, missing entry could be pruned
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('should FILTER ops from client that IS in import clock regardless of clock size', async () => {
        // Import has 3 entries (below MAX). Op clientId IS in the import clock.
        // This is a known client with a CONCURRENT op — should be filtered.
        const importClock = buildClock({
          clientA: 100,
          clientB: 200,
          clientC: 300,
        });

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019c4290-0a51-7184-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'clientA',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // clientB IS in the import clock — import knows about this client
        const knownClientOp = createOp({
          id: '019c42a0-0001-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'clientB',
          entityId: 'task-1',
          vectorClock: {
            clientB: 150, // LESS than import's 200
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([knownClientOp]);

        // FILTERED: import knows clientB (entry exists) and op is LESS_THAN
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });
    });
    /* eslint-enable @typescript-eslint/naming-convention */

    // NOTE: The "Oversized import clock normalization" describe block was REMOVED.
    // Clock normalization (limitVectorClockSize on import clock before comparison)
    // has been removed from the production code. Import clocks are now compared
    // directly without pruning. With MAX_VECTOR_CLOCK_SIZE increased to 20,
    // oversized clocks from the old MAX=10 era are well within bounds and
    // no longer need normalization.

    describe('Bug Scenario: Pruned vector clock causes false CONCURRENT classification', () => {
      /**
       * This test verifies the scenario that caused the bug where changes on client B
       * were not syncing to client A.
       *
       * Root Cause: When a SYNC_IMPORT is created locally via handleServerMigration(),
       * the protectedClientIds were not being set.
       * Without this protection, limitVectorClockSize() would prune low-counter entries
       * from subsequent operations' vector clocks.
       *
       * Example from logs:
       * - Op vectorClock had 9 entries
       * - Import vectorClock had 16 entries
       * - Op was missing 7 low-counter entries present in Import
       * - This caused CONCURRENT comparison instead of GREATER_THAN
       *
       * The fix was originally setProtectedClientIds(); now resolved by increasing
       * MAX_VECTOR_CLOCK_SIZE to 20, making pruning protection unnecessary.
       * This test validates the correct behavior when vector clocks are properly maintained.
       */

      it('should classify op as GREATER_THAN when it has full knowledge of SYNC_IMPORT (no pruning)', async () => {
        // Simulate a SYNC_IMPORT with many client entries (like from server migration)
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_3Xx3: 5,
          A_AMT3: 81,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_EemJ: 1,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_Jxm0: 35,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_wU5p: 13,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_ypDK: 19,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_bC8O: 25,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_HSxu: 10806,
        };

        const syncImport = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'A_Jxm0',
          entityType: 'ALL',
          vectorClock: syncImportClock,
        });

        // Op created AFTER the import - includes ALL entries from import plus increment
        // (This is what happens when SYNC_IMPORT replaces the clock correctly)
        const postImportOp = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'A_Jxm0',
          entityId: 'task-1',
          vectorClock: {
            // All entries from import are preserved
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_3Xx3: 5,
            A_AMT3: 81,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_EemJ: 1,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_Jxm0: 36, // Incremented
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_wU5p: 13,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_ypDK: 19,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            B_bC8O: 25,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            B_HSxu: 10806,
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          syncImport,
          postImportOp,
        ]);

        // Both should be valid - op has GREATER_THAN relationship to import
        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should correctly keep same-client op with pruned clock (was previously a bug)', async () => {
        // SYNC_IMPORT with many client entries
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_3Xx3: 5,
          A_AMT3: 81,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_EemJ: 1,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_Jxm0: 35,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_wU5p: 13,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_ypDK: 19,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_bC8O: 25,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_HSxu: 10806,
        };

        const syncImport = createOp({
          id: '019afd68-0050-7000-0000-000000000000',
          opType: OpType.SyncImport,
          clientId: 'A_Jxm0',
          entityType: 'ALL',
          vectorClock: syncImportClock,
        });

        // Op created AFTER the import by the SAME client, but with PRUNED clock
        // (missing low-counter entries). The op's counter (36) > import's counter (35)
        // proves it was created after the import.
        const postImportOpWithPrunedClock = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'A_Jxm0',
          entityId: 'task-1',
          vectorClock: {
            // Only kept the highest counter entries (pruned to ~3 entries)
            // Missing: A_3Xx3, A_EemJ, A_wU5p, A_ypDK, B_bC8O (all with low counters)
            A_AMT3: 81,
            // eslint-disable-next-line @typescript-eslint/naming-convention
            A_Jxm0: 36, // Incremented from 35
            // eslint-disable-next-line @typescript-eslint/naming-convention
            B_HSxu: 10806,
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          syncImport,
          postImportOpWithPrunedClock,
        ]);

        // FIXED: Op is now correctly KEPT because same-client counter comparison
        // (A_Jxm0: 36 > 35) definitively proves the op was created after the import.
        // Previously this was incorrectly classified as CONCURRENT and filtered.
        expect(result.validOps.length).toBe(2);
        expect(result.invalidatedOps.length).toBe(0);
      });
    });

    describe('same-client pruning artifact detection', () => {
      it('should KEEP op from same client as import when op counter is higher (real-world scenario)', async () => {
        // Real-world scenario: B_pr52 created a SYNC_IMPORT with a 10-entry clock.
        // Later, B_pr52 continues creating ops. Over time, pruning causes the op's
        // clock to diverge from the import's frozen clock (different entries pruned).
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_bw1h: 52,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_wU5p: 95,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_Jxm0: 35,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_3Xx3: 5,
          A_AMT3: 81,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_EemJ: 1,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_ypDK: 19,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_bC8O: 25,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_HSxu: 10806,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_pr52: 4176,
        };
        expect(Object.keys(syncImportClock).length).toBe(CLOCK_SIZE_10);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'B_pr52',
              entityType: 'ALL',
              vectorClock: syncImportClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Op from B_pr52 with a higher counter (4379 > 4176) but different pruned entries.
        // Has A_DReS:110 (new client added after import), missing A_wU5p (pruned).
        const opClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_bw1h: 52,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_DReS: 110,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_Jxm0: 35,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_3Xx3: 5,
          A_AMT3: 81,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_EemJ: 1,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          A_ypDK: 19,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_bC8O: 25,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_HSxu: 10806,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          B_pr52: 4379,
        };
        expect(Object.keys(opClock).length).toBe(CLOCK_SIZE_10);

        const op = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'B_pr52',
          entityId: 'task-1',
          vectorClock: opClock,
        });

        const result = await service.filterOpsInvalidatedBySyncImport([op]);

        // Op is from the SAME client as import with higher counter (4379 > 4176).
        // This definitively proves the op was created after the import.
        expect(result.validOps.length).toBe(1);
        expect(result.validOps[0].id).toBe('019afd68-0100-7000-0000-000000000000');
        expect(result.invalidatedOps.length).toBe(0);
      });

      it('should FILTER op from same client as import when op counter is EQUAL', async () => {
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          client_A: 10,
          // eslint-disable-next-line @typescript-eslint/naming-convention
          client_B: 20,
          import_client: 50,
        };

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'import_client',
              entityType: 'ALL',
              vectorClock: syncImportClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Same client, same counter but different entries → CONCURRENT
        const op = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'import_client',
          entityId: 'task-1',
          vectorClock: {
            // eslint-disable-next-line @typescript-eslint/naming-convention
            client_C: 5,
            import_client: 50,
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([op]);

        // Counter is EQUAL (50 == 50) — NOT definitively post-import
        expect(result.invalidatedOps.length).toBe(1);
        expect(result.validOps.length).toBe(0);
      });

      it('should FILTER op from same client as import when op counter is LOWER', async () => {
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          client_A: 10,
          import_client: 50,
        };

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'import_client',
              entityType: 'ALL',
              vectorClock: syncImportClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Same client, lower counter → LESS_THAN (dominated by import)
        const op = createOp({
          id: '019afd68-0030-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'import_client',
          entityId: 'task-1',
          vectorClock: {
            import_client: 40,
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([op]);

        // Counter is lower (40 < 50) — pre-import op, LESS_THAN → filtered
        expect(result.invalidatedOps.length).toBe(1);
        expect(result.validOps.length).toBe(0);
      });

      it('should FILTER op from DIFFERENT client even with higher counter on that client', async () => {
        const syncImportClock = {
          // eslint-disable-next-line @typescript-eslint/naming-convention
          client_A: 10,
          import_client: 50,
          other_client: 30,
        };

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'import_client',
              entityType: 'ALL',
              vectorClock: syncImportClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Different client with higher counter but missing import_client entry
        const op = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'other_client',
          entityId: 'task-1',
          vectorClock: {
            other_client: 35,
          },
        });

        const result = await service.filterOpsInvalidatedBySyncImport([op]);

        // Different client — same-client fix does NOT apply
        expect(result.invalidatedOps.length).toBe(1);
        expect(result.validOps.length).toBe(0);
      });
    });

    describe('full pruning pipeline simulation', () => {
      /**
       * These tests simulate the full round-trip of vector clock pruning.
       * With MAX_VECTOR_CLOCK_SIZE=20, pruning requires 21+ unique client IDs.
       * All CONCURRENT ops are filtered under clean slate semantics.
       */

      it('Test F: server-pruned clock round-trip — op from new client filtered as CONCURRENT', async () => {
        const importClock: Record<string, number> = {};
        for (let i = 0; i < CLOCK_SIZE_10; i++) {
          importClock[`client_${i}`] = 100 + i;
        }
        expect(Object.keys(importClock).length).toBe(CLOCK_SIZE_10);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'client_0',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client K inherited import clock + own ID = CLOCK_SIZE_10+1.
        // Server pruned: dropped client_0 (lowest counter=100), kept clientK.
        // Result: CLOCK_SIZE_10 entries with clientK replacing client_0.
        const serverPrunedOpClock: Record<string, number> = {};
        for (let i = 1; i < CLOCK_SIZE_10; i++) {
          serverPrunedOpClock[`client_${i}`] = 100 + i; // inherited from import
        }
        serverPrunedOpClock['clientK'] = 1; // K's own counter
        expect(Object.keys(serverPrunedOpClock).length).toBe(CLOCK_SIZE_10);

        const opFromK = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'clientK',
          entityId: 'task-1',
          vectorClock: serverPrunedOpClock,
        });

        const result = await service.filterOpsInvalidatedBySyncImport([opFromK]);

        // clientK is not in the import clock and client_0 was pruned from the op,
        // so the op no longer proves import knowledge.
        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.length).toBe(1);
      });

      it('Test G: multiple new clients after import — progressive pruning, both filtered', async () => {
        // Import with exactly CLOCK_SIZE_10 entries
        const importClock: Record<string, number> = {};
        for (let i = 0; i < CLOCK_SIZE_10; i++) {
          importClock[`client_${i}`] = 50 + i;
        }

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'client_0',
              entityType: 'ALL',
              vectorClock: importClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // Client K joins: inherits import + own = CLOCK_SIZE_10+1.
        // Server prunes: drops client_0 (counter=50, lowest), keeps clientK.
        const kClock: Record<string, number> = {};
        for (let i = 1; i < CLOCK_SIZE_10; i++) {
          kClock[`client_${i}`] = 50 + i;
        }
        kClock['clientK'] = 1;

        // Client L joins after K: inherits K's pruned clock + own = CLOCK_SIZE_10+1.
        // Server prunes: drops client_1 (counter=51, now lowest), keeps clientL.
        const lClock: Record<string, number> = {};
        for (let i = 2; i < CLOCK_SIZE_10; i++) {
          lClock[`client_${i}`] = 50 + i;
        }
        lClock['clientK'] = 1; // inherited from K
        lClock['clientL'] = 1; // L's own counter

        const opFromK = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'clientK',
          entityId: 'task-1',
          vectorClock: kClock,
        });

        const opFromL = createOp({
          id: '019afd68-0200-7000-0000-000000000000',
          opType: OpType.Create,
          clientId: 'clientL',
          entityId: 'task-2',
          vectorClock: lClock,
        });

        const result = await service.filterOpsInvalidatedBySyncImport([opFromK, opFromL]);

        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.map((op) => op.clientId)).toEqual(
          jasmine.arrayContaining(['clientK', 'clientL']),
        );
        expect(result.invalidatedOps.length).toBe(2);
      });

      it('Test H: large import clock (15 entries) — new client ops without import-client counter are filtered', async () => {
        // Import was created locally with 15 entries (exceeds CLOCK_SIZE_10=10, within MAX=20).
        // No normalization — import clock is compared directly.
        const oversizedImportClock: Record<string, number> = {};
        for (let i = 0; i < 15; i++) {
          oversizedImportClock[`client_${i}`] = 10 + i;
        }
        expect(Object.keys(oversizedImportClock).length).toBe(15);

        opLogStoreSpy.getLatestFullStateOpEntry.and.returnValue(
          Promise.resolve({
            seq: 1,
            op: createOp({
              id: '019afd68-0050-7000-0000-000000000000',
              opType: OpType.SyncImport,
              clientId: 'client_0',
              entityType: 'ALL',
              vectorClock: oversizedImportClock,
            }),
            source: 'remote',
            syncedAt: Date.now(),
            appliedAt: Date.now(),
          }),
        );

        // New client K's op with clock based on the server's version of the import.
        // Server stored the import pruned to its MAX, so K inherited a pruned version.
        // K inherits the top-10 entries (client_5..14, values 15..24) + own = 11.
        // Server prunes K's clock: drops client_5 (counter=15, lowest),
        // keeps clientK. Result: 10 entries.
        const kClock: Record<string, number> = {};
        for (let i = 6; i < 15; i++) {
          kClock[`client_${i}`] = 10 + i; // 9 entries from pruned import
        }
        kClock['clientK'] = 1;
        expect(Object.keys(kClock).length).toBe(CLOCK_SIZE_10);

        const opFromK = createOp({
          id: '019afd68-0100-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'clientK',
          entityId: 'task-1',
          vectorClock: kClock,
        });

        // Also test a genuinely concurrent op (from a client that existed before import)
        const concurrentOp = createOp({
          id: '019afd68-0080-7000-0000-000000000000',
          opType: OpType.Update,
          clientId: 'old_client',
          entityId: 'task-2',
          vectorClock: { old_client: 5 }, // no knowledge of import
        });

        const result = await service.filterOpsInvalidatedBySyncImport([
          opFromK,
          concurrentOp,
        ]);

        expect(result.validOps.length).toBe(0);
        expect(result.invalidatedOps.map((op) => op.clientId)).toEqual(
          jasmine.arrayContaining(['clientK', 'old_client']),
        );
        expect(result.invalidatedOps.length).toBe(2);
      });
    });
  });
});
