import { getTitle } from 'client/Containers/Calculation/Elements/tools';
import { ElementsNames } from 'client/Containers/Calculation/types/elements';
import { openNotification } from 'client/Elements/Notification';
import { pipe } from 'core/tools/func';
import { ICalculationStore } from 'core/types/Calculation/Store';
import CONDITIONS from 'core/validation/conditions';
import {
  convertToValidationResult,
  getValue,
  showValidationMessages,
  validate,
  ValidationCondition
} from 'core/validation/validate';

type ELTValidation = {
  requiredFields: ElementsNames[];
  conditions?: Partial<Record<ElementsNames, ValidationCondition>>;
};

export default function (this: ICalculationStore, validation: ELTValidation) {
  const { requiredFields, conditions: customConditions } = validation;

  const requiredFieldsConditions = requiredFields.reduce(
    (ac: Partial<Record<ElementsNames, ValidationCondition>>, elementName) => {
      ac[elementName] = pipe(
        getValue,
        CONDITIONS.IS_NULL,
        convertToValidationResult,
      );
      return ac;
    },
    {},
  );

  const requiredFieldsResult = validate(this, requiredFieldsConditions);
  let missingElementsNames: string[] = [];
  (Object.keys(requiredFieldsResult) as ElementsNames[]).forEach(
    elementName => {
      if (requiredFieldsResult[elementName]?.isValid === false) {
        const elementTitle = getTitle(elementName);
        missingElementsNames.push(elementTitle);
      }
    },
  );

  if (missingElementsNames.length > 0) {
    openNotification({
      type: 'error',
      message: 'Ошибка во время расчета ЭЛТ',
      description: String.prototype.concat(
        'Не заполнены поля: ',
        missingElementsNames.join(', '),
      ),
    });
    return false;
  }

  if (customConditions) {
    const customConditionsResult = validate(this, customConditions);
    const { hasMessages } = showValidationMessages(
      customConditionsResult,
      'Ошибка во время расчета ЭЛТ',
    );
    if (hasMessages) {
      return false;
    }

    return true;
  }
}
