package com.bcxin.platform.web.controller.obpm;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.bcxin.obpm.domain.ObpmCompany;
import com.bcxin.obpm.domain.ObpmDepartment;
import com.bcxin.obpm.domain.ObpmUser;
import com.bcxin.obpm.domain.UserDepartment;
import com.bcxin.obpm.service.ObpmCompanyService;
import com.bcxin.obpm.service.ObpmDepartmentService;
import com.bcxin.obpm.service.ObpmUserService;
import com.bcxin.obpm.service.UserDepartmentService;
import com.bcxin.platform.common.constant.Constants;
import com.bcxin.platform.common.core.domain.AjaxResult;
import com.bcxin.platform.common.core.domain.entity.SysUser;
import com.bcxin.platform.common.utils.IdWorker;
import com.bcxin.platform.common.utils.IdcardUtils;
import com.bcxin.platform.common.utils.ShiroUtils;
import com.bcxin.platform.domain.company.ComBaseInfo;
import com.bcxin.platform.domain.company.ComDepart;
import com.bcxin.platform.domain.company.PerBaseInfo;
import com.bcxin.platform.domain.company.PerOrgRelation;
import com.bcxin.platform.framework.shiro.service.SysPasswordService;
import com.bcxin.platform.service.company.ComBaseInfoService;
import com.bcxin.platform.service.company.ComDepartService;
import com.bcxin.platform.service.company.PerBaseInfoService;
import com.bcxin.platform.service.company.PerOrgRelationService;
import com.bcxin.platform.service.system.ISysConfigService;
import com.bcxin.platform.service.system.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Auther linqinglin
 * @date 2021/6/6 9:50
 */
@RestController
public class ObpmController {

    @Resource
    private ObpmCompanyService obpmCompanyService;

    @Resource
    private ObpmUserService obpmUserService;

    @Resource
    private ObpmDepartmentService obpmDepartmentService;

    @Resource
    private UserDepartmentService userDepartmentService;

    @Resource
    private ComBaseInfoService comBaseInfoService;

    @Autowired
    private ComDepartService comDepartService;

    @Autowired
    private PerBaseInfoService perBaseInfoService;

    @Autowired
    private PerOrgRelationService perOrgRelationService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private SysPasswordService passwordService;

    @Resource
    private IdWorker idWorker;


