import CalculationStore from 'client/stores/CalculationStore';
import { pipe } from 'core/tools/func';
import { ICalculationStore } from 'core/types/Calculation/Store';
import { Process } from 'core/types/Calculation/Store/process';
import { difference } from 'lodash';
import { reaction } from 'mobx';

export default function ($calculation: ICalculationStore) {
  reaction(
    () => ({
      product: $calculation.getOption('selectProduct'),
      subsidy: $calculation.getOption('selectSubsidy'),
      importProgram: $calculation.getOption('selectImportProgram'),
    }),
    ({ product, subsidy, importProgram }) => {
      /**
     * 
     * @description
     #1
    * DYN-190 При выборе значения в поле selectSubsidy необходимо добавить 
    * фильтрацию в полях при условии что selectSubsidy не равно null:

    Тип предмета лизинга selectLeaseObjectType
    если с записью  Субсидия нет связанных Типов предмета лизинга, 
    то указываются все записи согласно текущей фильтрации, 
    иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectSubsidy

    #2
    * На изменение поля Продукт selectProduct  добавляем фильтрацию списков:
    в поле Тип предмета лизинга selectLeaseObjectType - указываются те, которые связаны с продуктом. 
    Если с Продуктом нет связанных Типов предмета лизинга, 
    то указывается весь список. Это надо добавить в текущие условия фильтрации данного поля

    #3
    Тип предмета лизинга selectLeaseObjectType
    если с записью  Субсидия нет связанных Типов предмета лизинга,
    то указываются все записи согласно текущей фильтрации, 
    иначе указываются те записи, которые связаны с Субсидией, указанной в поле selectImportProgram
    */
      $calculation.setFilter('selectLeaseObjectType', types =>
        types.filter(
          pipe(
            leasingObjectType =>
              (!product?.evo_leasingobject_types?.length ||
                product.evo_leasingobject_types.filter(
                  x =>
                    x.evo_leasingobject_typeid ===
                    leasingObjectType?.evo_leasingobject_typeid,
                )?.length) &&
              leasingObjectType,
            leasingObjectType =>
              //@ts-ignore
              leasingObjectType &&
              (!subsidy?.evo_leasingobject_types?.length ||
                subsidy.evo_leasingobject_types.filter(
                  x =>
                    x.evo_leasingobject_typeid ===
                    leasingObjectType.evo_leasingobject_typeid,
                )?.length) &&
              leasingObjectType,
            leasingObjectType =>
              //@ts-ignore
              leasingObjectType &&
              (!importProgram?.evo_leasingobject_types?.length ||
                importProgram.evo_leasingobject_types.filter(
                  x =>
                    x.evo_leasingobject_typeid ===
                    leasingObjectType.evo_leasingobject_typeid,
                )?.length),
          ),
        ),
      );

      $calculation.setFilter('selectDealer', dealers =>
        dealers.filter(
          pipe(
            dealer =>
              (!subsidy?.accounts?.length ||
                subsidy.accounts.filter(x => x.accountid === dealer.accountid)
                  ?.length) &&
              dealer,
            dealer =>
              //@ts-ignore
              !importProgram?.accounts?.length ||
              importProgram.accounts.filter(
                //@ts-ignore
                x => x.accountid === dealer.accountid,
              )?.length,
          ),
        ),
      );

      $calculation.setFilter('selectDealerPerson', dealerPersons =>
        dealerPersons.filter(
          pipe(
            dealerPerson =>
              (!subsidy?.accounts?.length ||
                subsidy.accounts.filter(
                  x => x.accountid === dealerPerson.accountid,
                )?.length) &&
              dealerPerson,
            dealerPerson =>
              //@ts-ignore
              !importProgram?.accounts?.length ||
              importProgram.accounts.filter(
                //@ts-ignore
                x => x.accountid === dealerPerson.accountid,
              )?.length,
          ),
        ),
      );
    },
  );

  reaction(
    () => $calculation.getOption('selectTarif'),
    tarif => {
      /**
       * @description
       * На изменение поля Тариф selectTarif добавляем фильрацию в полях:
          в поле Вид графика radioGraphType должны закрываться значения для выбора,
          которые указаны в массиве поля "Недопустимые виды графиков" evo_graphtype_exception. 
          Если в массиве пусто, значит допустимы все значения
       */

      const graphTypes = $calculation.getOptions('radioGraphType');
      const filteredGraphTypes = graphTypes?.map(type => ({
        ...type,
        disabled: tarif?.evo_graphtype_exception?.includes(type.value),
      }));
      $calculation.setOptions(
        'radioGraphType',
        //@ts-ignore
        filteredGraphTypes,
      );
      if (!$calculation.stores.calculationProcess.hasProcess(Process.LoadKp)) {
        const graphTypeValue = $calculation.getValue('graphType');
        if (
          !filteredGraphTypes
            ?.filter(x => !x.disabled)
            ?.map(x => x.value)
            .includes(graphTypeValue)
        )
          CalculationStore.setValue('graphType', null);
      }
    },
  );

  /**
   * @description
   * в поле Тип дегрессии/сезонности selectSeasonType должны отображаться только те значения,
   * которых нет в массиве поля "Недопустимые Типы дегрессий/сезонности" evo_seasons_type_exception
   * (добавить в текущую фильтрацию поля)
   */
  reaction(
    () => {
      return {
        tarif: $calculation.getOption('selectTarif'),
        graphType: $calculation.getOption('radioGraphType'),
      };
    },
    ({ tarif, graphType }) => {
      const exeption = tarif?.evo_seasons_type_exception || [];
      const includes = graphType?.seasonTypes;

      const targetValues = difference(includes, exeption);

      $calculation.setFilter('selectSeasonType', options =>
        options.filter(x => targetValues.includes(x.value)),
      );
    },
  );

  /**
   * @description
   * При изменении Продукта selectProduct необходимо в поле "Расчет от"
   * radioCalcType фильтровать значения согласно списку
   * в поле "Доступные Методы расчета в калькуляторе" evo_calculation_method в selectProduct
   */
  reaction(
    () => $calculation.values.product,
    productId => {
      const product = $calculation.getOption('selectProduct', {
        evo_id: productId,
      });
      if (product?.evo_calculation_method) {
        $calculation.setFilter('radioCalcType', calcType =>
          calcType.filter(x =>
            product.evo_calculation_method?.includes(x.value),
          ),
        );
      } else {
        /**
         * Это фильтр по-умолчанию
         * TODO: Добавить его в дефолтные фильтры
         */
        $calculation.setFilter('radioCalcType', calcType =>
          calcType.filter(x => [100_000_000, 100_000_001].includes(x.value)),
        );
        $calculation.setValue('calcType', 100_000_000);
      }
    },
    { fireImmediately: true },
  );

  /**
   * @description
   * Добавить фильтр для поля selectProduct (работает на загрузку КП)
   * если  recalcWithRevision=True, то в списке поля selectProduct должны отображаться
   * записи quote.evo_baseproductid из поля Предложение selectQuote + дать возможность выбирать продукт,
   * связанный с оquote.evo_baseproductid из поля Предложение selectQuote по связи evo_evo_baseproduct_evo_baseproduct
   */
  reaction(
    () => $calculation.values.quote,
    quoteid => {
      if ($calculation.getValue('recalcWithRevision')) {
        const quote = $calculation.getOption('selectQuote', { quoteid });
        const quote_product = $calculation.getOption('selectProduct', {
          evo_baseproductid: quote?.evo_baseproductid,
        });
        $calculation.setFilter('selectProduct', products =>
          products.filter(product =>
            quote_product?.evo_baseproducts
              ?.map(x => x.evo_baseproductid)
              .concat(quote?.evo_baseproductid)
              .includes(product.evo_baseproductid),
          ),
        );
      } else {
        $calculation.setFilter('selectProduct', undefined);
      }
    },
  );
}
