import { database, collections } from './index';
import { Q } from '@nozbe/watermelondb';
import Tombstone, { TombstoneEntity } from '@/models/Tombstone';

// Batch variant: must be called from inside an existing database.write().
export async function recordTombstonesInBatch(entity: TombstoneEntity, ids: string[]): Promise<void> {
  const uniqueIds = [...new Set(ids)].filter(Boolean);
  for (const id of uniqueIds) {
    const existing = await collections.tombstones
      .query(Q.where('entity', entity), Q.where('entity_id', id))
      .fetch();
    const now = new Date();
    if (existing.length > 0) {
      await existing[0].update((t) => {
        t.deletedAt = now;
      });
    } else {
      await collections.tombstones.create((t) => {
        t.entity = entity;
        t.entityId = id;
        t.deletedAt = now;
      });
    }
  }
}

// Batch variant: must be called from inside an existing database.write().
export async function removeTombstonesInBatch(entity: TombstoneEntity, ids: string[]): Promise<void> {
  for (const id of ids) {
    const existing = await collections.tombstones
      .query(Q.where('entity', entity), Q.where('entity_id', id))
      .fetch();
    for (const row of existing) {
      await row.destroyPermanently();
    }
  }
}

export async function recordTombstone(entity: TombstoneEntity, id: string): Promise<void> {
  await database.write(async () => {
    await recordTombstonesInBatch(entity, [id]);
  });
}

export async function recordTombstones(entity: TombstoneEntity, ids: string[]): Promise<void> {
  await database.write(async () => {
    await recordTombstonesInBatch(entity, ids);
  });
}

export async function removeTombstone(entity: TombstoneEntity, id: string): Promise<void> {
  await database.write(async () => {
    await removeTombstonesInBatch(entity, [id]);
  });
}

export async function removeTombstones(entity: TombstoneEntity, ids: string[]): Promise<void> {
  await database.write(async () => {
    await removeTombstonesInBatch(entity, ids);
  });
}

export async function fetchPendingTombstones(sinceMs: number): Promise<Tombstone[]> {
  return collections.tombstones.query(Q.where('deleted_at', Q.gt(sinceMs))).fetch();
}
