import { Assets, Data, UTxO } from '@lucid-evolution/lucid';
import {
  fromSystemParamsAsset,
  SystemParams,
} from '../../src/types/system-params';
import { LucidContext, runAndAwaitTxBuilder } from '../test-helpers';
import { createScriptAddress } from '../../src/utils/lucid-utils';
import { getNewUtxosAtAddressAfterAction } from '../utils';
import { matchSingle, mkAssetsOf } from '@3rd-eye-labs/cardano-offchain-common';

export async function createMultipleUtxosAtTreasury(
  assets: Assets,
  numberUtxos: bigint,
  sysParams: SystemParams,
  context: LucidContext,
): Promise<UTxO[]> {
  const treasuryAddr = createScriptAddress(
    context.lucid.config().network!,
    sysParams.validatorHashes.treasuryHash,
  );

  const tx = context.lucid.newTx();

  for (let i = 0; i < numberUtxos; i++) {
    tx.pay.ToContract(
      treasuryAddr,
      { kind: 'inline', value: Data.void() },
      assets,
    );
  }

  const [_, utxos] = await getNewUtxosAtAddressAfterAction(
    context.lucid,
    treasuryAddr,
    () => runAndAwaitTxBuilder(context.lucid, tx),
  );

  if (utxos.length !== Number(numberUtxos)) {
    new Error('Expected a different number of new treasury UTxOs');
  }

  return utxos;
}

export async function createUtxoAtTreasury(
  assets: Assets,
  sysParams: SystemParams,
  context: LucidContext,
): Promise<UTxO> {
  const utxos = await createMultipleUtxosAtTreasury(
    assets,
    1n,
    sysParams,
    context,
  );

  return matchSingle(utxos, () => new Error('Expected a single treasury UTXO'));
}

export async function createIndyUtxoAtTreasury(
  indyAmt: bigint,
  sysParams: SystemParams,
  context: LucidContext,
): Promise<UTxO> {
  return createUtxoAtTreasury(
    mkAssetsOf(fromSystemParamsAsset(sysParams.govParams.indyAsset), indyAmt),
    sysParams,
    context,
  );
}
