import type { Pool } from 'pg';

import {
  mailSendPayloadSchema,
  MAIL_SEND_ACTIONS,
  type MailSendAction,
  type MailSendPayload,
} from '@/entities/mailSendItem';
import { getDb } from '@/shared/db';
import {
  createSendQueueRepo,
  type PendingItem,
  type SendResultInput,
} from '@/shared/sendQueue';

const repo = createSendQueueRepo({
  tableName: 'macsync.mail_send_queue',
  payloadSchema: mailSendPayloadSchema,
  allowedActions: MAIL_SEND_ACTIONS,
});

export interface EnqueueMailInput {
  deviceId: string;
  action: MailSendAction;
  payload: MailSendPayload;
}

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

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

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