import InputNumber from 'client/Elements/InputNumber';
import valuesConstants from 'core/constants/values';
import { rotateArrays } from 'core/tools/array';
import { formatNumber } from 'core/tools/format';
import { inRange } from 'lodash';
import { Table } from '../../types/tables';

const { PERIODS_NUMBER } = valuesConstants;

const columns: Table['columns'] = [
  {
    name: 'paymentRelation',
    title: '% платежа',
    Component: InputNumber,
    props: {
      min: '0.01',
      max: '100.00',
      step: '1.00',
      precision: 2,
      formatter: formatNumber,
    },
  },
];

const callbacks: Table['callbacks'] = {
  paymentRelation: ({ calculationStore, tableName, rowIndex, value }) => {
    const rowLength = calculationStore.tables[tableName].rows.length;
    const { graphType, seasonType } = calculationStore.values;

    if (graphType === 100000001 && seasonType === 100_000_007) {
      if (rowIndex > 1 && rowIndex < rowLength - 1) {
        if (
          calculationStore.tables[tableName].rows[rowIndex].paymentRelation
            ?.value !==
          calculationStore.tables[tableName].rows[rowIndex + 1].paymentRelation
            ?.value
        )
          calculationStore.setTableRows(
            tableName,
            rowIndex,
          )(
            Array.from(
              {
                length: rowLength - rowIndex - 1,
              },
              (_v, i) => ({
                paymentRelation: {
                  value,
                },
              }),
            ),
          );
      }
    }

    if (graphType === 100000003) {
      const { leasingPeriod } = calculationStore.values;
      if (rowIndex >= 1 && rowIndex <= PERIODS_NUMBER) {
        const highSeasonStartValue = parseInt(
            calculationStore.getOption('selectHighSeasonStart')?.name || '2',
          ),
          shiftNumber = highSeasonStartValue - 2;

        const seasonTypeOptions =
          calculationStore.getOption('selectSeasonType');
        const startPositions =
            seasonTypeOptions && seasonTypeOptions.startPositions,
          endPositions =
            seasonTypeOptions &&
            seasonTypeOptions.paymentsInStep.map(
              (x, i) => startPositions[i] + x,
            );

        const allBoundaries = rotateArrays(startPositions, endPositions);

        const withUnshift = n => n - shiftNumber;
        const withShift = n => n + shiftNumber;
        const withFirstPayment = n => n + 1;
        let index;
        for (let i = 0; i < allBoundaries.length; i++) {
          const [min, max] = allBoundaries[i].map(x => withFirstPayment(x));
          let unshiftedRowIndex = withUnshift(rowIndex);
          if (unshiftedRowIndex <= 0) {
            unshiftedRowIndex += PERIODS_NUMBER;
          }

          if (inRange(unshiftedRowIndex, min, max)) {
            index = i;
            break;
          }
        }

        const paymentsInStep =
          seasonTypeOptions && seasonTypeOptions.paymentsInStep;

        for (
          let i =
            withFirstPayment(withShift(allBoundaries[index][0])) -
            PERIODS_NUMBER;
          i < leasingPeriod - 1;
          i += PERIODS_NUMBER
        ) {
          const targetStartPosition = i;
          for (
            let j = targetStartPosition;
            j < paymentsInStep[index] + targetStartPosition;
            j++
          ) {
            if (j > 0 && j < leasingPeriod - 1)
              calculationStore.setTableRow(
                tableName,
                j,
              )({ paymentRelation: { value } });
          }
        }
      }
    }
  },
};

const params: Table['params'] = {
  features: {
    numerize: true,
    split: {
      rowsNumber: 12,
      columnsNumber: 3,
    },
  },
};

export default {
  columns,
  rows: [],
  params,
  callbacks,
} as Table;
