import { getValueName } from 'client/Containers/Calculation/Elements/tools';
import { ElementsNames } from 'client/Containers/Calculation/types/elements';
import { openNotification } from 'client/Elements/Notification';
import { ICalculationStore } from 'core/types/Calculation/Store/index';

export type ValidationResult = {
  isValid: boolean;
  message?: string;
};

export type ValidationCondition = (
  calculationStore: ICalculationStore,
  elementName: ElementsNames,
) => ValidationResult;

export const validate = (
  calculationStore: ICalculationStore,
  conditions: Partial<Record<ElementsNames, ValidationCondition>>,
) => {
  const validationResult: Partial<Record<ElementsNames, ValidationResult>> = (
    Object.keys(conditions) as ElementsNames[]
  ).reduce((ac, elementName) => {
    const condition = conditions[elementName];
    ac[elementName] = condition && condition(calculationStore, elementName);
    return ac;
  }, {});
  return validationResult;
};

export const getValue = (
  calculationStore: ICalculationStore,
  elementName: ElementsNames,
) => {
  const valueName = getValueName(elementName);
  const value = calculationStore.getValue(valueName);
  return value;
};

export const convertToValidationResult = result => ({ isValid: !result });

export function showValidationMessages(
  validationsResult: Partial<Record<ElementsNames, ValidationResult>>,
  title: string,
): { hasMessages: boolean } {
  let messages: string[] = [];
  (Object.keys(validationsResult) as ElementsNames[]).forEach(elementName => {
    const elementValidationResult = validationsResult[elementName];
    if (elementValidationResult) {
      const { isValid, message } = elementValidationResult;
      if (isValid === false && message !== undefined) {
        messages.push(message);
      }
    }
  });

  const hasMessages = messages?.length > 0;
  if (hasMessages) {
    messages.forEach(message => {
      if (message)
        openNotification({
          type: 'error',
          message: title,
          description: message,
        });
    });
  }
  return { hasMessages };
}
