import OpenFilters from '../../data/open_filters.json'
class FormPropertyLogicRule {
  property = null
  logic = null
  isConditionCorrect = true
  isActionCorrect = true
  ACTIONS_VALUES = [
    'show-block',
    'hide-block',
    'make-it-optional',
    'require-answer',
    'enable-block',
    'disable-block'
  ]
  CONDITION_MAPPING = OpenFilters

  constructor (property) {
    this.property = property
    this.logic = (property.logic !== undefined && property.logic) ? property.logic : null
  }

  isValid () {
    if (this.logic && this.logic['conditions']) {
      this.checkConditions(this.logic['conditions'])
      this.checkActions((this.logic && this.logic['actions']) ? this.logic['actions'] : null)
    }

    return this.isConditionCorrect && this.isActionCorrect
  }

  checkConditions (conditions) {
    if (conditions && conditions['operatorIdentifier']) {
      if ((conditions['operatorIdentifier'] !== 'and') && (conditions['operatorIdentifier'] !== 'or')) {
        this.isConditionCorrect = false
        return
      }

      if (conditions['operatorIdentifier']['children'] !== undefined || !Array.isArray(conditions['children'])) {
        this.isConditionCorrect = false
        return
      }

      conditions['children'].forEach(childrenCondition => {
        this.checkConditions(childrenCondition)
      })
    } else if (conditions && conditions['identifier']) {
      this.checkBaseCondition(conditions)
    }
  }

  checkBaseCondition (condition) {
    if (condition['value'] === undefined || 
        condition['value']['property_meta'] === undefined || 
        condition['value']['property_meta']['type'] === undefined || 
        condition['value']['operator'] === undefined || 
        condition['value']['value'] === undefined
      ) {
      this.isConditionCorrect = false
      return
    }

    const typeField = condition['value']['property_meta']['type']
    const operator = condition['value']['operator']
    const value = condition['value']['value']

    if (this.CONDITION_MAPPING[typeField] === undefined || 
      this.CONDITION_MAPPING[typeField]['comparators'][operator] === undefined
      ) {
      this.isConditionCorrect = false
      return
    }
 
    const type = this.CONDITION_MAPPING[typeField]['comparators'][operator]['expected_type']
    if (Array.isArray(type)) {
      let foundCorrectType = false
      type.forEach(subtype => {
        if (this.valueHasCorrectType(subtype, value)) {
          foundCorrectType = true
        }
      })
      if (!foundCorrectType) {
        this.isConditionCorrect = false
      }
    } else {
      if (!this.valueHasCorrectType(type, value)) {
        this.isConditionCorrect = false
      }
    }
  }

  valueHasCorrectType (type, value) {
    if (
        (type === 'string' && typeof value !== 'string') ||
        (type === 'boolean' && typeof value !== 'boolean') ||
        (type === 'number' && typeof value !== 'number') ||
        (type === 'object' && !Array.isArray(value))
    ) {
      return false
    }
    return true
  }

  checkActions (conditions) {
    if (Array.isArray(conditions) && conditions.length > 0) {
      conditions.forEach(val => {
        if (this.ACTIONS_VALUES.indexOf(val) === -1 ||
            (['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image'].indexOf(this.property["type"]) > -1 && ['hide-block', 'show-block'].indexOf(val) === -1) ||
            (this.property["hidden"] !== undefined && this.property["hidden"] && ['show-block', 'require-answer'].indexOf(val) === -1) ||
            (this.property["required"] !== undefined && this.property["required"] && ['make-it-optional', 'hide-block', 'disable-block'].indexOf(val) === -1) ||
            (this.property["disabled"] !== undefined && this.property["disabled"] && ['enable-block', 'require-answer', 'make-it-optional'].indexOf(val) === -1)
        ) {
          this.isActionCorrect = false
          return
        }
      })
    } else {
      this.isActionCorrect = false
    }
  }

}

export default FormPropertyLogicRule