import { toPurchaseReceiptAccount } from '../accounts.mjs';
import { PurchaseReceiptGpaBuilder } from '../gpaBuilders/PurchaseReceiptGpaBuilder.mjs';
import { useOperation } from '../../../types/Operation.mjs';
import { UnreachableCaseError } from '../../../errors/SdkError.mjs';
import { toLazyPurchase } from '../models/Purchase.mjs';

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

const Key = 'FindPurchasesByPublicKeyOperation';

/**
 * Finds multiple Purchases by specific criteria.
 *
 * ```ts
 * // Find purchases by seller.
 * const purchases = await metaplex
 *   .auctionHouse()
 *   .findPurchasesBy({ auctionHouse, type: 'seller', publicKey: seller };
 *
 * // Find purchases by buyer.
 * const purchases = await metaplex
 *   .auctionHouse()
 *   .findPurchasesBy({ auctionHouse, type: 'buyer', publicKey: buyer };
 *
 * // Find purchases by metadata.
 * const purchases = await metaplex
 *   .auctionHouse()
 *   .findPurchasesBy({ auctionHouse, type: 'metadata', publicKey: metadata };
 *
 * // Find purchases by mint.
 * const purchases = await metaplex
 *   .auctionHouse()
 *   .findPurchasesBy({ auctionHouse, type: 'mint', publicKey: mint };
 * ```
 *
 * @group Operations
 * @category Constructors
 */
const findPurchasesByPublicKeyFieldOperation = useOperation(Key);

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

/**
 * @group Operations
 * @category Handlers
 */
const findPurchasesByPublicKeyFieldOperationHandler = {
  handle: async (operation, metaplex, scope) => {
    const {
      programs,
      commitment
    } = scope;
    const {
      auctionHouse,
      type,
      publicKey
    } = operation.input;
    const auctionHouseProgram = metaplex.programs().getAuctionHouse();
    let purchaseQuery = new PurchaseReceiptGpaBuilder(metaplex, auctionHouseProgram.address).mergeConfig({
      commitment
    }).whereAuctionHouse(auctionHouse.address);
    switch (type) {
      case 'buyer':
        purchaseQuery = purchaseQuery.whereBuyer(publicKey);
        break;
      case 'seller':
        purchaseQuery = purchaseQuery.whereSeller(publicKey);
        break;
      case 'metadata':
        purchaseQuery = purchaseQuery.whereMetadata(publicKey);
        break;
      case 'mint':
        purchaseQuery = purchaseQuery.whereMetadata(metaplex.nfts().pdas().metadata({
          mint: publicKey,
          programs
        }));
        break;
      default:
        throw new UnreachableCaseError(type);
    }
    scope.throwIfCanceled();
    return purchaseQuery.getAndMap(account => toLazyPurchase(toPurchaseReceiptAccount(account), auctionHouse));
  }
};

export { findPurchasesByPublicKeyFieldOperation, findPurchasesByPublicKeyFieldOperationHandler };
//# sourceMappingURL=findPurchasesByPublicKeyField.mjs.map
