package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rongwei.bscommon.sys.dao.CxCommonDao;
import com.rongwei.bscommon.sys.service.OrgUserSyncService;
import com.rongwei.bscommon.sys.service.SlaveSourceService;
import com.rongwei.bsentity.vo.VDeptVo;
import com.rongwei.bsentity.vo.VPsndocVo;
import com.rongwei.commonservice.service.RedisService;
import com.rongwei.rwadmincommon.system.domain.SysOrganizationDo;
import com.rongwei.rwadmincommon.system.domain.SysUserDo;
import com.rongwei.rwadmincommon.system.domain.SysUserOrgDo;
import com.rongwei.rwadmincommon.system.service.SysOrganizationService;
import com.rongwei.rwadmincommon.system.service.SysUserOrgService;
import com.rongwei.rwadmincommon.system.service.SysUserService;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.safecommon.utils.SaveConstans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrgUserSyncServiceImpl implements OrgUserSyncService {

    @Autowired
    private SlaveSourceService slaveSourceService;
    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserOrgService sysUserOrgService;
    @Autowired
    private CxCommonDao commonDao;
    @Autowired
    private RedisService redisService;

    /**
     * 组织机构同步
     */
    @Override
    public void orgSync(){
        List<SysOrganizationDo> orgs = new ArrayList<>();

        List<VDeptVo> allOracleDepts = slaveSourceService.getAllOracleDepts();
        // 获取根目录
        List<VDeptVo> rootOrgs = allOracleDepts.stream().filter(v -> "~".equals(v.getPk_fatherorg())).collect(Collectors.toList());
        // 获取非根目录
        List<VDeptVo> notRootOrgs = allOracleDepts.stream().filter(v -> !"~".equals(v.getPk_fatherorg())).collect(Collectors.toList());
        // 构造所有根目录的Map
        for(int i=0;i<rootOrgs.size();i++){
            VDeptVo rootOrg = rootOrgs.get(i);
            SysOrganizationDo sysOrganizationDo = new SysOrganizationDo();
            // 字段映射
            sysOrganizationDo.setPid("-1");
            sysOrganizationDo.setTreecode((i+1)+"");
            sysOrganizationDo.setLevel(1);
            sysOrganizationDo.setSort((i+1));
            this.baseSet(sysOrganizationDo,rootOrg);

            // 递归子节点
            this.setChild(orgs,sysOrganizationDo,notRootOrgs);
            orgs.add(sysOrganizationDo);
        }
        System.out.println("******************************************");
        System.out.println(JSONUtil.toJsonStr(orgs));
        System.out.println("******************************************");
        System.out.println(JSONUtil.toJsonStr(notRootOrgs));
        // 保存数据
        saveOrgs(orgs);

        // 查询所有数据，并缓存到Redis中
        List<SysOrganizationDo> orgdos = sysOrganizationService.list();
        redisService.redisCatchInit("allOrgs",orgdos,0);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrgs(List<SysOrganizationDo> orgs){
        // 组织机构保存，先清理老数据，再保存
//        commonDao.deleteAllOrg();
        // 保存最新数据
        sysOrganizationService.saveOrUpdateBatch(orgs);
    }

    /**
     * 递归赋值子节点数据
     * @param orgs
     * @param pOrg
     * @param notRootOrgs
     */
    private void setChild(List<SysOrganizationDo> orgs,SysOrganizationDo pOrg,List<VDeptVo> notRootOrgs){
        boolean hasChild = false;
        int j = 1;
        for (int i = 0; i < notRootOrgs.size(); i++) {
            VDeptVo rootOrg = notRootOrgs.get(i);
            // 找到当前节点的所有子节点
            if(rootOrg.getPk_fatherorg() != null && rootOrg.getPk_fatherorg().equals(pOrg.getId())){
                hasChild = true;
                // 子节点赋值
                SysOrganizationDo sysOrganizationDo = new SysOrganizationDo();
                // 字段映射
                sysOrganizationDo.setPid(rootOrg.getPk_fatherorg());
                sysOrganizationDo.setTreecode(pOrg.getTreecode()+"."+j);
                sysOrganizationDo.setLevel(pOrg.getLevel()+1);
                sysOrganizationDo.setSort((i+1));
                if(StringUtils.isBlank(pOrg.getFullpid())){
                    sysOrganizationDo.setFullpid("," + rootOrg.getPk_fatherorg());
                }else{
                    sysOrganizationDo.setFullpid(pOrg.getFullpid() + "," + rootOrg.getPk_fatherorg());
                }
                this.baseSet(sysOrganizationDo,rootOrg);
                orgs.add(sysOrganizationDo);
                this.setChild(orgs,sysOrganizationDo,notRootOrgs);
                j++;
            }
        }
        // 设置父节点是否为叶子节点
        if(hasChild){
            pOrg.setIsleaf("n");
        }else{
            pOrg.setIsleaf("y");
        }
    }

    /**
     * 基本属性设置
     * @param sysOrganizationDo
     * @param rootOrg
     */
    private void baseSet(SysOrganizationDo sysOrganizationDo,VDeptVo rootOrg){
        sysOrganizationDo.setId(rootOrg.getPk_dept());
        sysOrganizationDo.setCode(rootOrg.getCode());
        sysOrganizationDo.setFullname(rootOrg.getName());
        sysOrganizationDo.setShortname(rootOrg.getName());
        if(!"~".equals(rootOrg.getPrincipal())){
            sysOrganizationDo.setChargeid(rootOrg.getPrincipal());
        }
        if(rootOrg.getEnablestate() == 2){
            sysOrganizationDo.setEnabled("y");
        }else{
            sysOrganizationDo.setEnabled("n");
        }
        sysOrganizationDo.setCreatedate(DateUtil.parse(rootOrg.getCreationtime()+".154", DatePattern.NORM_DATETIME_MS_PATTERN));
        sysOrganizationDo.setModifydate(DateUtil.parseDate(rootOrg.getTs()));
        // 设置部门类型
        String[] facs = {"1027","1028","1003"};
        List<String> faclist = Arrays.asList(facs);
        // 工厂类型
        if(sysOrganizationDo.getCode() != null && faclist.contains(sysOrganizationDo.getCode())){
            sysOrganizationDo.setOrgtype(SaveConstans.ORGTYPE_FACTORY);
        }
    }

    /**
     * 人员同步
     */
    @Override
    public void userSync(){
        // 获取OA所有用户
        List<VPsndocVo> allOracleUsers = slaveSourceService.getAllOracleUsers();
        // 获取本系统所有用户
        List<SysUserDo> users = sysUserService.list();

        // 组织UserDo对象和UserOrgDo对象
        List<SysUserDo> userDos = new ArrayList<>();
        List<SysUserOrgDo> userOrgDos = new ArrayList<>();
        // 主键ID集合
        List<String> ids = new ArrayList<>();

        for (VPsndocVo psndocVo : allOracleUsers) {
            if(ids.contains(psndocVo.getPk_psndoc())){
                List<SysUserOrgDo> hasOrgs = userOrgDos.stream().filter(v ->
                        v.getUserid().equals(psndocVo.getPk_psndoc()) && v.getOrgid().equals(psndocVo.getPk_dept()))
                        .collect(Collectors.toList());
                if(hasOrgs == null || hasOrgs.size() == 0){
                    // 用户部门表数据构造
                    if(StringUtils.isNotBlank(psndocVo.getPk_dept())){
                        SysUserOrgDo userOrgDo = new SysUserOrgDo();
                        userOrgDo.setUserid(psndocVo.getPk_psndoc());
                        userOrgDo.setOrgid(psndocVo.getPk_dept());
                        userOrgDo.setId(SecurityUtil.getUUID());
                        userOrgDos.add(userOrgDo);
                    }
                }
            }else{
                ids.add(psndocVo.getPk_psndoc());
                // 用户表数据构造
                SysUserDo userDo = new SysUserDo();
                userDo.setId(psndocVo.getPk_psndoc());
                userDo.setAccount(psndocVo.getUser_code());
                userDo.setName(psndocVo.getName());
                userDo.setCode(psndocVo.getCode());
                userDo.setEmail(psndocVo.getSecret_email());
                if("1".equals(psndocVo.getSex())){
                    userDo.setGender("male");
                } else if ("2".equals(psndocVo.getSex())) {
                    userDo.setGender("female");
                }
                userDo.setMobile(psndocVo.getMobile());
                userDo.setCreatedate(DateUtil.parseDate(psndocVo.getCreationtime()));
                userDo.setModifydate(DateUtil.parseDate(psndocVo.getTs()));
                if(StringUtils.isBlank(userDo.getAccount())){
                    userDo.setAccount(userDo.getCode());
                }
                // 设置登录密码
                List<SysUserDo> hasUser = users.stream().filter(v -> v.getId().equals(psndocVo.getPk_psndoc())).collect(Collectors.toList());
                if(hasUser != null && hasUser.size() == 1){
                    userDo.setPassword(hasUser.get(0).getPassword());
                }else{
                    userDo.setPassword(SecurityUtil.getSaltMd5AndSha("000000", userDo.getId()));
                }
                userDos.add(userDo);
                // 用户部门表数据构造
                if(StringUtils.isNotBlank(psndocVo.getPk_dept())){
                    SysUserOrgDo userOrgDo = new SysUserOrgDo();
                    userOrgDo.setUserid(userDo.getId());
                    userOrgDo.setOrgid(psndocVo.getPk_dept());
                    userOrgDo.setId(SecurityUtil.getUUID());
                    userOrgDos.add(userOrgDo);
                }
            }
        }
        // 先清除用户表删除状态的数据（deleted为1的数据）
        commonDao.deleteAllUser();
        // 数据保存
        this.userSave(userDos,userOrgDos);
    }

    /**
     * 用户相关数据保存
     * @param userDos
     * @param userOrgDos
     */
    @Transactional(rollbackFor = Exception.class)
    public void userSave(List<SysUserDo> userDos,List<SysUserOrgDo> userOrgDos){
        // 用户表和用户部门表数据保存
        if(userDos != null && userDos.size()>0){
            sysUserService.saveOrUpdateBatch(userDos);
            if(userOrgDos != null && userOrgDos.size()>0){
                // 先清除用户部门表
                commonDao.deleteAllUserDept();
                sysUserOrgService.saveBatch(userOrgDos);
            }
        }
    }
}
