import { advancedToBigInt as e } from "../../../functions/utils/amounts.utils.mjs";
import { poseidonFunction as t } from "../../../crypto/poseidon.mjs";
import "../../../crypto/index.mjs";
import { encodeSolanaOnChainUtxo as n, isSolanaOnChainUtxo as r } from "../../crypto-keys/decodeUTXO.mjs";
import { MerkleTree as i } from "../../merkle-tree/MerkleTree.mjs";
import "../../merkle-tree/index.mjs";
import { contructMerkleTreeFromSerialized as a } from "../../../functions/utils/merkleTree.utils.mjs";
import { AbstractSolanaSnapshotService as o } from "./AbstractSolanaSnapshotService.mjs";
//#region libs/shared/common/src/data-structures/event-service/solana/AbstractSolanaCommitmentsSnapshotService.ts
var s = class extends o {
	constructor(e) {
		super(e, "NewCommitment");
	}
	_merkleTree;
	_encryptedOutputs;
	_encryptedOutputsByCommitment = /* @__PURE__ */ new Map();
	get merkleTree() {
		return this._merkleTree;
	}
	get encryptedOutputs() {
		return this._encryptedOutputs;
	}
	serializeSnapshot(e) {
		return {
			merkleTree: e.payload.merkleTree.toJSON(),
			latestBlockNumber: e.latestBlockNumber,
			encryptedOutputs: e.payload.encryptedOutputs.map((e) => ({
				value: e.value,
				isPositive: String(e.isPositive),
				isBlocked: e.isBlocked ?? !1
			})),
			encryptedOutputsByCommitment: Array.from(e.payload.encryptedOutputsByCommitment.entries()).map(([e, t]) => ({
				commitment: e.toString(),
				encryptedOutput: t
			}))
		};
	}
	deserializeSnapshot(e) {
		let n;
		n = e.latestBlockNumber && e.merkleTree ? a(e.merkleTree) : i.create(t, 0n);
		let r = e.encryptedOutputs?.map((e) => ({
			value: e.value,
			isPositive: JSON.parse(e.isPositive),
			isBlocked: e.isBlocked ?? !1
		})), o = /* @__PURE__ */ new Map();
		return e.encryptedOutputsByCommitment?.forEach(({ commitment: e, encryptedOutput: t }) => {
			o.set(BigInt(e), t);
		}), {
			latestBlockNumber: e.latestBlockNumber ?? 0,
			payload: {
				merkleTree: n,
				encryptedOutputs: r || [],
				encryptedOutputsByCommitment: o
			}
		};
	}
	getSnapshotPayload() {
		return {
			merkleTree: this._merkleTree,
			encryptedOutputs: this._encryptedOutputs,
			encryptedOutputsByCommitment: this._encryptedOutputsByCommitment
		};
	}
	populateSnapshot({ payload: { merkleTree: e, encryptedOutputs: t, encryptedOutputsByCommitment: n } }) {
		this._merkleTree = e, this._encryptedOutputs = t, this._encryptedOutputsByCommitment = n;
	}
	async mapEvent(t) {
		let r = t.getArg("commitment"), i = t.getArg("index"), a = t.getArg("encrypted_output"), o = t.getArg("on_chain_data"), s = e(r), c = e(i);
		return a.length === 0 ? {
			commitment: s,
			index: c,
			encryptedOutput: n(o)
		} : {
			commitment: s,
			index: c,
			encryptedOutput: `0x${Buffer.from(a).toString("hex")}`
		};
	}
	acceptEvent(e, t, n, i) {
		let a = e.index >= 0n ? e.index : -1n * e.index, o = this._merkleTree.getValue(a);
		if (o === e.commitment) return !1;
		this._merkleTree.insert(e.commitment, a);
		let s = o === void 0 ? void 0 : this._encryptedOutputsByCommitment.get(o);
		if (o !== void 0 && s !== void 0) {
			let e = this.encryptedOutputs.findIndex((e) => e.value === s);
			e !== -1 && this.encryptedOutputs.splice(e, 1), this._encryptedOutputsByCommitment.delete(o);
		}
		if (this._encryptedOutputsByCommitment.set(e.commitment, e.encryptedOutput), this.encryptedOutputs.map((e) => e.value).includes(e.encryptedOutput)) return !0;
		let c = {
			value: e.encryptedOutput,
			isPositive: !r(e.encryptedOutput),
			isBlocked: i ?? !1
		};
		return this._encryptedOutputs.push(c), !0;
	}
};
//#endregion
export { s as AbstractSolanaCommitmentsSnapshotService };
