import { openNotification } from 'client/Elements/Notification';
import valuesConstants from 'core/constants/values';
import { IReactionEffect } from 'core/types/Calculation/Store/effect';
import { Process } from 'core/types/Calculation/Store/process';
import { round } from 'lodash';
import { convertPrice } from '../../lib/tools';
import { calculatePerc, calculateRub, getPrice } from './calculate';

export default [
  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { leaseObjectPrice, supplierDiscountRub } = calculationStore.values;
      return [leaseObjectPrice, supplierDiscountRub];
    },
    effect: ([leaseObjectPrice, supplierDiscountRub = 0]) => {
      if (calculationProcess.hasProcess(Process.LoadKp)) {
        return;
      }
      calculationStore.setValue(
        'supplierDiscountPerc',
        leaseObjectPrice ? (supplierDiscountRub / leaseObjectPrice) * 100 : 0,
      );
    },
    options: {
      fireImmediately: true,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { leaseObjectPrice, supplierDiscountPerc } =
        calculationStore.values;
      return [leaseObjectPrice, supplierDiscountPerc];
    },
    effect: ([leaseObjectPrice = 0, supplierDiscountPerc = 0]) => {
      if (calculationProcess.hasProcess(Process.LoadKp)) {
        return;
      }
      calculationStore.setValue(
        'supplierDiscountRub',
        (supplierDiscountPerc * leaseObjectPrice) / 100,
      );
    },
    options: {
      fireImmediately: true,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      //@ts-ignore
      const importProgramSum = calculationStore.importProgramSum();
      const { firstPaymentRub, addEquipmentPrice } = calculationStore.values;
      return { firstPaymentRub, addEquipmentPrice, importProgramSum };
    },
    effect: ({
      firstPaymentRub = 0,
      addEquipmentPrice = 0,
      importProgramSum = 0,
    }) => {
      if (calculationProcess.hasProcess(Process.LoadKp)) {
        return;
      }
      const { supplierCurrency, leaseObjectPrice } = calculationStore.values;
      if (leaseObjectPrice) {
        const perc = calculatePerc(calculationStore)(
          supplierCurrency,
          leaseObjectPrice + addEquipmentPrice - importProgramSum,
          firstPaymentRub,
        );
        calculationStore.setValue('firstPaymentPerc', perc);
      } else {
        calculationStore.setValue('firstPaymentPerc', 0);
      }
    },
    options: {
      fireImmediately: true,
    },
  }),

  calculationStore => ({
    expression: () => {
      //@ts-ignore
      const importProgramSum = calculationStore.importProgramSum();
      const {
        supplierCurrency,
        leaseObjectPrice,
        firstPaymentPerc,
        addEquipmentPrice,
      } = calculationStore.values;
      return [
        supplierCurrency,
        leaseObjectPrice,
        firstPaymentPerc,
        addEquipmentPrice,
        importProgramSum,
      ];
    },
    effect: ([
      supplierCurrencyId,
      leaseObjectPrice = 0,
      firstPaymentPerc = 0,
      addEquipmentPrice = 0,
      importProgramSum = 0,
    ]) => {
      const rub = calculateRub(calculationStore)(
        supplierCurrencyId,
        leaseObjectPrice + addEquipmentPrice - importProgramSum,
        firstPaymentPerc,
      );

      calculationStore.setValue('firstPaymentRub', rub);
    },
    options: {
      fireImmediately: true,
      equals: () => false,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { supplierCurrency, leaseObjectPrice, comissionPerc } =
        calculationStore.values;
      return [supplierCurrency, leaseObjectPrice, comissionPerc];
    },
    effect: ([supplierCurrencyId, leaseObjectPrice = 0, comissionPerc = 0]) => {
      if (calculationProcess.hasProcess(Process.LoadKp)) {
        return;
      }
      const rub = calculateRub(calculationStore)(
        supplierCurrencyId,
        leaseObjectPrice,
        comissionPerc,
      );
      calculationStore.setValue('comissionRub', rub);
    },
    options: {
      fireImmediately: true,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { comissionRub } = calculationStore.values;
      return comissionRub;
    },
    effect: comissionRub => {
      if (calculationProcess.hasProcess(Process.LoadKp)) {
        return;
      }
      const { supplierCurrency, leaseObjectPrice } = calculationStore.values;
      if (leaseObjectPrice) {
        const perc = calculatePerc(calculationStore)(
          supplierCurrency,
          leaseObjectPrice,
          comissionRub,
        );
        calculationStore.setValue('comissionPerc', perc);
      } else {
        calculationStore.setValue('comissionPerc', 0);
      }
    },
    options: {
      fireImmediately: true,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      //@ts-ignore
      const importProgramSum = calculationStore.importProgramSum();
      const {
        supplierCurrency,
        leaseObjectPrice,
        lastPaymentPerc,
        lastPaymentRule,
        addEquipmentPrice,
      } = calculationStore.values;
      return [
        supplierCurrency,
        leaseObjectPrice,
        lastPaymentPerc,
        lastPaymentRule,
        addEquipmentPrice,
        importProgramSum,
      ];
    },
    effect: ([
      supplierCurrencyId,
      leaseObjectPrice,
      lastPaymentPerc = 0,
      lastPaymentRule,
      addEquipmentPrice = 0,
      importProgramSum = 0,
    ]) => {
      if (
        lastPaymentRule === 100000000 ||
        calculationProcess.hasProcess(Process.LoadKp)
      ) {
        return;
      }

      const rub = calculateRub(calculationStore)(
        supplierCurrencyId,
        leaseObjectPrice + addEquipmentPrice - importProgramSum,
        lastPaymentPerc,
      );
      calculationStore.setValue('lastPaymentRub', rub);
    },
    options: {
      fireImmediately: true,
    },
  }),
  (calculationStore, calculationProcess) => ({
    expression: () => {
      //@ts-ignore
      const importProgramSum = calculationStore.importProgramSum();
      const {
        supplierCurrency,
        leaseObjectPrice,
        lastPaymentRub,
        lastPaymentRule,
        addEquipmentPrice,
      } = calculationStore.values;
      return [
        supplierCurrency,
        leaseObjectPrice,
        lastPaymentRub,
        lastPaymentRule,
        addEquipmentPrice,
        importProgramSum,
      ];
    },
    effect: ([
      supplierCurrencyId,
      leaseObjectPrice,
      lastPaymentRub = 0,
      lastPaymentRule,
      addEquipmentPrice = 0,
      importProgramSum = 0,
    ]) => {
      if (
        lastPaymentRule === 100000001 ||
        calculationProcess.hasProcess(Process.LoadKp)
      ) {
        return;
      }
      if (leaseObjectPrice) {
        const perc = calculatePerc(calculationStore)(
          supplierCurrencyId,
          leaseObjectPrice + addEquipmentPrice - importProgramSum,
          lastPaymentRub,
        );
        calculationStore.setValue('lastPaymentPerc', perc);
      } else {
        calculationStore.setValue('lastPaymentPerc', 0);
      }
    },
    options: {
      fireImmediately: true,
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { supplierDiscountRub } = calculationStore.values;
      return supplierDiscountRub;
    },
    effect: supplierDiscountRub => {
      const { leaseObjectPrice } = calculationStore.values;

      const { supplierCurrency: supplierCurrencyId } = calculationStore.values;
      const price = getPrice(
        supplierCurrencyId,
        leaseObjectPrice,
        calculationStore,
      );

      if (price && price > 0 && supplierDiscountRub >= price) {
        calculationStore.setValidation('tbxSupplierDiscountRub', false);
        openNotification({
          type: 'error',
          message: 'Ошибка',
          description:
            'Скидка от поставщика не может быть больше или равна стоимости ПЛ.',
        });
      } else {
        calculationStore.setValidation('tbxSupplierDiscountRub', undefined);
      }
    },
  }),

  (calculationStore, calculationProcess) => ({
    expression: () => {
      const { firstPaymentRub } = calculationStore.values;
      return firstPaymentRub;
    },
    effect: firstPaymentRub => {
      const { leaseObjectPrice } = calculationStore.values;

      const { supplierCurrency: supplierCurrencyId } = calculationStore.values;
      const supplierCurrency = calculationStore
        .getOptions('selectSupplierCurrency')
        ?.find(x => x.transactioncurrencyid === supplierCurrencyId);
      const evo_currencychange = calculationStore
        .getStaticData('evo_currencychange')
        ?.find(x => x.evo_ref_transactioncurrency === supplierCurrencyId);
      const evo_currencychangeValue =
        (evo_currencychange && evo_currencychange.evo_currencychange) || 0;
      const price = convertPrice(
        supplierCurrency?.isocurrencycode,
        leaseObjectPrice,
        evo_currencychangeValue,
      );
      if (price && price > 0 && firstPaymentRub >= price) {
        calculationStore.setValidation('tbxFirstPaymentRub', false);
        openNotification({
          type: 'error',
          message: 'Ошибка',
          description:
            'Первый платеж не может быть больше или равен стоимости ПЛ.',
        });
      } else {
        calculationStore.setValidation('tbxFirstPaymentRub', undefined);
      }
    },
  }),

  calculationStore => ({
    expression: () => {
      const product = calculationStore.getOption('selectProduct');
      const { leaseObjectPrice, VATInLeaseObjectPrice } =
        calculationStore.values;
      return {
        product,
        leaseObjectPrice,
        VATInLeaseObjectPrice,
      };
    },
    effect: ({ product, leaseObjectPrice, VATInLeaseObjectPrice }) => {
      calculationStore.setValidation('tbxVATInLeaseObjectPrice', undefined);
      const { VAT } = valuesConstants;

      if (!product?.evo_sale_without_nds) {
        const leaseObjectPriceWthtVATValue = leaseObjectPrice / (1 + VAT);
        calculationStore.setValue(
          'leaseObjectPriceWthtVAT',
          leaseObjectPriceWthtVATValue,
        );
        calculationStore.setValue(
          'VATInLeaseObjectPrice',
          leaseObjectPrice - leaseObjectPriceWthtVATValue,
        );
      } else {
        const leaseObjectPriceWthtVAT =
          leaseObjectPrice - VATInLeaseObjectPrice;
        calculationStore.setValue(
          'leaseObjectPriceWthtVAT',
          leaseObjectPriceWthtVAT,
        );

        if (round(VATInLeaseObjectPrice / leaseObjectPriceWthtVAT, 2) >= VAT) {
          calculationStore.setValidation('tbxVATInLeaseObjectPrice', false);
          openNotification({
            type: 'error',
            message: 'Ошибка',
            description:
              'При продаже ПЛ после ФЛ размер НДС в стоимости ПЛ не может составлять 20% и более от стоимости с НДС. Проверьте корректность НДС либо измените Продукт',
          });
        }
      }
    },
    options: {
      delay: 10,
    },
  }),
] as IReactionEffect[];
