/**
 * Admin outbox resource — write actions.
 *
 * - retryOutboxEvent: resets retryCount and clears failedAt, writes audit log.
 */

import { eq } from 'drizzle-orm';
import type { DrizzleClient } from '@/server/db/client.js';
import { outbox } from '@/server/db/schema.js';
import { OutboxMonitorError } from './errors.js';
import type { RetryOutboxEventInput } from './types.js';
import { recordAdminAction } from '@/server/db/queries/admin-actions.js';
import { resetOutboxEventForRetry } from '@/server/db/queries/outbox.js';

// ─── retryOutboxEvent ─────────────────────────────────────────────────────────

export async function retryOutboxEvent(
  db: DrizzleClient,
  input: RetryOutboxEventInput,
): Promise<void> {
  const { eventId, adminId } = input;

  const [event] = await db
    .select({
      id: outbox.id,
      processedAt: outbox.processedAt,
      retryCount: outbox.retryCount,
      aggregateId: outbox.aggregateId,
    })
    .from(outbox)
    .where(eq(outbox.id, eventId))
    .limit(1);

  if (!event) {
    throw new OutboxMonitorError('EVENT_NOT_FOUND', 'Outbox event not found');
  }

  if (event.processedAt) {
    throw new OutboxMonitorError('ALREADY_PROCESSED', 'Event has already been processed');
  }

  // Reset retryCount to 0 and clear failedAt so the processor picks it up again
  await resetOutboxEventForRetry(db, eventId);

  await recordAdminAction(db, {
    adminId,
    targetType: 'OUTBOX_EVENT',
    targetId: event.aggregateId,
    action: 'OUTBOX_RETRY',
    note: `Manually retried outbox event ${eventId}`,
  });
}
