import { EndSettingType, } from '@metaplex-solarti/mpl-candy-machine';
import { countCandyMachineV2Items, getCandyMachineV2UuidFromAddress, parseCandyMachineV2Items, } from '../helpers';
import { CandyMachineV2Program } from '../program';
import { amount, lamports, SOL, toBigNumber, toDateTime, toOptionDateTime, } from '../../../types';
import { assert, removeEmptyChars } from '../../../utils';
// -----------------
// Program to Model
// -----------------
/** @group Model Helpers */
export const isCandyMachineV2 = (value) => typeof value === 'object' && value.model === 'candyMachineV2';
/** @group Model Helpers */
export function assertCandyMachineV2(value) {
    assert(isCandyMachineV2(value), 'Expected CandyMachineV2 type');
}
/** @group Model Helpers */
export const toCandyMachineV2 = (account, unparsedAccount, collectionAccount, mint) => {
    assert(mint === null ||
        (account.data.tokenMint !== null &&
            mint.address.equals(account.data.tokenMint)));
    const itemsAvailable = toBigNumber(account.data.data.itemsAvailable);
    const itemsMinted = toBigNumber(account.data.itemsRedeemed);
    const { endSettings } = account.data.data;
    const { hiddenSettings } = account.data.data;
    const { whitelistMintSettings } = account.data.data;
    const { gatekeeper } = account.data.data;
    const rawData = unparsedAccount.data;
    const itemsLoaded = hiddenSettings
        ? toBigNumber(0)
        : countCandyMachineV2Items(rawData);
    const items = hiddenSettings ? [] : parseCandyMachineV2Items(rawData);
    return {
        model: 'candyMachineV2',
        address: account.publicKey,
        programAddress: account.owner,
        version: account.owner.equals(CandyMachineV2Program.publicKey) ? 2 : 1,
        authorityAddress: account.data.authority,
        walletAddress: account.data.wallet,
        tokenMintAddress: account.data.tokenMint,
        collectionMintAddress: collectionAccount && collectionAccount.exists
            ? collectionAccount.data.mint
            : null,
        uuid: account.data.data.uuid,
        price: amount(account.data.data.price, mint ? mint.currency : SOL),
        symbol: removeEmptyChars(account.data.data.symbol),
        sellerFeeBasisPoints: account.data.data.sellerFeeBasisPoints,
        isMutable: account.data.data.isMutable,
        retainAuthority: account.data.data.retainAuthority,
        goLiveDate: toOptionDateTime(account.data.data.goLiveDate),
        maxEditionSupply: toBigNumber(account.data.data.maxSupply),
        items,
        itemsAvailable,
        itemsMinted,
        itemsRemaining: toBigNumber(itemsAvailable.sub(itemsMinted)),
        itemsLoaded,
        isFullyLoaded: itemsAvailable.lte(itemsLoaded),
        // eslint-disable-next-line no-nested-ternary
        endSettings: endSettings
            ? endSettings.endSettingType === EndSettingType.Date
                ? {
                    endSettingType: EndSettingType.Date,
                    date: toDateTime(endSettings.number),
                }
                : {
                    endSettingType: EndSettingType.Amount,
                    number: toBigNumber(endSettings.number),
                }
            : null,
        hiddenSettings,
        whitelistMintSettings: whitelistMintSettings
            ? Object.assign(Object.assign({}, whitelistMintSettings), { discountPrice: whitelistMintSettings.discountPrice
                    ? lamports(whitelistMintSettings.discountPrice)
                    : null }) : null,
        gatekeeper: gatekeeper
            ? Object.assign(Object.assign({}, gatekeeper), { network: gatekeeper.gatekeeperNetwork }) : null,
        creators: account.data.data.creators,
    };
};
/** @group Model Helpers */
export const toCandyMachineV2Configs = (candyMachine) => {
    return Object.assign({ wallet: candyMachine.walletAddress, tokenMint: candyMachine.tokenMintAddress }, candyMachine);
};
/** @group Model Helpers */
export const toCandyMachineV2InstructionData = (address, configs) => {
    var _a, _b;
    const { endSettings } = configs;
    const { whitelistMintSettings } = configs;
    const { gatekeeper } = configs;
    return {
        wallet: configs.wallet,
        tokenMint: configs.tokenMint,
        data: Object.assign(Object.assign({}, configs), { uuid: getCandyMachineV2UuidFromAddress(address), price: configs.price.basisPoints, maxSupply: configs.maxEditionSupply, endSettings: endSettings
                ? Object.assign(Object.assign({}, endSettings), { number: endSettings.endSettingType === EndSettingType.Date
                        ? endSettings.date
                        : endSettings.number }) : null, whitelistMintSettings: whitelistMintSettings
                ? Object.assign(Object.assign({}, whitelistMintSettings), { discountPrice: (_b = (_a = whitelistMintSettings.discountPrice) === null || _a === void 0 ? void 0 : _a.basisPoints) !== null && _b !== void 0 ? _b : null }) : null, gatekeeper: gatekeeper
                ? Object.assign(Object.assign({}, gatekeeper), { gatekeeperNetwork: gatekeeper.network }) : null }),
    };
};
//# sourceMappingURL=CandyMachineV2.js.map