import type { Pool } from 'pg';

import {
  calendarSendPayloadSchema,
  CALENDAR_SEND_ACTIONS,
  type CalendarSendAction,
  type CalendarSendPayload,
} from '@/entities/calendarSendItem';
import { getDb } from '@/shared/db';
import {
  createSendQueueRepo,
  type PendingItem,
  type SendResultInput,
} from '@/shared/sendQueue';

const repo = createSendQueueRepo({
  tableName: 'macsync.calendar_send_queue',
  payloadSchema: calendarSendPayloadSchema,
  allowedActions: CALENDAR_SEND_ACTIONS,
});

export interface EnqueueEventInput {
  deviceId: string;
  action: CalendarSendAction;
  payload: CalendarSendPayload;
}

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

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

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