"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CorporateActionBase = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const internal_1 = require("../../../internal");
const types_1 = require("../../../types");
const conversion_1 = require("../../../utils/conversion");
const internal_2 = require("../../../utils/internal");
/**
 * Represents an action initiated by the issuer of an Asset which may affect the positions of
 *   the Asset Holders
 */
class CorporateActionBase extends internal_1.Entity {
    /**
     * @hidden
     */
    constructor(args, context) {
        const { kind, declarationDate, targets, description, defaultTaxWithholding, taxWithholdings } = args, identifiers = __rest(args, ["kind", "declarationDate", "targets", "description", "defaultTaxWithholding", "taxWithholdings"]);
        super(identifiers, context);
        const { id, ticker } = identifiers;
        this.id = id;
        this.asset = new internal_1.Asset({ ticker }, context);
        this.kind = kind;
        this.declarationDate = declarationDate;
        this.description = description;
        this.targets = targets;
        this.defaultTaxWithholding = defaultTaxWithholding;
        this.taxWithholdings = taxWithholdings;
        this.linkDocuments = (0, internal_2.createProcedureMethod)({ getProcedureAndArgs: procedureArgs => [internal_1.linkCaDocs, Object.assign({ id, ticker }, procedureArgs)] }, context);
    }
    /**
     * @hidden
     * Check if a value is of type {@link UniqueIdentifiers}
     */
    static isUniqueIdentifiers(identifier) {
        const { id, ticker } = identifier;
        return id instanceof bignumber_js_1.default && typeof ticker === 'string';
    }
    /**
     * Determine whether this Corporate Action exists on chain
     */
    exists() {
        return __awaiter(this, void 0, void 0, function* () {
            const corporateAction = yield this.fetchCorporateAction();
            return corporateAction.isSome;
        });
    }
    /**
     * Retrieve the Checkpoint associated with this Corporate Action. If the Checkpoint is scheduled and has
     *   not been created yet, the corresponding CheckpointSchedule is returned instead. A null value means
     *   the Corporate Action was created without an associated Checkpoint
     */
    checkpoint() {
        return __awaiter(this, void 0, void 0, function* () {
            const { context: { polymeshApi: { query }, }, context, asset: { ticker }, } = this;
            const rawTicker = (0, conversion_1.stringToTicker)(ticker, context);
            const corporateAction = yield this.fetchCorporateAction();
            if (corporateAction.isNone) {
                throw new internal_1.PolymeshError({
                    code: types_1.ErrorCode.DataUnavailable,
                    message: 'The Corporate Action no longer exists',
                });
            }
            const { recordDate } = corporateAction.unwrap();
            if (recordDate.isNone) {
                return null;
            }
            const { checkpoint } = recordDate.unwrap();
            if (checkpoint.isExisting) {
                return new internal_1.Checkpoint({ ticker, id: (0, conversion_1.u64ToBigNumber)(checkpoint.asExisting) }, context);
            }
            const [scheduleId, amount] = checkpoint.asScheduled;
            const [schedules, schedulePoints] = yield Promise.all([
                query.checkpoint.schedules(rawTicker),
                query.checkpoint.schedulePoints(rawTicker, scheduleId),
            ]);
            const createdCheckpointIndex = (0, conversion_1.u64ToBigNumber)(amount).toNumber();
            if (createdCheckpointIndex >= schedulePoints.length) {
                // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                const schedule = schedules.find(({ id: schedId }) => (0, conversion_1.u64ToBigNumber)(schedId).eq((0, conversion_1.u64ToBigNumber)(scheduleId)));
                return new internal_1.CheckpointSchedule(Object.assign({ ticker }, (0, conversion_1.storedScheduleToCheckpointScheduleParams)(schedule)), context);
            }
            return new internal_1.Checkpoint({ ticker, id: (0, conversion_1.u64ToBigNumber)(schedulePoints[createdCheckpointIndex]) }, context);
        });
    }
    /**
     * @hidden
     */
    fetchCorporateAction() {
        const { context: { polymeshApi: { query }, }, context, id, asset: { ticker }, } = this;
        const rawTicker = (0, conversion_1.stringToTicker)(ticker, context);
        return query.corporateAction.corporateActions(rawTicker, (0, conversion_1.bigNumberToU32)(id, context));
    }
    /**
     * Return the Corporate Action's static data
     */
    toHuman() {
        const { asset, id, declarationDate, description, targets, defaultTaxWithholding, taxWithholdings, } = this;
        return (0, internal_2.toHumanReadable)({
            ticker: asset,
            id,
            declarationDate,
            defaultTaxWithholding,
            taxWithholdings,
            targets,
            description,
        });
    }
}
exports.CorporateActionBase = CorporateActionBase;
//# sourceMappingURL=index.js.map