"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
var _require = require('date-fns'),
  endOfDay = _require.endOfDay,
  isAfter = _require.isAfter,
  isBefore = _require.isBefore,
  isValidDate = _require.isValid,
  startOfDay = _require.startOfDay;
var _require2 = require('lodash'),
  cloneDeep = _require2.cloneDeep,
  isEmpty = _require2.isEmpty;
var _require3 = require('yup'),
  number = _require3.number,
  string = _require3.string;
var FqType = require('../../constant/flexible-questionnaire/fq-type.constant');
var isValidEmail = function isValidEmail(str) {
  return string().email().isValidSync(str);
};
var isNumber = function isNumber(str) {
  return number().isValidSync(str);
};
var isNumberInRange = function isNumberInRange(num) {
  var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.NEGATIVE_INFINITY;
  var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Number.POSITIVE_INFINITY;
  return number().min(min).max(max).isValidSync(num);
};
var isValidNumber = function isValidNumber(question, answer) {
  var _question$inputProps = question.inputProps,
    min = _question$inputProps.min,
    max = _question$inputProps.max;
  return isNumber(answer) && isNumberInRange(answer, min, max);
};
var Helper = {
  hasValue: function hasValue(value) {
    if (typeof value === 'string') {
      return value.trim() !== '';
    }
    if (_typeof(value) === 'object') {
      return !isEmpty(value);
    }
    return ![null, undefined].includes(value);
  },
  hasError: function hasError(question, answer) {
    var inputPropsType = question && question.inputProps && question.inputProps.type ? question.inputProps.type : null;
    if (!question.required && ![FqType.GROUP, FqType.ADD_ANOTHER, FqType.DATEPICKER].includes(question.type) && !['email', 'number'].includes(inputPropsType) && isEmpty(question.validationProps)) {
      return false;
    }
    var questionAnswer = answer && Object.prototype.hasOwnProperty.call(answer, question.key) ? answer[question.key] : answer;
    switch (question.type) {
      case FqType.GROUP:
        return Helper.hasGroupError(question, questionAnswer);
      case FqType.LIBRARYTYPE:
        return Helper.hasLibraryError(question, questionAnswer);
      case FqType.ADD_ANOTHER:
        return Helper.hasAddAnotherError(question, questionAnswer);
      case FqType.PERMIT_SITE:
        return Helper.hasAddAnotherError(question, questionAnswer);
      case FqType.LABEL:
        return false;
      case FqType.PEOPLE:
      case FqType.LOCATION:
      case FqType.ATTACHMENT:
        return isEmpty(answer) || !Object.keys(answer).filter(function (key) {
          return answer[key];
        }).length;
      case FqType.DATETIMEPICKER:
      case FqType.DATEPICKER:
        {
          if (question.required && !Helper.hasValue(questionAnswer)) {
            return true;
          }
          if (questionAnswer && !isValidDate(new Date(questionAnswer))) {
            return true;
          }
          var disableFuture = question.disableFuture,
            disablePast = question.disablePast,
            minDate = question.minDate,
            maxDate = question.maxDate,
            validationProps = question.validationProps;
          if (!isEmpty(validationProps)) {
            var maxDateKey = validationProps.maxDateKey,
              minDateKey = validationProps.minDateKey;
            if (maxDateKey && answer && answer[maxDateKey]) {
              if (isAfter(new Date(questionAnswer), new Date(answer[maxDateKey]))) {
                return true;
              }
            }
            if (minDateKey && answer && answer[minDateKey]) {
              if (isBefore(new Date(questionAnswer), new Date(answer[minDateKey]))) {
                return true;
              }
            }
          }
          if (maxDate) {
            if (isAfter(new Date(questionAnswer), new Date(maxDate))) {
              return true;
            }
          }
          if (disableFuture) {
            if (isAfter(new Date(questionAnswer), endOfDay(new Date()))) {
              return true;
            }
          }
          if (minDate) {
            if (isBefore(new Date(questionAnswer), new Date(minDate))) {
              return true;
            }
          }
          if (disablePast) {
            if (isBefore(new Date(questionAnswer), startOfDay(new Date()))) {
              return true;
            }
          }
          return false;
        }
      case FqType.RECIPIENTS:
        {
          if (question.required && !Helper.hasValue(questionAnswer)) {
            return true;
          }
          if (question.valueType === 'email' && Helper.hasValue(questionAnswer)) {
            return questionAnswer.some(function (_ref) {
              var email = _ref.email;
              try {
                string().email().validateSync(email);
              } catch (yupError) {
                return true;
              }
              return false;
            });
          }
          return false;
        }
      case FqType.RICHTEXT:
        {
          return Helper.hasRichTextError(question, questionAnswer);
        }
      default:
        {
          if (question.required && !Helper.hasValue(questionAnswer)) {
            return true;
          }
          switch (inputPropsType) {
            case 'email':
              return !isValidEmail(questionAnswer);
            case 'number':
              {
                if (Helper.hasValue(questionAnswer) && !isValidNumber(question, questionAnswer)) {
                  return true;
                }
                var inputProps = question.inputProps,
                  _validationProps = question.validationProps;
                if (!isEmpty(_validationProps)) {
                  var maxNumberKey = _validationProps.maxNumberKey,
                    minNumberKey = _validationProps.minNumberKey;
                  if (maxNumberKey && answer && Helper.hasValue(answer[maxNumberKey]) && isNumber(answer[maxNumberKey])) {
                    if (Number(questionAnswer) > Number(answer[maxNumberKey])) {
                      return true;
                    }
                  }
                  if (minNumberKey && answer && Helper.hasValue(answer[minNumberKey]) && isNumber(answer[minNumberKey])) {
                    if (Number(questionAnswer) < Number(answer[minNumberKey])) {
                      return true;
                    }
                  }
                }
                if (!isEmpty(inputProps)) {
                  var max = inputProps.max,
                    min = inputProps.min;
                  if (Helper.hasValue(max) && isNumber(max)) {
                    if (Number(questionAnswer) > Number(max)) {
                      return true;
                    }
                  }
                  if (Helper.hasValue(min) && isNumber(min)) {
                    if (Number(questionAnswer) < Number(min)) {
                      return true;
                    }
                  }
                }
                return false;
              }
            default:
              return false;
          }
        }
    }
  },
  hasRichTextError: function hasRichTextError(question, answer) {
    if (question.required) {
      if (answer) {
        var replaceTag = answer.replace('<p>', '');
        var answerValue = replaceTag.replace('</p>', '');
        if (answerValue && answerValue.trim().length === 0 || ['<p></p>', '<p></p>\n'].includes(answer)) {
          return true;
        }
      } else {
        return true;
      }
    }
    return false;
  },
  // for follow up question, answers are in array
  // since there could be multiple times answer
  // (eg. multiple materials) for same set of question
  // and whenever there is an answer,
  // check against corresponding question with answer is valid
  hasFollowUpError: function hasFollowUpError(question, answer) {
    return answer && answer.some(function (ans) {
      return question && !isEmpty(question.questions) && !question.questions.some(function (q) {
        return ans[q.key] && !Helper.hasGroupError(q, ans[q.key]);
      });
    });
  },
  hasLibraryError: function hasLibraryError(question, answer) {
    if (question.required && (!answer || isEmpty(answer))) {
      return true;
    }
    return answer && !answer.every(function (a) {
      var libraryQuestion = question.showTagFilter === false ? question.questions[0] : question.questions.find(function (q) {
        return a.tags.some(function (tag) {
          return q.parentType.includes(tag);
        });
      });
      // Fixes issue where item would show as invalid if type didn't have follow up questions
      if (!libraryQuestion) {
        return true;
      }
      return !Helper.hasGroupError(libraryQuestion, a[libraryQuestion.key] || {});
    });
  },
  hasAddAnotherError: function hasAddAnotherError(question, answers) {
    if (question.required && !Helper.hasValue(answers)) {
      return true;
    }
    return question.questions.some(function (q) {
      return answers && answers.some(function (ans) {
        if (question.require && isEmpty(ans.item)) {
          return true;
        }
        if (q.type === FqType.GROUP) {
          return Helper.hasGroupError(q, ans.item[q.key]);
        }
        if (q.type === FqType.LIBRARYTYPE) {
          return Helper.hasLibraryError(q, ans.item[q.key]);
        }
        if (!isEmpty(q.validationProps)) {
          return Helper.hasError(q, ans.item);
        }
        return Helper.hasError(q, ans.item[q.key]);
      });
    });
  },
  hasGroupError: function hasGroupError(questionGroup, answers) {
    return questionGroup.questions.some(function (q) {
      if (answers) {
        if (q.type === FqType.GROUP) {
          return Helper.hasGroupError(q, answers[q.key]);
        }
        if (q.type === FqType.LIBRARYTYPE) {
          return Helper.hasLibraryError(q, answers[q.key]);
        }
        if (q.type === FqType.ADD_ANOTHER) {
          return Helper.hasAddAnotherError(q, answers[q.key]);
        }
        if (q.type === FqType.DEPENDENT) {
          return Helper.hasDependentError(q, answers);
        }
        if (!isEmpty(q.validationProps)) {
          return Helper.hasError(q, answers);
        }
        return !!q.required && Helper.hasError(q, answers[q.key]);
      }
      return !!q.required;
    });
  },
  hasDependentError: function hasDependentError(q, answers) {
    if (Array.isArray(q.parentValue)) {
      // eslint-disable-next-line
      if (Helper._multipleAnswersHaveMatchedParents(q, answers)) {
        return Helper.hasGroupError(q, answers[q.key]);
        // eslint-disable-next-line
      } else if (Helper._singleAnswerHasMatchedParnts(q, answers)) {
        return Helper.hasGroupError(q, answers[q.key]);
      }
    } else {
      // eslint-disable-next-line
      if (Helper._answerHasMatchedParent(q, answers)) {
        return Helper.hasGroupError(q, answers[q.key]);
        // eslint-disable-next-line
      } else if (Helper._multipleAnswersHaveMatchedParent(q, answers)) {
        return Helper.hasGroupError(q, answers[q.key]);
        // eslint-disable-next-line
      } else {
        return Helper.hasError(q, answers);
      }
    }
    return false;
  },
  _multipleAnswersHaveMatchedParent: function _multipleAnswersHaveMatchedParent(q, answers) {
    return Array.isArray(answers[q.parentKey]) && answers[q.parentKey].some(function (ans) {
      return ans.value === q.parentValue;
    });
  },
  _multipleAnswersHaveMatchedParents: function _multipleAnswersHaveMatchedParents(q, answers) {
    return Array.isArray(answers[q.parentKey]) && answers[q.parentKey].some(function (ans) {
      return q.parentValue.some(function (pValue) {
        return ans.value === pValue;
      });
    });
  },
  _answerHasMatchedParent: function _answerHasMatchedParent(q, answers) {
    return answers[q.parentKey] && (answers[q.parentKey].value === q.parentValue || answers[q.parentKey] === q.parentValue);
  },
  _singleAnswerHasMatchedParnts: function _singleAnswerHasMatchedParnts(q, answers) {
    return q.parentValue.some(function (pValue) {
      return answers[q.parentKey] && pValue === answers[q.parentKey].value;
    });
  },
  isFormValid: function isFormValid(questions, answers) {
    return !questions.some(function (question) {
      return Helper.hasError(question, answers);
    });
  },
  setDefaultValueToResponses: function setDefaultValueToResponses(responses) {
    var questions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    if (!questions || isEmpty(questions)) {
      return responses;
    }
    var transformed = cloneDeep(responses || {});
    questions.forEach(function (q) {
      if (transformed[q.key] !== undefined || q.defaultValue) {
        switch (q.type) {
          case FqType.LABEL:
            break;
          case FqType.DEPENDENT:
          case FqType.GROUP:
            transformed[q.key] = Helper.setDefaultValueToResponses(transformed[q.key], q.questions);
            break;
          case FqType.ADD_ANOTHER:
            transformed[q.key] = (transformed[q.key] || []).map(function (answer) {
              return Helper.setDefaultValueToResponses(answer, q.questions);
            });
            break;
          default:
            if ((!transformed[q.key] || isEmpty(transformed[q.key])) && q.defaultValue) {
              transformed[q.key] = q.defaultValue;
            }
            break;
        }
      }
    });
    return transformed;
  }
};
module.exports = Helper;