import { constructContinueTx, NewTx, passCwebFrom, sendCwebInterface } from '@coinweb/contract-kit';

import { context, getRawContext } from '../../context';
import { getAwaitedTasks } from '../../promisifiedOps';

import { prepareInThreadTxs } from './prepareInThreadTxs';
import { prepareOutThreadTxs } from './prepareOutThreadTxs';
import { splitTasks } from './splitTasks';

export const prepareTx = (isFullyExecuted: boolean, callsCount?: number): { txs: NewTx[]; calls: number } => {
  console.log('Calls Count: ', callsCount);

  const awaitedTasks = getAwaitedTasks();

  console.log('Awaited Tasks: ', JSON.stringify(awaitedTasks));

  if (!awaitedTasks.length) {
    if (context.isChild) {
      return { txs: [], calls: 0 };
    }

    const { constructSendCweb } = sendCwebInterface();
    const { availableCweb, takeOps, storedCweb } = context.funds;
    const { user } = context;

    const restOfCweb = availableCweb + storedCweb - BigInt(takeOps.length) * 100n - 3000n;

    const txs =
      restOfCweb > 0n
        ? [
            constructContinueTx(getRawContext(), [
              passCwebFrom(context.issuer, availableCweb),
              ...takeOps,
              ...constructSendCweb(restOfCweb, user, null),
            ]),
          ]
        : [];

    return { txs, calls: 0 };
  }

  const { inThreadTasks, outThreadTasks } = splitTasks(awaitedTasks, isFullyExecuted);

  const { availableCweb } = context.funds;

  const cwebPerCall = availableCweb / BigInt(callsCount || 1);
  const {
    txs: outThreadTxs,
    fee: outThreadFee,
    calls: outThreadCallsPrepared,
  } = prepareOutThreadTxs({ tasks: outThreadTasks, cwebPerCall });

  const { txs: inThreadTxs, calls: inThreadCallsPrepared } = prepareInThreadTxs({
    tasks: inThreadTasks,
    cwebPerCall,
    outThreadTasksCount: outThreadTasks.length,
    outThreadFee,
  });

  return { txs: [...inThreadTxs, ...outThreadTxs], calls: inThreadCallsPrepared + outThreadCallsPrepared };
};
