import leasebackReactions from 'client/process/agents/leaseback';
import agentsReactions from 'client/process/agents/reactions';
import injectBonusesReaction from 'client/process/bonuses/reactions';
import { injectConfiguratorReactions } from 'client/process/configurator/reactions';
import { injectFinGapReactions } from 'client/process/fingap/reactions';
import injectSubsidyReactions from 'client/process/subsidy-import-program/reactions';
import injectUsedWhthVATReactions from 'client/process/used-pl/reactions';
import { ICalculationStore } from 'core/types/Calculation/Store';
import { isEqual } from 'lodash';
import { autorun, makeAutoObservable, reaction, when } from 'mobx';
import staticData from './Data/static';
import tables from './Data/tables';
import values from './Data/values';
import autorunEffects from './Effects/autorun';
import computedEffects from './Effects/computed';
import reactionEffects from './Effects/reactions';
import whenEffects from './Effects/when';
import init from './init';
import subStores from './subStores';

const { calculationProcess } = subStores;

const CalculationStore: ICalculationStore = makeAutoObservable(
  Object.assign({ init }, staticData, values, tables, computedEffects, {
    stores: subStores,
  }),
);

autorunEffects.map(autorunEffect => autorun(autorunEffect(CalculationStore)));

reactionEffects.map(reactionEffectBuilder => {
  const reactionEffect = reactionEffectBuilder(
    CalculationStore,
    calculationProcess,
  );
  return reaction(reactionEffect.expression, reactionEffect.effect, {
    ...reactionEffect.options,
    equals:
      reactionEffect.options?.equals ||
      ((nextParams, prevParams) => isEqual(nextParams, prevParams)),
  });
});
injectFinGapReactions(CalculationStore);
injectUsedWhthVATReactions(CalculationStore);
injectConfiguratorReactions(CalculationStore);
injectSubsidyReactions(CalculationStore);
injectBonusesReaction(CalculationStore);
agentsReactions(CalculationStore);
leasebackReactions(CalculationStore);

whenEffects.map(whenEffectBuilder => {
  const whenEffect = whenEffectBuilder(CalculationStore);
  return when(whenEffect.predicate, whenEffect.effect);
});

export default CalculationStore;
