import { createUpdateInstruction, updateInstructionDiscriminator } from '@metaplex-foundation/mpl-candy-guard';
import { emptyDefaultCandyGuardSettings } from '../guards/default.mjs';
import { serializeDiscriminator } from '../../../types/Serializer.mjs';
import { TransactionBuilder } from '../../../utils/TransactionBuilder.mjs';

// -----------------
// Operation
// -----------------

const Key = 'UpdateCandyGuardOperation';

/**
 * Updates an existing Candy Guard account.
 *
 * Note that the provided `guards` and `groups`
 * will replace the existing ones.
 *
 * ```ts
 * await metaplex
 *   .candyMachines()
 *   .updateCandyGuard({
 *     candyGuard: candyGuard.address,
 *     guards: {
 *       startDate: { date: toDateTime('2022-09-05T20:00:00.000Z') },
 *       solPayment: { amount: sol(1.5), },
 *       botTax: { lamports: sol(0.01), lastInstruction: true },
 *     },
 *     groups: [],
 *   };
 * ```
 *
 * @group Operations
 * @category Constructors
 */
const updateCandyGuardOperation = _updateCandyGuardOperation;
// eslint-disable-next-line @typescript-eslint/naming-convention
function _updateCandyGuardOperation(input) {
  return {
    key: Key,
    input
  };
}
_updateCandyGuardOperation.key = Key;

/**
 * @group Operations
 * @category Types
 */

/**
 * @group Operations
 * @category Handlers
 */
const updateCandyGuardOperationHandler = {
  async handle(operation, metaplex, scope) {
    return updateCandyGuardBuilder(metaplex, operation.input, scope).sendAndConfirm(metaplex, scope.confirmOptions);
  }
};

// -----------------
// Builder
// -----------------

/**
 * @group Transaction Builders
 * @category Inputs
 */

/**
 * Updates an existing Candy Guard account.
 *
 * Note that the provided `guards` and `groups`
 * will replace the existing ones.
 *
 * ```ts
 * const transactionBuilder = metaplex
 *   .candyMachines()
 *   .builders()
 *   .updateCandyGuard({
 *     candyGuard: candyGuard.address,
 *     guards: {
 *       startDate: { date: toDateTime('2022-09-05T20:00:00.000Z') },
 *       solPayment: { amount: sol(1.5), },
 *       botTax: { lamports: sol(0.01), lastInstruction: true },
 *     },
 *     groups: [],
 *   });
 * ```
 *
 * @group Transaction Builders
 * @category Constructors
 */
const updateCandyGuardBuilder = (metaplex, params, options = {}) => {
  const {
    programs,
    payer = metaplex.rpc().getDefaultFeePayer()
  } = options;
  const {
    candyGuard,
    guards,
    groups,
    authority = metaplex.identity()
  } = params;
  const candyGuardProgram = metaplex.programs().getCandyGuard(programs);
  const updateInstruction = createUpdateInstruction({
    candyGuard,
    authority: authority.publicKey,
    payer: payer.publicKey
  }, {
    data: {
      default: emptyDefaultCandyGuardSettings,
      groups: null
    }
  }, candyGuardProgram.address);
  const serializedSettings = metaplex.candyMachines().guards().serializeSettings(guards, groups, programs);
  const discriminator = serializeDiscriminator(updateInstructionDiscriminator);
  updateInstruction.data = Buffer.concat([discriminator, serializedSettings]);
  return TransactionBuilder.make().setFeePayer(payer)

  // Update the candy guard account.
  .add({
    instruction: updateInstruction,
    signers: [authority, payer],
    key: params.updateInstructionKey ?? 'updateCandyGuard'
  });
};

export { updateCandyGuardBuilder, updateCandyGuardOperation, updateCandyGuardOperationHandler };
//# sourceMappingURL=updateCandyGuard.mjs.map
