import { LucidEvolution, ScriptHash, UTxO } from '@lucid-evolution/lucid';
import { createScriptAddress, matchSingle } from '../../src';
import { option as O, array as A, function as F } from 'fp-ts';
import {
  AssetClass,
  assetClassToUnit,
} from '@3rd-eye-labs/cardano-offchain-common';
import {
  ExecuteDatum,
  parseExecuteDatum,
} from '../../src/contracts/execute/types-new';

export async function findExecute(
  lucid: LucidEvolution,
  executeHash: ScriptHash,
  executeNft: AssetClass,
  upgradeId: bigint,
): Promise<{
  utxo: UTxO;
  datum: ExecuteDatum;
}> {
  const executeUtxos = await lucid.utxosAtWithUnit(
    createScriptAddress(lucid.config().network!, executeHash),
    assetClassToUnit(executeNft),
  );

  return matchSingle(
    F.pipe(
      executeUtxos.map((utxo) =>
        F.pipe(
          O.fromNullable(utxo.datum),
          O.flatMap(parseExecuteDatum),
          O.flatMap((datum) => {
            if (datum.id === upgradeId) {
              return O.some({ utxo, datum: datum });
            } else {
              return O.none;
            }
          }),
        ),
      ),
      A.compact,
    ),
    (res) =>
      new Error('Expected a single Execute UTXO.: ' + JSON.stringify(res)),
  );
}
