import BigNumber from "bignumber.js";
import { Market } from "./interfaces/market.interface";
import { AggregatedPool } from "./interfaces/aggregated-pool.interface";

export const getAggregatedPoolsDistributionOrder = (market: Market) => {
  const aggregatedPoolSet: Partial<Record<string, AggregatedPool>> = (market.aggregatedPools || []).reduce((acc, aggregatedPool) => {
    acc[aggregatedPool.id] = aggregatedPool;
    return acc;
  }, {});

  const aggregatedPools: AggregatedPool[] = [];

  if (aggregatedPoolSet[market.headAggregatedPoolId]) {
    aggregatedPools.push(aggregatedPoolSet[market.headAggregatedPoolId]!);
  }

  let cursor = aggregatedPools[0]?.nextAggregatedPoolId || "0";

  while (cursor !== "0" && aggregatedPoolSet[cursor]) {
    const aggregatedPool = aggregatedPoolSet[cursor]!;
    aggregatedPools.push(aggregatedPool);
    cursor = aggregatedPool.nextAggregatedPoolId;
  }

  return aggregatedPools;
};

export const getDistributedAggregatedPoolsPayoutOrder = (market: Market) => {
  const aggregatedPools: AggregatedPool[] = getAggregatedPoolsDistributionOrder(market);
  const aggregatedPoolsExtended: AggregatedPool[] = [];
  let remainder = new BigNumber(market.desiredCover);

  for (let i = 0; i < aggregatedPools.length; i++) {
    if (remainder.isZero()) {
      break;
    }

    const aggregatedPool = aggregatedPools[i];
    const cover = BigNumber.min(aggregatedPool.totalCapacity, remainder);

    const aggregatedPoolExtended: AggregatedPool = { ...aggregatedPool, totalCover: cover.toFixed(0) };

    if (aggregatedPool.id === market.headAggregatedPoolId) {
      aggregatedPoolsExtended.push(aggregatedPoolExtended);
    } else {
      aggregatedPoolsExtended.splice(1, 0, aggregatedPoolExtended);
    }

    remainder = remainder.minus(cover);
  }

  return aggregatedPoolsExtended;
};
