import { DQRule } from '../models/dq-rules.model'
import { specialMissingNumericValidator } from './hot-custom-validators'

const dqValidation: {
  [key: string]: (value: any, ruleValue: string | number) => boolean
} = {
  CASE: (value: any, ruleValue: string | number): boolean => {
    switch (ruleValue) {
      case 'UPCASE': {
        if ([undefined, null].includes(value)) return true

        return (
          typeof value === 'string' &&
          value.toString() === value.toString().toUpperCase()
        )
      }
      case 'LOWCASE': {
        if ([undefined, null].includes(value)) return true

        return (
          typeof value === 'string' &&
          value.toString() === value.toString().toLowerCase()
        )
      }
    }

    return true
  },
  MINVAL: (value: any, ruleValue: string | number): boolean => {
    const isValidNumeric = specialMissingNumericValidator(value)
    const numValue = parseFloat(value)

    // If it's validNumeric and it is NaN it means it is special numeric, and those are always less then any
    // min value set
    if (isValidNumeric && isNaN(numValue)) return false

    return numValue >= Number(ruleValue.toString())
  },
  MAXVAL: (value: any, ruleValue: string | number): boolean => {
    const isValidNumeric = specialMissingNumericValidator(value)
    const numValue = parseFloat(value)

    if (isValidNumeric && isNaN(numValue)) return true

    return numValue <= Number(ruleValue.toString())
  },
  NOTNULL: (value: any, ruleValue: string | number): boolean => {
    return value !== undefined && value !== null && value.toString().length > 0
  }
}

export const dqValidate = (dqRules: DQRule[], value: any): boolean => {
  for (let detail of dqRules) {
    if (dqValidation[detail.RULE_TYPE]) {
      if (!dqValidation[detail.RULE_TYPE](value, detail.RULE_VALUE)) {
        console.warn(
          `DQ Invalid Reason: ${
            detail.RULE_TYPE
          }\nValue: ${value})\nRule Value: ${
            detail.RULE_VALUE.length > 0 && detail.RULE_VALUE !== ' '
              ? detail.RULE_VALUE
              : 'Not defined'
          }`
        )
        return false
      }
    }
  }

  return true
}
