"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCustomAccount = void 0;
const types_1 = require("@polkadot/types");
const operators_1 = require("rxjs/operators");
const util_1 = require("@equilab/api/genshiro/util");
const bn_js_1 = __importDefault(require("bn.js"));
const transformBalanceStorage = (query, arg, transform) => {
    // HACK as we cannot properly transform queryMulti result, define AccountData getters on standard Enum
    if (!types_1.Enum.hacked) {
        types_1.Enum.hacked = true;
        for (const prop of ["free", "reserved", "miscFrozen", "feeFrozen"]) {
            Object.defineProperty(types_1.Enum.prototype, prop, {
                get() {
                    const accData = transform(this);
                    return accData[prop];
                },
                set() {
                    // Do nothing
                },
            });
        }
    }
    // Transform result if we call the func normally
    const boundFunction = (account) => 
    //@ts-ignore
    query(account, { 0: (0, util_1.u64FromCurrency)(arg) }).pipe((0, operators_1.map)(transform));
    // Bind currency as second key for doubleMap for queryMulti
    const boundCreator = (account) => query.creator([account, { 0: (0, util_1.u64FromCurrency)(arg) }]);
    Object.assign(boundCreator, { ...query.creator });
    return Object.assign(boundFunction, {
        ...query,
        creator: boundCreator,
    });
};
const signedBalancePredicate = (raw) => ["asNegative", "asPositive", "isNegative", "isPositive"].some((key) => Object.prototype.hasOwnProperty.call(raw, key));
const createCustomAccount = (cur) => (instanceId, api) => {
    const registry = api.registry;
    const transform = (balance) => {
        let free = registry.createType("Balance");
        const reserved = registry.createType("Balance");
        const miscFrozen = registry.createType("Balance");
        const feeFrozen = registry.createType("Balance");
        if (signedBalancePredicate(balance)) {
            if (balance.isPositive) {
                free = registry.createType("Balance", balance.asPositive);
            }
            else if (balance.isNegative) {
                free = registry.createType("Balance", balance.asNegative.mul(new bn_js_1.default(-1)));
            }
        }
        return registry.createType("AccountData", {
            feeFrozen,
            free,
            miscFrozen,
            reserved,
        });
    };
    return transformBalanceStorage(api.query.eqBalances.account, cur, transform);
};
exports.createCustomAccount = createCustomAccount;
