import { match, P } from 'ts-pattern';
import { CDPContent } from '../../src/contracts/cdp/types-new';
import { calculateAccruedInterest } from '../../src/contracts/interest-oracle/helpers';
import { LucidContext } from '../test-helpers';
import { slotToUnixTime, toHex, toText } from '@lucid-evolution/lucid';
import { findCollateralAsset } from '../queries/iasset-queries';
import {
  fromSystemParamsAsset,
  getInlineDatumOrThrow,
  SystemParams,
} from '../../src';
import { findInterestOracle } from '../queries/interest-oracle-queries';
import { parseInterestOracleDatum } from '../../src/contracts/interest-oracle/types-new';

export async function calculateCdpInterest(
  cdp: CDPContent,
  context: LucidContext,
  sysParams: SystemParams,
): Promise<bigint> {
  const currentTime = BigInt(
    slotToUnixTime(context.lucid.config().network!, context.emulator.slot),
  );

  const collateralAsset = await findCollateralAsset(
    context.lucid,
    sysParams,
    fromSystemParamsAsset(sysParams.cdpParams.collateralAssetAuthToken),
    toText(toHex(cdp.iasset)),
    cdp.collateralAsset,
  );

  const interestOracleUtxo = await findInterestOracle(
    context.lucid,
    collateralAsset.datum.interestOracleNft,
  );

  const interestOracleDatum = parseInterestOracleDatum(
    getInlineDatumOrThrow(interestOracleUtxo),
  );

  return match(cdp.cdpFees)
    .with({ FrozenCDPAccumulatedFees: P.select() }, (fees) => {
      return fees.iassetInterest;
    })
    .with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
      return calculateAccruedInterest(
        currentTime,
        interest.unitaryInterestSnapshot,
        cdp.mintedAmt,
        interest.lastSettled,
        interestOracleDatum,
      );
    })
    .exhaustive();
}
