import cloneDeep from 'lodash/cloneDeep'

/**
 * 动态函数
 * @param script 函数脚本
 * @param model 整个表单的数据
 * @param key 当前整改表单数据的标识key
 * @param row 如果为batch 标识当前行的数据
 * @param rowKey 如果为batch 标识当前行数据的key
 * @return 验证结果 函数脚本执行结果
 */
export function dynamicFun(script, model, key = '$', row, rowKey, thisObj = window) {
  if (!script) return false

  const func = script.indexOf('return') >= 0 ? '{' + script + '}' : 'return (' + script + ')'

  if (row && rowKey) {
    const Fn = new Function(key, rowKey, func)
    return Fn(model, row)
  } else {
    const Fn = new Function(key, func)
    return Fn(model)
  }
}
/**
 * 数据复制并且格式化
 */
export function cloneDeepAndFormat(data, e) {
  const clone = cloneDeep(data)
  delete clone.icon

  // 按照当前语言对国际化适配的数据进行格式化

  const fs_ = (p, k, v) => {
    if (v instanceof Function) {
      const nv = getLabel(v)
      p[k] = nv
    } else if (v instanceof Array) {
      v.forEach((t, idx) => {
        fs_(v, idx, t)
      })
    } else if (v instanceof Object) {
      for (const key in v) {
        fs_(v, key, v[key])
      }
    }
  }

  for (const key in clone) {
    const kdata = clone[key]

    fs_(clone, key, kdata)
  }

  // 判断事件 和数据来源 如果存在且来自非ul 则不刷新key和model
  // console.log('e.from.nodeName' , e ? e.from.nodeName : 'none')
  if (e && e.from && e.from.nodeName != 'UL') {
    return clone
  }

  let idx = 1
  // 2023-08-27 lyf 迭代判断是否包含子组件，全部替换子组件的key和model
  const iterKeyReplace_ = (v) => {
    if (v instanceof Array) {
      v.forEach((c) => {
        iterKeyReplace_(c)
      })
    } else if (v.key) {
      // 重置key和model
      idx++
      const vkey = v.type + '_' + new Date().getTime() + '' + idx
      v['key'] = vkey
      v['model'] = vkey
    }

    for (const k in v) {
      const kd = v[k]
      if (kd instanceof Array) {
        iterKeyReplace_(kd)
      }
    }
  }

  iterKeyReplace_(clone)

  return clone
}

/**
 * 获取uuid
 */
export function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16)
  })
}

export function getLabel(v) {
  if (typeof v === 'function') {
    const label = v()
    return label
  }
  return v
}

/**
 * 动态函数
 * @param script 函数脚本
 * @param model 整个表单的数据
 * @param key 当前整改表单数据的标识key
 * @param row 如果为batch 标识当前行的数据
 * @param rowKey 如果为batch 标识当前行数据的key
 * @return 验证结果 函数脚本执行结果
 */
export function dynamicVoidFun(script, model, key = '$', row, rowKey, thisObj = window) {
  if (!script) return false
  const func = script // .indexOf('return') >= 0 ? '{' + script + '}' : 'return (' + script + ')'

  if (row && rowKey) {
    const Fn = new Function(key, rowKey, func)
    Fn.call(thisObj, model, row)
  } else {
    const Fn = new Function(key, func)
    Fn.call(thisObj, model)
  }
}

export function dateFormater(date, fmt) {
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'H+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  for (var k in o) { if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)) }
  return fmt
}

// 定制组件参数的规范和转换
// 配置数组转 配置项
// 配置最多两层，不走迭代
export function translateConfig(config) {
  const fs = (v) => {
    const formOptions = v.options

    if (formOptions.group && formOptions.group.length > 0) {
      formOptions.group.forEach((t) => {
        if (t.label && t.prop && t.default != null && !t.column) {
          v[t.prop] = t.default
        } else if (t.column) {
          v[t.prop] = {}
          t.column
            .filter((tf) => tf.prop)
            .forEach((tc) => {
              let jdefault = tc['default']
              if (jdefault == undefined || jdefault == null) {
                jdefault = ''
              }

              v[t.prop][tc.prop] = jdefault
            })
        }
      })
    }

    if (formOptions.columns && formOptions.columns.length > 0) {
      formOptions.columns
        .filter((tf) => tf.prop)
        .forEach((tc) => {
          let jdefault = tc['default']
          if (jdefault == undefined || jdefault == null) {
            jdefault = ''
          }

          v[tc.prop] = jdefault
        })
    }
  }

  const cloneConfig = cloneDeep(config)

  if (cloneConfig instanceof Array) {
    cloneConfig.map((t) => fs(t))
  } else {
    fs(cloneConfig)
  }

  return cloneConfig
}
