import type { DeltaDeletedItem } from "../types";

export type DeltaRowMergeOptions<T> = {
  deletedResourceType?: string;
  sort?: (left: T, right: T) => number;
};

export function deltaDeletedIds(deleted: DeltaDeletedItem[] | undefined, resourceType?: string): Set<string> {
  return new Set(
    (deleted ?? [])
      .filter((item) => !resourceType || !item.resource_type || item.resource_type === resourceType)
      .map((item) => item.id)
  );
}

export function mergeDeltaRows<T>(
  current: T[],
  changed: T[],
  deleted: DeltaDeletedItem[] | undefined,
  getKey: (item: T) => string,
  options: DeltaRowMergeOptions<T> = {}
): T[] {
  const byId = new Map(current.map((item) => [getKey(item), item]));
  for (const item of changed) {
    byId.set(getKey(item), item);
  }
  for (const id of deltaDeletedIds(deleted, options.deletedResourceType)) {
    byId.delete(id);
  }
  const rows = Array.from(byId.values());
  return options.sort ? rows.sort(options.sort) : rows;
}
