import axios from '../bc-libs/api.request'
import config from '@/config'

const systemPrefix = config.deploymentStandAlone ? '' : 'cas/'

const prefix = systemPrefix + 'api/v1/base/dictGroup'

const prefixDict = systemPrefix + 'api/v1/base/dict'

/**
 *
 * 获取字典
 * @param code 字典类型编码
 * @param fn 回调函数
 * @param params 附带参数
 */
/**
 * 获取字典
 * @param fn
 */

let dictTag = 'bc_cache_dict'//普通的字典
let dictCadeTag = 'bc_cache_cade_dict'//级联的父子节点
let dictParentTag = 'bc_by_parent_dict'//通过父节点id缓存的字典
let groupTag = 'bc_cache_group'
let systemFlagTag = 'bc_cache_system'//系统的字典缓存,key是系统,值是系统包含的字典
let fnArr = {}
//将字典添加到缓存
var addCache = (storageKey, code, dict) => {
  let _dicts = sessionStorage.getItem(storageKey)
  _dicts = _dicts ? JSON.parse(_dicts) : {}
  _dicts[code] = dict
  sessionStorage.setItem(storageKey, JSON.stringify(_dicts))
}

//从缓存中获取字典
var getDictByCache = (storageKey, code) => { //加页面缓存获取
  let _dicts = sessionStorage.getItem(storageKey)
  _dicts = _dicts ? JSON.parse(_dicts) : {}
  if (_dicts[code]) {
    return _dicts[code]
  }
}

//先从缓存获取,如果缓存没有,就从后台查询
var getDict = (code, fn) => {
  let dictCache = getDictByCache(dictTag, code)
  if (dictCache && dictCache.length > 0) {
    return fn(dictCache)
  } else {
    if (fnArr[code]) {//如果已经在查询当中了.那就
      fnArr[code].push(fn)
      return
    }
    fnArr[code] = []
    fnArr[code].push(fn)
    getDictL(code, dict => {
      addCache(dictTag, code, dict)
      fnArr[code].forEach(callBack => {
        callBack(dict)
      })
      delete fnArr[code]
      return
    })
  }
}

var getDictL = (code, fn, params) => {//直接获取
  //先处理附带参数
  params = params ? params : {}
  params.groupCode = code
  //发送请求
  axios.request({
    url: prefixDict + '/list/',
    params: params,
    method: 'get'
  }).then(response => {
    fn(response.data.result)
  }).catch(err => {
    delete fnArr[code]
    //this.$Message.error('查询字典失败!类型: ' + code)
    console.log(err)
  })
}

/**
 * 通过父id查询子字典集合  单层
 * @param parentId 父字典id
 * @param fn
 */
var getDictByParentId = (parentId, fn) => {//直接获取
  let dictCache = getDictByCache(dictParentTag, parentId)
  if (dictCache) {
    fn(dictCache)
    return
  }
  //发送请求查询字典
  getDictL(null, (data1) => {
    if (data1 && data1.length > 0) {
      addCache(dictParentTag, parentId, data1)
      fn(data1)
    } else {
      fn({})
    }
  }, { parentId: parentId })

}

/**
 * 删除字典缓存
 * @param storageKey
 * @param code
 */
var clearDictCahce = (storageKey, code) => {
  let _dicts = sessionStorage.getItem(storageKey)
  _dicts = _dicts ? JSON.parse(_dicts) : {}
  if (_dicts[code]) {//有就删除
    delete _dicts[code]
    sessionStorage.setItem(storageKey, JSON.stringify(_dicts))
  }
  //没有就清除所有
  else {
    sessionStorage.setItem(storageKey, JSON.stringify({}))
  }
}

/**
 * 获取字典类型与字典集合组成map,格式如下
 * {
 *   groupCode1: list<Dict>
 *   groupCode2: list<Dict>
 * }
 * @param fn
 */
