import type { Pool } from 'pg';

import {
  noteSendPayloadSchema,
  NOTE_SEND_ACTIONS,
  type NoteSendAction,
  type NoteSendPayload,
} from '@/entities/noteSendItem';
import { getDb } from '@/shared/db';
import {
  createSendQueueRepo,
  type PendingItem,
  type SendResultInput,
} from '@/shared/sendQueue';

const repo = createSendQueueRepo({
  tableName: 'macsync.note_send_queue',
  payloadSchema: noteSendPayloadSchema,
  allowedActions: NOTE_SEND_ACTIONS,
});

export interface EnqueueNoteInput {
  deviceId: string;
  action: NoteSendAction;
  payload: NoteSendPayload;
}

export async function enqueueNoteChange(
  input: EnqueueNoteInput,
  db: Pool = getDb(),
): Promise<{ id: string }> {
  try {
    return await repo.enqueue(db, input);
  } catch (err) {
    throw new Error(
      `enqueueNoteChange failed for device ${input.deviceId} (${input.action}): ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}

export async function listPendingNoteSends(
  deviceId: string,
  db: Pool = getDb(),
): Promise<PendingItem<NoteSendPayload>[]> {
  try {
    return await repo.listPending(db, deviceId);
  } catch (err) {
    throw new Error(
      `listPendingNoteSends failed for device ${deviceId}: ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}

export async function markNoteSendResult(
  input: SendResultInput,
  db: Pool = getDb(),
): Promise<void> {
  try {
    await repo.markResult(db, input);
  } catch (err) {
    throw new Error(
      `markNoteSendResult failed for id ${input.id}: ${
        err instanceof Error ? err.message : String(err)
      }`,
      { cause: err },
    );
  }
}
