import { calculateRates } from "@utils/calculateRates";
import { formatValue } from "@utils/formatValue";
import { getAutoMinOutput, getManualMinOutput } from "@utils/getMinOutput";
import type {
	BungeeQuote,
	FormattedAutoQuote,
	FormattedManualQuote,
} from "./types";

export function formatAutoRoute(
	data: BungeeQuote,
): FormattedAutoQuote | undefined {
	const autoRoute = data?.autoRoute;
	if (!autoRoute) return;

	const { input } = data;
	const output = autoRoute.output;

	const minOutput = getAutoMinOutput(output, autoRoute.slippage);

	// deriving formatted amounts to calculate the exchange rate
	const formattedInputAmount = input
		? formatValue(input.amount, input.token.decimals)
		: "0";
	const formattedOutputAmount = output
		? formatValue(output.amount, output.token.decimals)
		: "0";

	const { srcToDestRate, destToSrcRate } = calculateRates(
		formattedInputAmount,
		formattedOutputAmount,
	);

	return {
		...autoRoute,
		requestType: autoRoute.requestType,
		routingMode: "auto",
		receiver: data.receiverAddress,
		sender: data.userAddress,
		input: [data.input],
		output: [autoRoute.output],
		primaryInput: data.input,
		primaryOutput: autoRoute.output,
		estimatedFulfilTime: autoRoute.estimatedTime,
		// derived
		isSwapRoute: autoRoute.requestType === "SWAP_REQUEST",
		slippage: autoRoute.slippage,
		minOutput,
		srcToDestRate,
		destToSrcRate,
		rewards: autoRoute?.rewards?.isRewardEnabled ? autoRoute.rewards : undefined,
	};
}

export function formatManualRoutes(
	data: BungeeQuote,
): FormattedManualQuote[] | undefined {
	const manualRoutes = data?.manualRoutes;
	if (!manualRoutes?.length) return;

	return manualRoutes.map((item): FormattedManualQuote => {
		const minOutput = getManualMinOutput(item.output);

		// deriving formatted amount to calculate exchange rate
		const formattedInputAmount =
			data.input && formatValue(data.input.amount, data.input.token.decimals);
		const formattedOutputAmount =
			item.output && formatValue(item.output.amount, item.output.token.decimals);

		const { srcToDestRate, destToSrcRate } = calculateRates(
			formattedInputAmount,
			formattedOutputAmount,
		);

		return {
			...item,
			receiver: data.receiverAddress,
			sender: data.userAddress,
			input: [data.input],
			output: [item.output],
			primaryInput: data.input,
			primaryOutput: item.output,
			estimatedFulfilTime: item.estimatedTime,
			// derived
			isSwapRoute: item.output.token.chainId === data.input.token.chainId,
			// manual specific
			routingMode: "manual",
			protocol: item.routeDetails,
			totalGasFeesInUsd: item.gasFee.feeInUsd,
			receivedValueInUsd:
				item.output.valueInUsd && item.gasFee.feeInUsd
					? item.output.valueInUsd - item.gasFee.feeInUsd
					: 0,
			slippage: item?.slippage,
			minOutput,
			srcToDestRate,
			destToSrcRate,
			approvalData: item?.approvalData,
			routeId: item.quoteId,
		};
	});
}
