import {
  Data,
  LucidEvolution,
  OutRef,
  slotToUnixTime,
  TxBuilder,
} from '@lucid-evolution/lucid';
import {
  serialisePriceOracleDatum,
  serialisePriceOracleRedeemer,
} from '../../src/contracts/price-oracle/types-new';
import { PriceOracleParams } from '../../src/contracts/price-oracle/types';
import { mkPriceOracleValidator } from '../../src/contracts/price-oracle/scripts';
import { matchSingle } from '../../src/utils/utils';
import { ONE_SECOND } from '../../src/utils/time-helpers';
import * as Core from '@evolution-sdk/evolution';
import { mkLovelacesOf } from '@3rd-eye-labs/cardano-offchain-common';
import { Rational } from '../../src/types/rational';

export async function feedPriceOracleTxStealNft(
  lucid: LucidEvolution,
  oracleOref: OutRef,
  newPrice: Rational,
  oracleParams: PriceOracleParams,
  currentSlot: number,
): Promise<TxBuilder> {
  const network = lucid.config().network!;
  const currentTime = BigInt(slotToUnixTime(network, currentSlot));

  const priceOracleUtxo = matchSingle(
    await lucid.utxosByOutRef([oracleOref]),
    (_) => new Error('Expected a single price oracle UTXO'),
  );

  const oracleValidator = mkPriceOracleValidator(oracleParams);

  return lucid
    .newTx()
    .validFrom(Number(currentTime - oracleParams.biasTime) + ONE_SECOND)
    .validTo(Number(currentTime + oracleParams.biasTime) - ONE_SECOND)
    .attach.SpendingValidator(oracleValidator)
    .collectFrom(
      [priceOracleUtxo],
      serialisePriceOracleRedeemer({
        currentTime: currentTime,
        newPrice: newPrice,
      }),
    )
    .pay.ToContract(
      priceOracleUtxo.address,
      {
        kind: 'inline',
        value: serialisePriceOracleDatum({
          price: newPrice,
          expirationTime: currentTime + oracleParams.expirationPeriod,
          auxiliaryData: Core.Data.fromCBORHex(Data.void()),
        }),
      },
      mkLovelacesOf(5_000_000n),
    )
    .addSignerKey(oracleParams.owner);
}
