import type { RpcResponse } from "viem/_types/types/rpc";
import { sleep } from "./sleep";

export type TransactionStatus =
	| "confirmed"
	| "finalized"
	| "processed"
	| "error";

export const validateTransaction = async (
	signature: string,
	rpcEndpoint: string | undefined,
	retries = 0,
	retryIntervalMs = 5000,
): Promise<{
	success: boolean;
	status: TransactionStatus;
	error: unknown;
}> => {
	if (!rpcEndpoint) {
		return {
			success: false,
			status: "error",
			error: "RPC endpoint is not defined",
		};
	}
	const { result } = await getTransactionStatus(signature, rpcEndpoint);

	const status = result?.value[0]?.confirmationStatus;
	const err = result?.value[0]?.err;

	if (!["confirmed", "finalized"].includes(status) || err) {
		if (retries > 5) {
			return {
				success: status === "processed",
				status,
				error: err,
			};
		}
		await sleep(retryIntervalMs);
		return await validateTransaction(
			signature,
			rpcEndpoint,
			retries + 1,
			retryIntervalMs,
		);
	}

	return {
		success: true,
		status,
		error: err,
	};
};

export const getTransactionStatus = async (
	signature: string,
	rpcEndpoint: string,
) => {
	const body = {
		jsonrpc: "2.0",
		id: 1,
		method: "getSignatureStatuses",
		params: [
			[signature],
			{
				searchTransactionHistory: true,
			},
		],
	};

	const response = await fetch(rpcEndpoint, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
		},
		body: JSON.stringify(body),
	});

	const data = await response.json();

	return data as RpcResponse;
};
