package com.artfess.sysConfig.persistence.manager.impl;


import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.model.CommonResult;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.poi.util.ExcelUtil;
import com.artfess.sysConfig.persistence.dao.DataDictDao;
import com.artfess.sysConfig.persistence.manager.DataDictManager;
import com.artfess.sysConfig.persistence.manager.SysTypeManager;
import com.artfess.sysConfig.persistence.model.DataDict;
import com.artfess.sysConfig.persistence.model.SysType;
import com.artfess.sysConfig.vo.DataDictExcelVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Service("dataDictManager")
public class DataDictManagerImpl extends BaseManagerImpl<DataDictDao, DataDict> implements DataDictManager{
	@Resource
	SysTypeManager sysTypeManager;

	@Override
	public List<DataDict> getByTypeId(String typeId) {
		return baseMapper.getByTypeId(typeId);
	}
	@Override
	public DataDict getByDictKey(String typeId, String key) {
		Map<String, Object> params = new HashMap<>();
		params.put("typeId", typeId);
		params.put("key", key);
		return baseMapper.getByDictKey(params);
	}

	@Override
	public void removeByIds(String ...ids) {
		if(BeanUtils.isNotEmpty(ids)){
			for(String id : ids){
				this.remove(id);
				List<DataDict> childs = getChildrenByParentId(id);
				for(DataDict dict : childs){
					this.remove(dict.getId());
				}

			}
		}
		super.removeByIds(ids);
	}
	/**
	 * 获取一级子节点
	 * @param id
	 * @return
	 */
	@Override
	public List<DataDict> getFirstChilsByParentId(String id){
		return baseMapper.getByParentId(id);
	}
	/**
	 * 获取所有的子节点
	 * @param id
	 * @return
	 */
	@Override
	public List<DataDict> getChildrenByParentId(String id){
		List<DataDict> childs = baseMapper.getByParentId(id);
		return getChilds(childs);
	}
	/**
	 * 通过子节点查询子节点
	 * @param childs
	 * @return
	 */
	private List<DataDict> getChilds(List<DataDict> childs){
		List<DataDict> dataDict = new ArrayList<DataDict>();
		// 如果孩子不为空 查询孩子的孩子
		if(BeanUtils.isNotEmpty(childs)){
			for(DataDict dict : childs){
				List<DataDict> children =  baseMapper.getByParentId(dict.getId());
				//如果孩子的孩子们不为空  则通过孩子们 查询他们的孩子们
				if(BeanUtils.isNotEmpty(children)){
					children = getChilds(children);
					dataDict.addAll(children);
				}

			}
			dataDict.addAll(childs);
		}
		return dataDict;
	}
	@Override
	public void delByDictTypeId(String dictTypeId) {
		baseMapper.delByDictTypeId(dictTypeId);
	}




