import { ContractType as e } from "../../types/ethereum-network.types.mjs";
import { networkRegistry as t } from "../../constants/chains.constants.mjs";
import { TRON_DEFAULT_FEE_LIMIT_SUN as n, zeroAddress as r } from "../../constants/protocol.constants.mjs";
import { caseInsensitiveEqual as i } from "../../functions/utils/caseInsensitive.utils.mjs";
import { insufficientResourcesErrorCodes as a } from "../../error-handling/error-codes.constants.mjs";
import { emitTxPublicData as o } from "../../API/admin-calls.mjs";
import { Logger as s } from "../../error-handling/logger.mjs";
import { createTronCallData as c, estimateTronFeeSunWithPadding as l, evmHexToTronBase58Address as u } from "../../functions/utils/tron.utils.mjs";
import { constructAdminData as d } from "../../functions/pre-transaction/constructAdminData.mjs";
import { simulateTronTransaction as f } from "../../functions/utils/tronSimulation.utils.mjs";
import { buildApproveAndDepositWrapperCalls as p } from "../../functions/web3/functionCalls/constructBatchCall.mjs";
import { waitForErc20Approvals as m, waitForTronErc20Approvals as h } from "../../functions/web3/functionCalls/waitForErc20Approvals.mjs";
import { aggregateAmountsForApproval as g, approveTokens as _, approveTronTokens as v, assertNoDuplicateStealthAddressStructures as y } from "./hinkalProoflessDeposit.utils.mjs";
//#region libs/shared/common/src/data-structures/Hinkal/hinkalProoflessDepositViaWrapper.ts
var b = (e, t, n, a) => {
	let o = i(e, r), s = n.reduce((e, t, n) => i(t.erc20TokenAddress, r) ? e + a[n] : e, 0n) + (o ? t : 0n), c = g(n, a), l = c.filter(({ token: e }) => !i(e.erc20TokenAddress, r)).map((n) => !o && i(n.token.erc20TokenAddress, e) ? {
		token: n.token,
		balance: n.balance + t
	} : n).filter(({ balance: e }) => e > 0n);
	return !o && t > 0n && (c.some(({ token: t }) => i(t.erc20TokenAddress, e)) || l.push({
		token: {
			erc20TokenAddress: e,
			chainId: n[0]?.chainId
		},
		balance: t
	})), {
		tokensForApproval: l,
		ethValue: s
	};
}, x = (e, t, n, r) => {
	if (t.length !== n.length || n.length !== r.length) throw Error(`${e}: array length mismatch`);
}, S = async (e, p, m, g, _, S, C, w) => {
	x("hinkalTronProoflessDepositViaWrapper", _, S, C), y(C);
	let { hinkalWrapperAddress: T, hinkalWrapperABI: E } = t[p]?.contractData ?? {};
	if (!T || !E) throw Error(`No HinkalWrapper configured for chainId ${p}`);
	let D = await e.getRandomRelay(p, !1);
	if (!D) throw Error(`No relay available for chainId ${p}`);
	let O = e.getTronWeb(), k = await e.getEthereumAddressByChain(p), A = u(T), j = i(m, r) ? m : u(m), { tokensForApproval: M, ethValue: N } = b(m, g, _, S), P = _.map((e) => e.erc20TokenAddress), F = S.map(() => "0"), I = C.map((e) => [
		e.extraRandomization.toString(),
		e.stealthAddress.toString(),
		e.H0.toString(),
		e.H1.toString()
	]);
	if (N > 0n) {
		let e = BigInt(await O.trx.getBalance(k)), t = BigInt(n);
		try {
			t = await l(O, p, A, k, c(E, "prooflessDeposit", [
				u(D),
				j,
				g.toString(),
				P,
				S.map(String),
				F,
				I
			]), N);
		} catch (e) {
			s.error("Error estimating Tron wrapper deposit fee", e);
		}
		if (e < N + t) throw Error(a.INSUFFICIENT_TRON_BALANCE_FOR_FEE);
	}
	let { transaction: L } = await O.transactionBuilder.triggerSmartContract(A, "prooflessDeposit(address,address,uint256,address[],uint256[],uint256[],(uint256,uint256,uint256,uint256)[])", {
		feeLimit: n,
		callValue: N > 0n ? Number(N) : 0
	}, [
		{
			type: "address",
			value: u(D)
		},
		{
			type: "address",
			value: j
		},
		{
			type: "uint256",
			value: g.toString()
		},
		{
			type: "address[]",
			value: P
		},
		{
			type: "uint256[]",
			value: S.map(String)
		},
		{
			type: "uint256[]",
			value: F
		},
		{
			type: "tuple(uint256,uint256,uint256,uint256)[]",
			value: I
		}
	], k), R = new Map(M.map(({ token: e, balance: t }) => [u(e.erc20TokenAddress), t]));
	await v(O, k, A, R), R.size > 0 && await h(O, k, A, Array.from(R.entries()).map(([e, t]) => ({
		tokenAddress: e,
		requiredAmount: t
	}))), await f(p, A, "prooflessDeposit", E, [
		u(D),
		j,
		g.toString(),
		P,
		S.map(String),
		F,
		I
	], k, N > 0n ? N : void 0);
	let z = await O.trx.sign(L), B = await O.trx.sendRawTransaction(z);
	if (!B.result) throw Error("Tron wrapper deposit failed");
	let V = typeof B == "string" ? B : B?.txid ?? B?.transaction?.txID;
	if (!V) throw Error("Tron wrapper deposit failed (missing txid)");
	return o(d(w, p, P, S, k)), V;
}, C = async (n, r, i, a, s, c, l, u) => {
	x("hinkalEvmProoflessDepositViaWrapper", s, c, l), y(l);
	let f = t[r]?.contractData?.hinkalWrapperAddress;
	if (!f) throw Error(`No HinkalWrapper configured for chainId ${r}`);
	let h = await n.getRandomRelay(r, !1);
	if (!h) throw Error(`No relay available for chainId ${r}`);
	let g = s.map((e) => e.erc20TokenAddress), v = c.map(() => 0n), { tokensForApproval: S, ethValue: C } = b(i, a, s, c), w = await n.getEthereumAddressByChain(r), T = n.getProviderAdapter(r), E = n.getContractWithSigner(r, e.HinkalWrapper), D;
	if (S.length > 0 && await T.supportsBatchCall?.(r) && T.sendBatchCallsTransaction) {
		let e = p(S.map(({ token: e }) => e.erc20TokenAddress), S.map(({ balance: e }) => e), f, E.interface, h, i, a, g, c, v, l, C);
		D = await T.sendBatchCallsTransaction(r, e);
	} else await _(n, r, f, S), await m(n, r, w, f, S.map(({ token: e, balance: t }) => ({
		tokenAddress: e.erc20TokenAddress,
		requiredAmount: t
	}))), D = await E.prooflessDeposit(h, i, a, g, c, v, l, { value: C > 0n ? C : void 0 });
	return o(d(u, r, g, c, w)), D.hash;
};
//#endregion
export { C as hinkalEvmProoflessDepositViaWrapper, S as hinkalTronProoflessDepositViaWrapper };
