package com.yihu.jw.base.service.org;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.yihu.jw.base.dao.org.OrgTreeDao;
import com.yihu.jw.base.service.org.tree.SimpleTree;
import com.yihu.jw.base.service.org.tree.SimpleTreeNode;
import com.yihu.jw.base.service.org.tree.TreeNode;
import com.yihu.jw.entity.base.org.BaseOrgDO;
import com.yihu.jw.rm.base.BaseRequestMapping;
import com.yihu.mysql.query.BaseJpaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 
 * 机构信息服务service
 * 
 * @version 
 * <pre>
 * Author	Version		Date		Changes
 * litaohong    1.0  2018年10月15日 Created
 *
 * </pre>
 * @since 1.
 */
@Service
public class OrgTreeService extends BaseJpaService<OrgTree, OrgTreeDao> {

    @Autowired
    private OrgTreeDao orgTreeDao;

    /**
     * 添加机构和区域的关系
     * @param baseOrgDO
     */
    @Transactional(rollbackFor = Exception.class)
    public void addOrgTreeNode(BaseOrgDO baseOrgDO){
        List<OrgTree> treeNodes = new ArrayList<>();
        if(!orgTreeDao.existsByCode(baseOrgDO.getCode())){
            OrgTree orgNode = new OrgTree(baseOrgDO.getCode(),baseOrgDO.getTownCode(),baseOrgDO.getName(), OrgTree.Level.org.getLevelValue());
            treeNodes.add(orgNode);
        }
        if(!orgTreeDao.existsByCode(baseOrgDO.getTownCode())){
            OrgTree townTree = new OrgTree(baseOrgDO.getTownCode(),baseOrgDO.getCityCode(),baseOrgDO.getTownName(), OrgTree.Level.town.getLevelValue());
            treeNodes.add(townTree);
        }
        if(!orgTreeDao.existsByCode(baseOrgDO.getCityCode())){
            OrgTree cityTree = new OrgTree(baseOrgDO.getCityCode(),baseOrgDO.getProvinceCode(),baseOrgDO.getCityName(), OrgTree.Level.city.getLevelValue());
            treeNodes.add(cityTree);
        }
        if(!orgTreeDao.existsByCode(baseOrgDO.getProvinceCode())){
            OrgTree provinceTree = new OrgTree(baseOrgDO.getProvinceCode(),"",baseOrgDO.getProvinceName(), OrgTree.Level.province.getLevelValue());
            treeNodes.add(provinceTree);
        }
        this.batchInsert(treeNodes);
    }

    /**
     * 修改机构和区域的关系
     * @param oldBaseOrgDO
     * @param newBaseOrgDO
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOrgTreeNode(BaseOrgDO oldBaseOrgDO,BaseOrgDO newBaseOrgDO,int level){
        if( level == OrgTree.Level.org.getLevelValue() ){
            OrgTree orgTree = orgTreeDao.findByCode(oldBaseOrgDO.getCode());
            //新修改的机构代码不存在，表示未添加过，应把相应的父类关联关系存储起来（省份，城市，区域等）
            if(null == orgTree){
                addOrgTreeNode(newBaseOrgDO);
                return;
            }
            orgTree.setCode(newBaseOrgDO.getCode());
            orgTree.setName(newBaseOrgDO.getName());
            this.save(orgTree);
        }
        else if( level == OrgTree.Level.town.getLevelValue() ){
            OrgTree orgTree = orgTreeDao.findByCodeAndParentCode(oldBaseOrgDO.getCode(),oldBaseOrgDO.getTownCode());
            //新修改的代区码不存在，表示未添加过，应把相应的父类关联关系存储起来（省份，城市，等）
            if(null == orgTree){
                addOrgTreeNode(newBaseOrgDO);
                return;
            }
            orgTree.setParentCode(newBaseOrgDO.getTownCode());
            this.save(orgTree);
        }
       else if( level == OrgTree.Level.city.getLevelValue() ){
            OrgTree orgTree = orgTreeDao.findByCodeAndParentCode(oldBaseOrgDO.getTownCode(),oldBaseOrgDO.getCityCode());
            //新修改的城市代码不存在，表示未添加过，应把相应的父类关联关系存储起来（省份等）
            if(null == orgTree){
                addOrgTreeNode(newBaseOrgDO);
                return;
            }
            orgTree.setParentCode(newBaseOrgDO.getCityCode());
            this.save(orgTree);
        }
        else if( level == OrgTree.Level.province.getLevelValue() ){
            OrgTree orgTree = orgTreeDao.findByCodeAndParentCode(oldBaseOrgDO.getCityCode(),oldBaseOrgDO.getProvinceCode());
            //新修改的省代码不存在，表示未添加过，
            if(null == orgTree){
                addOrgTreeNode(newBaseOrgDO);
                return;
            }
            orgTree.setParentCode(newBaseOrgDO.getProvinceCode());
            this.save(orgTree);
        }
    }


    /**
     * 删除机构
     * @param baseOrgDO
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByCode(BaseOrgDO baseOrgDO){
        if(StringUtils.isEmpty(baseOrgDO.getCode())){
            return;
        }
        // 删除机构code
        orgTreeDao.deleteByCode(baseOrgDO.getCode());

        // 判断该机构code所在的区下面还有没有其他机构，如果没有，该区县一并删掉
        if(!orgTreeDao.existsByParentCode(baseOrgDO.getTownCode())){
            orgTreeDao.deleteByCode(baseOrgDO.getTownCode());
        }
        // 判断该区县code所在的城市下面还有没有其他区县，如果没有，该城市一并删掉
        if(!orgTreeDao.existsByParentCode(baseOrgDO.getCityCode())){
            orgTreeDao.deleteByCode(baseOrgDO.getCityCode());
        }
        // 判断该城市code所在的省下面还有没有其他城市，如果没有，该省一并删掉
        if(!orgTreeDao.existsByParentCode(baseOrgDO.getProvinceCode())){
            orgTreeDao.deleteByCode(baseOrgDO.getProvinceCode());
        }
    }

    /**
     * 根据树的节点层级查询
     * @param level
     * @return
     */
    public List<OrgTree> findListByLevel(Integer level){
        List<OrgTree> result = new ArrayList<>();
        if(null == level){
            return result;
        }
        return orgTreeDao.findByLevelLessThanEqual(level);
    }

    /**
     * 获取区下面的机构列表
     *
     * @param townCode
     * @return
     */
    public List<Map<String, Object>> findOrgListByParentCode(String townCode) {
        List<Map<String, Object>> result = new ArrayList<>();
        if (StringUtils.isEmpty(townCode)) {
            return result;
        }
        return orgTreeDao.findOrgListByParentCode(townCode);
    }


    /**
     * 构建树形结构
     * @return
     */
    public String makeTree(List<OrgTree> orgTreeList,boolean isAllowedRepeat,boolean showLevel){
        List<TreeNode> treeNodes = new ArrayList<>();
        treeNodes.addAll(orgTreeList);
        SimpleTree tree = new SimpleTree(treeNodes,isAllowedRepeat);
        List<SimpleTreeNode> treeNode = tree.getRoot();
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        filter.getExcludes().add("parent");
        filter.getExcludes().add("allChildren");
        filter.getExcludes().add("orderNum");
        if(!showLevel){
            filter.getExcludes().add("level");
        }
        return JSONObject.toJSONString(treeNode, filter);
    }

}