	/**
	 * 更新排序  sn
	 * @param dicId
	 * @param sn
	 */
	@Override
	public void updSn(String dicId, int sn) {
		Map<String, Object> params = new HashMap<>();
		params.put("id", dicId);
		params.put("sn", sn);
		baseMapper.updSn(params);
	}
	@Override
	public CommonResult<String> removeByTypeIds(String typeIds) {
		if (StringUtil.isNotEmpty(typeIds)) {
			List<SysType> typeList = sysTypeManager.getChildByTypeId(typeIds);
			String[] typeIdList = new String[typeList.size()+1];
			typeIdList[0] = typeIds;
			for (int i = 0; i < typeList.size(); i++) {
				typeIdList[i+1] = typeList.get(i).getId();
			}
			sysTypeManager.removeByIds(typeIdList);
			for (String typeId : typeIdList) {
				baseMapper.delByDictTypeId(typeId);
			}
		}
		return new CommonResult<>("操作成功");
	}
	@Override
	@Transactional
	public void importData(List<MultipartFile> files, String typeId) throws Exception {
		Iterator<MultipartFile> it = files.iterator();
		Map<String, DataDict> data = new HashMap<String, DataDict>();
		//数据字典分类
		SysType sysType = sysTypeManager.get(typeId);
		if(BeanUtils.isEmpty(sysType)) {
			throw new BaseException("请选择数据字典分类进行导入");
		}
		while (it.hasNext()) {
			MultipartFile file = it.next();
			List<DataDictExcelVo> list= ExcelUtil.readExcel(DataDictExcelVo.class,file);
			LinkedList<DataDict> dataDictBuffer = new LinkedList<>();
			for (DataDictExcelVo vo:list) {
				String pKey = vo.getPidKey();
				String key = vo.getKey();
				String name = vo.getName();
				Map<String, Object> params = new HashMap<>();
				params.put("typeId", typeId);
				params.put("key", key);
				// 验证字典key 是否已经存在
				DataDict dict= baseMapper.getByDictKey(params);
				if(dict != null){
					throw new BaseException("该字典项值已经存在");
				}

				DataDict dataDict = new DataDict();
				dataDict.setTypeId(typeId);
				if(StringUtil.isEmpty(pKey)) {
					dataDict.setParentId(typeId);
				}else {
					//
					Map<String, Object> pMap = new HashMap<>();
					pMap.put("typeId", typeId);
					pMap.put("key", pKey);

					DataDict dtDict= baseMapper.getByDictKey(pMap);
					if(BeanUtils.isEmpty(dtDict)) {
						//从添加的列表中获取
						DataDict dmDict = data.get(pKey);
						if(BeanUtils.isEmpty(dmDict)) {
							if(isParentKeyInList(pKey,list)){
								//将父亲节点尚未生成的元素放入一个缓冲队列中
								dataDict.setParentId(pKey);
								dataDict.setKey(key);
								dataDict.setName(name);
								dataDictBuffer.add(dataDict);
								continue;
							}else{
								throw new BaseException("请输入正确的父节点key");
							}
						}else {
							dataDict.setParentId(dmDict.getId());
						}
					}
					dataDict.setParentId(dtDict.getId());
				}
				dataDict.setKey(key);
				dataDict.setName(name);
				this.create(dataDict);
				//添加列表
				data.put(key, dataDict);
			}
			//循环处理dataDictBuffer
			handleSaveBuffer(dataDictBuffer,data);
			/*for (DataDict dataDict : dataDictBuffer) {
				String parentKey = dataDict.getParentId();
				DataDict parent = data.get(parentKey);
				if(BeanUtils.isEmpty(parent)){
					throw new BaseException("请输入正确的父节点");
				}
				dataDict.setParentId(parent.getId());
				this.create(dataDict);
			}*/
		}
	}

	/*
	* 判断父节点在DataDictExcelVo中是否存在
	* */
	private boolean isParentKeyInList(String parentKey,List<DataDictExcelVo> list){
		if(StringUtil.isEmpty(parentKey) || BeanUtils.isEmpty(list)){
			return false;
		}
		for (DataDictExcelVo dataDictExcelVo : list) {
			if (parentKey.equals(dataDictExcelVo.getPidKey())) {
				return true;
			}
		}
		return false;
	}

	private void handleSaveBuffer(LinkedList<DataDict> list,Map<String,DataDict> data){
		if(BeanUtils.isEmpty(list)){
			return ;
		}
		int size = list.size();
		int count = 0; //出队又入队的次数，连续出队入队次数超过队列长度，则可以认为进入了死循环。
		//如果循环一遍，一个元素都没有被处理，则直接跳出循环
		while(list.size() > 0){
			//队首取，队尾插入
			DataDict dataDict = list.removeFirst();
			String parentKey = dataDict.getParentId();
			DataDict parent = data.get(parentKey);
			//父节点尚未生成，将此元素放到队尾
			if(BeanUtils.isEmpty(parent)){
				list.addLast(dataDict);
				count++;
				if(count > size){
					throw new BaseException("导入失败，请检查excel数据是否正确");
				}
			}else{
				dataDict.setParentId(parent.getId());
				this.create(dataDict);
				data.put(dataDict.getKey(),dataDict);
				//重置count和size
				size = list.size();
				count = 0;
			}
		}
	}

}
