import { createHash } from 'crypto';
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';

/**
 * Rail send outbox (Prisma `gateway_outbox`). Scaffold for PG-GW-W01 send orchestration:
 * enqueue → worker claims PENDING → marks SENT/FAILED (DLQ semantics = FAILED + operator retry).
 */
export function hashPayload(payload: string): string {
	return createHash('sha256').update(payload, 'utf8').digest('hex');
}

export async function enqueueGatewayOutbox(params: {
	txnId: string;
	adapterId: string;
	payload: string;
}): Promise<{ id: string }> {
	const payloadHash = hashPayload(params.payload);
	const row = await prisma.gateway_outbox.create({
		data: {
			txnId: params.txnId,
			adapterId: params.adapterId,
			payloadHash,
			status: 'PENDING',
			sendAttempts: 0,
		},
	});
	logger.info('gateway_outbox enqueued', { id: row.id, adapterId: params.adapterId, txnId: params.txnId });
	return { id: row.id };
}

export async function listPendingGatewayOutbox(limit = 50): Promise<
	Array<{
		id: string;
		txnId: string;
		adapterId: string;
		payloadHash: string;
		sendAttempts: number;
		status: string;
	}>
> {
	return prisma.gateway_outbox.findMany({
		where: { status: 'PENDING' },
		orderBy: { createdAt: 'asc' },
		take: limit,
		select: {
			id: true,
			txnId: true,
			adapterId: true,
			payloadHash: true,
			sendAttempts: true,
			status: true,
		},
	});
}

export async function markGatewayOutboxSent(id: string): Promise<void> {
	await prisma.gateway_outbox.update({
		where: { id },
		data: { status: 'SENT', lastAttemptAt: new Date() },
	});
}

export async function markGatewayOutboxFailed(id: string, incrementAttempts = true): Promise<void> {
	const row = await prisma.gateway_outbox.findUnique({ where: { id } });
	if (!row) return;
	await prisma.gateway_outbox.update({
		where: { id },
		data: {
			status: 'FAILED',
			lastAttemptAt: new Date(),
			sendAttempts: incrementAttempts ? row.sendAttempts + 1 : row.sendAttempts,
		},
	});
}
