/** Maximum number of recent messages to include in sync inventories. */
export const INVENTORY_LIMIT = 1000;

/** Number of messages per chunk for inventory / batch transfers. */
export const CHUNK_SIZE = 200;

/** Aggressive sync poll interval (10 seconds). */
export const SYNC_POLL_FAST_MS = 10_000;

/** Idle sync poll interval after a clean (no-new-messages) cycle (15 minutes). */
export const SYNC_POLL_SLOW_MS = 900_000;

/** Sync timeout duration before auto-completing a cycle (5 seconds). */
export const SYNC_TIMEOUT_MS = 5_000;

/** Large limit used for legacy full-sync operations. */
export const FULL_SYNC_LIMIT = 10_000;

/** Inventory item representing a message's sync state. */
export interface InventoryItem {
  id: string;
  ts: number;
  rc: number;
  ac?: number;
}

/** Splits an array into chunks of the given size. */
export function chunkArray<T>(items: T[], size: number): T[][] {
  const chunks: T[][] = [];

  for (let index = 0; index < items.length; index += size) {
    chunks.push(items.slice(index, index + size));
  }

  return chunks;
}

/** Identifies missing or stale message IDs by comparing remote items against a local map. */
export function findMissingIds(
  remoteItems: readonly { id: string; ts: number; rc?: number; ac?: number }[],
  localMap: ReadonlyMap<string, { ts: number; rc: number; ac: number }>
): string[] {
  const missing: string[] = [];

  for (const item of remoteItems) {
    const local = localMap.get(item.id);

    if (
      !local ||
      item.ts > local.ts ||
      (item.rc !== undefined && item.rc !== local.rc) ||
      (item.ac !== undefined && item.ac !== local.ac)
    ) {
      missing.push(item.id);
    }
  }

  return missing;
}