var getAllDictToMap = (fn, params) => {
  axios.request({
    url: prefix + '/allDictToMap/',
    params: params,
    method: 'get'
  }).then(response => {
    fn(response.data.result)
  }).catch(err => {
    //this.$Message.error('查询字典类型集合失败!')
    console.log(err)
  })
}

export default {
  name: 'bcDictUtil',
  dictGroupList: [],

  /**
   * 初始化全部字典
   * 参数是系统的code,如果没有传,那就默认取当前系统的code
   * @param fn
   */
  initAllDictCache: (sysCode) => {
    if (!sysCode) {
      sysCode = config.systemCode + '|common'
    }
    //看一看有没有这个系统的字典缓存在浏览器,有就直接取
    let dictMapCache = getDictByCache(systemFlagTag, sysCode)
    if (dictMapCache) {
      /*for(let key in dictMapCache){
        addCache(dictTag,key,dictMapCache[key]);
      }*/
    } else {
      getAllDictToMap(dictMap => {
        //将这个结果加入缓存
        addCache(systemFlagTag, sysCode, true)
        //循环将每个字典类型存入缓存
        for (let key in dictMap) {
          addCache(dictTag, key, dictMap[key])
        }
      }, { code__in: sysCode, getChildren: true })
    }
  },

  /**
   * 获取字典类型集合
   * @param fn
   */
  getDictGroupList: (fn, params) => {
    axios.request({
      url: prefix + '/list/',
      params: params,
      method: 'get'
    }).then(response => {
      fn(response.data.result)
    }).catch(err => {
      this.$Message.error('查询字典类型集合失败!')
      console.log(err)
    })
  },

  /**
   * 获取指定字典类型
   * @param fn
   */
  getDictGroup: (params, fn) => {
    axios.request({
      url: prefix + '/list/',
      params: params,
      method: 'get'
    }).then(response => {
      //this.dictGroupList = response.result
      if (response.data.result && response.data.result.length > 0) {
        fn(response.data.result[0])
      } else {
        fn({})
      }
    })/*.catch(err => {
      this.$Message.error('查询字典类型失败!')
      console.log(err)
    })*/
  },
  getDict: getDict,
  getDictL: getDictL,

  /**
   * 获取字典name
   * @param value
   * @param fn
   */
  getDictName: (code, value, fn) => {
    let name = ''
    return getDict(code, (data) => {
      data.forEach(dict => {
        if (dict.value == value) {
          name = dict.name
          return fn(name)
        }
      })
    })
  },

  //先从缓存获取,如果缓存没有,就返回空
  getDictNameByCache: (code, value) => {
    let name = ''
    let dictCache = getDictByCache(dictTag, code)
    if (dictCache) {
      dictCache.forEach(dict => {
        if (dict.value == value) {
          name = dict.name
        }
      })
    }
    return name
  },

  /**
   * 获取字典value
   * @param id
   * @param name
   */
  getDictValue: (code, name, fn) => {
    let value = ''
    getDict(code, (data) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].name == name) {
          value = data[i].value
          fn(value)
        }
      }
    })
  },

  /**
   * 获取字典下级集合
   * @param code 字典类型编码
   * @param value 字典值
   * @param fn 回调函数
   */
  getDictChildren: (code, value, fn) => {
    //获取字典本身对象,然后再去查询子字典,有缓存机制
    getDict(code, (data) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].value == value) {
          //第二次发请求,这次是查询子字典,有缓存机制
          getDictByParentId(data[i].id, (data1) => {
            fn(data1)
          })
        }
      }
    })
  },

  /**
   * 获取字典下级集合---级联
   * @param code 字典类型编码
   * @param value 字典值
   * @param fn 回调函数
   */
  getDictChildrenCas: (code, value, fn) => {
    //获取字典本身对象,然后再去查询子字典,有缓存机制
    let targetPid
    let arr = []
    let result = []
    getDict(code, (data) => {
      //第一次循环，是找出parent对象。与筛选一下有父级的集合
      for (let i = 0; i < data.length; i++) {
        if (data[i].value == value) {
          targetPid = data[i].id
        }
        if (data[i].parentId && data[i].parentId.length > 0) {
          arr.push(data[i])
        }
      }
      //第二个循环，根据fullPath来筛选正确的对象
      arr.forEach(n => {
        if (n.fullPath.indexOf(targetPid) !== -1) {
          result.push(n)
        }
      })
      //最后回调
      fn(result)
    })
  },

  /**
   * 获取字典父级对象
   * @param code 字典类型编码
   * @param value 字典值
   * @param fn 回调函数
   */
  getDictParent: (code, value, fn) => {
    //获取字典本身对象,然后再去查询父字典
    getDict(code, (data) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].value == value) {
          //第二次发请求,这次是查询父字典
          getDictL(code, (data1) => {
            if (data1 && data1.length > 0) {
              fn(data1[0])
            } else {
              fn({})
            }
          }, { id: data[i].parentId })
        }
      }
    })
  },
  /**
   *
   * 获取字典(级联查出code对应所有父子字典)
   * @param code 字典类型编码
   * @param fn 回调函数
   * @param params 附带参数
   */
  getDictCascade: (code, fn, params) => {
    //如果参数是空,就可以取缓存
    if (!params) {
      let dictCadeCache = getDictByCache(dictCadeTag, code)
      if (dictCadeCache) {
        fn(dictCadeCache)
        return
      }
    }
    //缓存没有就先处理附带参数
    let newParams = params ? JSON.parse(JSON.stringify(params)) : {}
    newParams.groupCode = code
    //发送请求
    axios.request({
      url: prefixDict + '/tree/',
      params: newParams,
      method: 'get'
    }).then(response => {
      if (!params) {
        addCache(dictCadeTag, code, response.data.result)
      }
      fn(response.data.result)
    })/*.catch(err => {
    this.$Message.error('查询字典失败!类型: ' + code)
    console.log(err)
  })*/
  },

  /**
   * 获取字典指定的那一级
   * @param code 字典类型编码
   * @param value 字典值
   * @param fn 回调函数
   */
  getDictSpecifyLevel: (code, specifyLevel, fn) => {
    //先初始化层级的集合
    let levelDictIds = { 1: [], 2: [], 3: [], 4: [], }
    let levelDictObjs = { 1: [], 2: [], 3: [], 4: [], }
    getDict(code, (data) => {
      for (let level = 1; level <= 4; level++) {
        //第一次循环,将没有父级的字典都放在1级
        for (let i = 0; i < data.length; i++) {
          if (level === 1) {
            if ((!data[i].parentId) || data[i].parentId == '') {
              levelDictIds[level].push(data[i].id)
              levelDictObjs[level].push(data[i])
            }
          }else {
            if (levelDictIds[level-1].indexOf(data[i].parentId) > -1) {
              levelDictIds[level].push(data[i].id)
              levelDictObjs[level].push(data[i])
            }
          }
        }
      }
      fn(levelDictObjs[specifyLevel])
    })
  },

  //删除前端缓存的字典数据
  clearCache (dictDomain) {
    if (dictDomain.groupCode) {
      let code = dictDomain.groupCode
      //普通code字典
      clearDictCahce(dictTag, code)
      //级联code字典
      clearDictCahce(dictCadeTag, code)
    }
    //父子id字典
    if (dictDomain.parentId) {
      clearDictCahce(dictParentTag, dictDomain.parentId)
    }
    if (dictDomain.id) {
      clearDictCahce(dictParentTag, dictDomain.id)
    }
    //全局系统级字典缓存
    clearDictCahce(systemFlagTag, config.systemCode + '|common')
  },
  /**
   * 删除所有字典缓存
   */
  clearCacheAll(){
    clearDictCahce(dictTag)
    clearDictCahce(dictCadeTag)
    clearDictCahce(dictParentTag)
    clearDictCahce(groupTag)
    clearDictCahce(systemFlagTag)
  },

}

















