import { randomUUIDv7 } from 'bun';

import { touchDevice } from '@/entities/device';
import { countNotes, getLastNoteSyncAt, listNotes, upsertNote } from '@/entities/note';
import type { NoteFilter, NoteRecord } from '@/entities/note';
import { getDb, pgRun } from '@/shared/db';

export interface NotePayload {
  noteIdentifier: string;
  folder?: string | null;
  name?: string | null;
  body?: string | null;
  modifiedAt?: string | null;
}

export interface SyncNotesPayload {
  notes: NotePayload[];
}

export interface INoteStats {
  totalNotes: number;
  lastSyncAt: string | null;
}

export async function ingestNotes(
  deviceId: string,
  payload: SyncNotesPayload,
): Promise<{ synced: number }> {
  try {
    const db = getDb();
    await touchDevice(db, deviceId);

    let synced = 0;
    for (const n of payload.notes) {
      await upsertNote(db, {
        id: randomUUIDv7(),
        deviceId,
        externalId: n.noteIdentifier,
        folder: n.folder ?? null,
        name: n.name ?? null,
        body: n.body ?? null,
        modifiedAt: n.modifiedAt ?? null,
      });
      synced++;
    }
    return { synced };
  } catch (err) {
    throw new Error(
      `ingestNotes failed for device ${deviceId}: ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}

export async function queryNotes(filter: NoteFilter): Promise<readonly NoteRecord[]> {
  try {
    return await listNotes(getDb(), filter);
  } catch (err) {
    throw new Error(
      `queryNotes failed: ${err instanceof Error ? err.message : String(err)}`,
      { cause: err },
    );
  }
}

export async function getINoteStats(deviceId: string): Promise<INoteStats> {
  try {
    const db = getDb();
    return {
      totalNotes: await countNotes(db, deviceId),
      lastSyncAt: await getLastNoteSyncAt(db, deviceId),
    };
  } catch (err) {
    throw new Error(
      `getINoteStats failed for device ${deviceId}: ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}

export async function resetNoteSync(deviceId: string): Promise<{ deleted: number }> {
  try {
    const db = getDb();
    const before = await countNotes(db, deviceId);
    await pgRun(db, 'DELETE FROM macsync.notes WHERE device_id = $1', [deviceId]);
    return { deleted: before };
  } catch (err) {
    throw new Error(
      `resetNoteSync failed for device ${deviceId}: ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}