    @RequestMapping("getV5Info")
    public AjaxResult getV5Info(){
        List<ObpmCompany> comList = obpmCompanyService.selectObpmCompanyList();

        //使用线程池
        CountDownLatch workCount = ThreadUtil.newCountDownLatch(comList.size());
        ThreadPoolExecutor threadPoolExecutor = ThreadUtil.newExecutor(15, 15);
        for (ObpmCompany obpmCompany : comList) {

            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        getV5Info(obpmCompany);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        workCount.countDown();
                    }

                }
            });
        }

        try {
            //线程等待全部数据文件生成完成
            workCount.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }finally {
            threadPoolExecutor.shutdown();
        }

        return AjaxResult.success();
    }


    @RequestMapping("getV5InfoById")
    public AjaxResult getV5InfoById(String id){
        ObpmCompany obpmCompany = obpmCompanyService.selectObpmCompanyById(id);
        getV5Info(obpmCompany);
        return AjaxResult.success();
    }

    private void getV5Info(ObpmCompany obpmCompany){
        try {
            ComBaseInfo comBaseInfo = comBaseInfoService.selectComBaseInfoByTlkId(obpmCompany.getID());
            if(comBaseInfo == null) {
                comBaseInfo = new ComBaseInfo();
                comBaseInfo.setComId(idWorker.nextId());
                comBaseInfo.setIsDelete(Constants.N);
                comBaseInfo.setTlkComId(obpmCompany.getID());
                comBaseInfo.setComName(obpmCompany.getNAME());
                comBaseInfo.setRegProvince(430000);
                comBaseInfo.setRegCity(430100);
                comBaseInfo.setRegArea(430101);
                comBaseInfo.setRegAddress(obpmCompany.getREGISTERADDRESS());
                comBaseInfo.setComTreeCode(comBaseInfo.getComId().toString());
                //comBaseInfo.setTelePhone();
                comBaseInfo.setComCerNo(obpmCompany.getFIELD11());
                comBaseInfo.setComType("9");
                comBaseInfo.setComCerType("2");
                comBaseInfo.setIndustryType("0102");
                comBaseInfo.setInstitutionType("01");

                comBaseInfoService.insertComBaseInfo(comBaseInfo);
            }

            List<ObpmDepartment> departmentList = obpmDepartmentService.selectObpmDepartmentList(obpmCompany.getID());
            List<ComDepart> dbComDepartList = comDepartService.selectListByComId(comBaseInfo.getComId());
            Map<String,ComDepart> departMap = dbComDepartList.stream().collect(Collectors.toMap(ComDepart::getTlkDepartId, Function.identity()));
            List<ComDepart> comDepartList = new ArrayList<>();
            for (ObpmDepartment obpmDepartment : departmentList) {
                ComDepart comDepart = departMap.get(obpmDepartment.getID());
                if(comDepart == null){
                    comDepart = new ComDepart();
                    comDepart.setDepartId(idWorker.nextId());
                    comDepart.setIsDelete(Constants.N);
                    comDepart.setComId(comBaseInfo.getComId());
                    comDepart.setTlkDepartId(obpmDepartment.getID());
                    comDepart.setSeq(obpmDepartment.getLEVELS().intValue());
                    comDepart.setDepartName(obpmDepartment.getNAME());

                    if(StrUtil.isNotEmpty(obpmDepartment.getSUPERIOR())) {
                        ComDepart parentDepart = departMap.get(obpmDepartment.getSUPERIOR());
                        if(parentDepart != null) {
                            comDepart.setParentDepartId(parentDepart.getDepartId());
                            comDepart.setDepartTreeCode(parentDepart.getDepartTreeCode() + comDepart.getDepartId()+"-");
                        }else{
                            System.out.println("上级部门未同步");
                        }
                    }else{
                        comDepart.setParentDepartId(-1L);
                        comDepart.setDepartTreeCode(comDepart.getDepartId()+"-");
                    }
                    comDepartList.add(comDepart);
                    departMap.put(comDepart.getTlkDepartId(),comDepart);
                    //comDepartService.insertComDepart(comDepart);
                }
            }
            if(comDepartList.size() > 0) {
                comDepartService.saveBatch(comDepartList);
            }
            List<ObpmUser> obpmUserList = obpmUserService.selectObpmUserList(obpmCompany.getID());
            if(obpmUserList.size() == 0){
                return;
            }


            //根据数据数量情况，切分不同的大小
            int limit = 200;
            //计算拆分次数
            int count = new Double(Math.ceil(obpmUserList.size() * 1.0 / limit)).intValue();
            //存放拆分数据
            List<ObpmUser> subList = null;
            //循环拆分次数 生成相应数据文件
            for (int i = 0; i < count; i++) {
                subList = obpmUserList.stream().skip(i * limit).limit(limit).collect(Collectors.toList());
                List<PerBaseInfo> perBaseInfoList = new ArrayList<>();
                List<SysUser> sysUserList = new ArrayList<>();
                List<PerOrgRelation> relationList = new ArrayList<>();
                List<String> tlkIds = subList.stream().map(ObpmUser::getID).collect(Collectors.toList());
                List<String> loginNames = subList.stream().map(ObpmUser::getLOGINNO).collect(Collectors.toList());

                List<PerBaseInfo> dbPerList = perBaseInfoService.selectPerBaseInfoByTlkIds(tlkIds);
                Map<String, PerBaseInfo> perMap =dbPerList.stream().collect(Collectors.toMap(PerBaseInfo::getTlkPerId, Function.identity()));

                List<SysUser> dbUserList = sysUserService.selectByLoginNames(loginNames);
                Map<String, SysUser> userMap =dbUserList.stream().collect(Collectors.toMap(SysUser::getLoginName, Function.identity()));


                List<UserDepartment> dbDepartmentList = userDepartmentService.selectUserDepartmentList(tlkIds);
                Map<String, List<UserDepartment>> departmentMap =dbDepartmentList.stream().collect(Collectors.groupingBy(UserDepartment::getUserId));

                for (ObpmUser obpmUser : subList) {
                    PerBaseInfo perBaseInfo = perMap.get(obpmUser.getID());
                    if(perBaseInfo == null) {
                        perBaseInfo = new PerBaseInfo();
                        perBaseInfo.setPerId(idWorker.nextId());
                        perBaseInfo.setIdCardNo(obpmUser.getFIELD12());
                        //perBaseInfo.setIdCardType(obpmUser.getFIELD11());
                        //perBaseInfo.setIdCardType(obpmUser.getIdType());
                        perBaseInfo.setIdCardType(Constants.Y);
                        perBaseInfo.setIsIncumbency(Constants.Y);
                        perBaseInfo.setIsDelete(Constants.N);
                        perBaseInfo.setName(obpmUser.getNAME());
                        perBaseInfo.setMobilePhone(obpmUser.getLOGINNO());
                        perBaseInfo.setTlkPerId(obpmUser.getID());
                        perBaseInfo.setComId(comBaseInfo.getComId());
                        try {
                            perBaseInfo.setBirthDay(IdcardUtils.getBirthDayByIdCard(perBaseInfo.getIdCardNo()));
                            perBaseInfo.setSex(IdcardUtils.getGenderByIdCard(perBaseInfo.getIdCardNo()));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        perBaseInfo.setPerType("010001");

                        SysUser sysUser = userMap.get(obpmUser.getLOGINNO());

                        if(sysUser == null){
                            sysUser = new SysUser();
                            sysUser.setUserId(idWorker.nextId());
                            sysUser.setPhonenumber(obpmUser.getLOGINNO());
                            sysUser.setLoginName(obpmUser.getLOGINNO());
                            sysUser.setSalt(ShiroUtils.randomSalt());
                            sysUser.setUserName(obpmUser.getNAME());
                            sysUser.setPassword(passwordService.encryptPassword(sysUser.getLoginName(), sysConfigService.selectConfigByKey("sys.user.initPassword"), sysUser.getSalt()));
                            sysUser.setUserType("00");
                            sysUser.setStatus(Constants.N);
                            sysUser.setDelFlag(Constants.N);
                            sysUserList.add(sysUser);
                            userMap.put(sysUser.getLoginName(),sysUser);
                        }
                        perBaseInfo.setUserId(sysUser.getUserId());
                        perBaseInfoList.add(perBaseInfo);
                        List<UserDepartment> userDepartmentList = departmentMap.get(perBaseInfo.getTlkPerId());
                        if(userDepartmentList.size() > 0) {
                            for (UserDepartment userDepartment : userDepartmentList) {
                                PerOrgRelation perOrgRelation = new PerOrgRelation();
                                perOrgRelation.setPerOrgRelationId(idWorker.nextId());
                                perOrgRelation.setComId(comBaseInfo.getComId());
                                perOrgRelation.setPerId(perBaseInfo.getPerId());
                                perOrgRelation.setEntryDate(perBaseInfo.getCreateTime());
                                perOrgRelation.setTlkRelationId(userDepartment.getId());
                                ComDepart comDepart = departMap.get(userDepartment.getDepartmentId());
                                perOrgRelation.setOrgId(comDepart.getDepartId());
                                perOrgRelation.setOrgType("2");
                                relationList.add(perOrgRelation);
                            }
                        }else{
                            PerOrgRelation perOrgRelation = new PerOrgRelation();
                            perOrgRelation.setPerOrgRelationId(idWorker.nextId());
                            perOrgRelation.setOrgId(comBaseInfo.getComId());
                            perOrgRelation.setComId(comBaseInfo.getComId());
                            perOrgRelation.setPerId(perBaseInfo.getPerId());
                            perOrgRelation.setOrgType("1");
                            perOrgRelation.setTlkRelationId(null);
                            relationList.add(perOrgRelation);
                        }
                    }
                }
                if(relationList.size() > 0) {
                    perOrgRelationService.saveBatch(relationList);
                }

                if(sysUserList.size() > 0) {
                    sysUserService.saveBatch(sysUserList);
                }

                if(perBaseInfoList.size() > 0) {
                    perBaseInfoService.saveBatch(perBaseInfoList);
                }
            }



        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }
}
