package com.dgtly.sync.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dgtly.common.exception.BusinessException;
import com.dgtly.sync.domain.MetaNipponOrgRelation;
import com.dgtly.sync.domain.SyncFailDetail;
import com.dgtly.sync.domain.SyncLog;
import com.dgtly.sync.exception.EndLessLoopParentException;
import com.dgtly.sync.exception.NotFoundParentException;
import com.dgtly.sync.mapper.SyncFailDetailMapper;
import com.dgtly.sync.service.IAnalysisDeptService;
import com.dgtly.sync.service.IMetaNipponOrgRelationService;
import com.dgtly.sync.service.ISyncLogService;
import com.dgtly.system.domain.SysDept;
import com.dgtly.system.mapper.SysDeptMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AnalysisDeptService  implements IAnalysisDeptService {

    private static final Logger log = LoggerFactory.getLogger(AnalysisDeptService.class);


    @Autowired
    private IMetaNipponOrgRelationService metaNipponOrgRelationService;
    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SyncFailDetailMapper syncFailDetailMapper;
    @Autowired
    private ISyncLogService syncLogService;



    /**
     * 解析部门数据  异步执行
     * @param packageId
     * @return
     */
    @Override
    @Async
    public SyncLog analysisDept(String packageId){
        //查询所需要的基础数据
        MetaNipponOrgRelation selectParam = new MetaNipponOrgRelation();
        selectParam.setPackageId(packageId);
        List<MetaNipponOrgRelation> list =  metaNipponOrgRelationService.selectMetaNipponOrgRelationList(selectParam);

        SyncLog syncLog = new SyncLog();
        syncLog.setSyncType("dept");
        syncLog.setStartTime(new Date());
        syncLog.setPackageId(packageId);
        syncLog.setTotalCount((long)list.size());
        List<SyncFailDetail> failDetails = new ArrayList<>();
        long successCount = 0;
        long failCount = 0;
        if(list.size()>0){
            List<SysDept> sysDepts = sysDeptMapper.selectDeptList(new SysDept());
            //待插入或更新的list转HashMap提高查找效率  部门id  部门
            Map<Long,MetaNipponOrgRelation> nMap = new HashMap<>();
            for (MetaNipponOrgRelation n:list){
                nMap.put(n.getObjid(),n);
            }
            //已存在部门转HashMap提高查找效率 父id  祖籍列表值
            Map<Long,String> ancestorsMap = new HashMap<>();
            List<Long> sysDeptIdList = new ArrayList<>();
            for(SysDept sysDept:sysDepts){
                ancestorsMap.put(sysDept.getDeptId(),sysDept.getAncestors());
                sysDeptIdList.add(sysDept.getDeptId());
            }


            for(int i=0;i< list.size();i++){
                MetaNipponOrgRelation n = list.get(i);
                SysDept dept = orgRelation2SysDept(n);
                Long id = n.getObjid();

                //获取祖籍列表 ancestors 字段
                String ancestors = "";
                Set<Long> idSet = new HashSet<>();
                try {
                    //  递归查询祖籍列表
                    ancestors = getAncestors(n,ancestorsMap,nMap,idSet);
                    dept.setAncestors(ancestors);
                    //判断是添加还是更新
                    if(sysDeptIdList.contains(id)){
                        sysDeptMapper.updateDept(dept);
                    }else{
                        sysDeptMapper.insertDeptReturnId(dept);
                    }
                    successCount++;
                }catch (Exception e){
                    failCount++;
                    SyncFailDetail syncFailDetail = new SyncFailDetail();
                    syncFailDetail.setPackageId(packageId);
                    syncFailDetail.setFailReason(e.getMessage());
                    syncFailDetail.setDataJson(JSONObject.toJSONString(n));
                    failDetails.add(syncFailDetail);
                    e.printStackTrace();
                    log.error("解析部门出错",e);
                }
            }
            syncLog.setSuccessCount(successCount);
            syncLog.setFaileCount(failCount);
        }else{
            syncLog.setSuccessCount(0l);
            syncLog.setFaileCount(0l);
        }
        try{
            syncLog.setEndTime(new Date());
            if(failDetails.size()>0){
                syncFailDetailMapper.batchInsertSyncFailDetail(failDetails);
            }
        }catch (Exception e){
            log.error("解析部门插入解析日志出错",e);
            e.printStackTrace();
            throw new BusinessException("解析部门插入解析日志出错",e);
        }finally {
            syncLogService.insertSyncLog(syncLog);
        }
        return syncLog;
    }


    /***
     *  递归查询祖籍列表
     */
    public String getAncestors(MetaNipponOrgRelation nipponOrgRelation, Map<Long,String> ancestorsMap, Map<Long,MetaNipponOrgRelation> listMap,Set<Long> idSet){
        String ancestors ="";
        Long parentId =Long.parseLong(nipponOrgRelation.getSobid());
        Long id = nipponOrgRelation.getObjid();
        idSet.add(id);
       //防止死循环
        if(idSet.contains(parentId)){

            ancestorsMap.put(id,"error");
            throw new EndLessLoopParentException(nipponOrgRelation);
        }
        if(ancestorsMap.containsKey(parentId)){
            if(ancestorsMap.get(parentId).equals("error")){
                throw new NotFoundParentException(nipponOrgRelation);
            }
            //所属事项的父事项存在数据库中
            ancestors = ancestorsMap.get(parentId)+","+id;
            ancestorsMap.put(id,ancestors);
        }else{
            //父事项不存存在父数据库中  前往当前列表中查询
            if(listMap.containsKey(parentId)){
                nipponOrgRelation = listMap.get(parentId);
                id  = nipponOrgRelation.getObjid();
                ancestors= getAncestors(nipponOrgRelation,ancestorsMap,listMap,idSet)+","+id;
                ancestorsMap.put(id,ancestors);
            }else{
                ancestorsMap.put(id,"error");
                throw new NotFoundParentException(nipponOrgRelation);
            }

        }
        return ancestors;
    }

    private SysDept orgRelation2SysDept(MetaNipponOrgRelation metaNipponOrgRelation){
        SysDept dept = new SysDept();
        Long id = metaNipponOrgRelation.getObjid();
        Long parentId = Long.parseLong(metaNipponOrgRelation.getSobid());
        //构建插入或更新的部门信息
        dept.setDeptName(metaNipponOrgRelation.getStext());
        dept.setRemark(metaNipponOrgRelation.getShort());
        dept.setDeptId(id);
        dept.setParentId(parentId);
        dept.setCompanyId(1l);
        return dept;
    }

}
