package com.engine.organization.thread;

import com.engine.common.util.ServiceUtil;
import com.engine.hrm.service.impl.HrmJobServiceImpl;
import com.engine.hrm.service.impl.OrganizationServiceImpl;
import com.engine.organization.entity.commom.RecordInfo;
import com.engine.organization.entity.company.po.CompPO;
import com.engine.organization.entity.department.po.DepartmentPO;
import com.engine.organization.entity.extend.param.ExtendInfoParams;
import com.engine.organization.entity.job.po.JobPO;
import com.engine.organization.enums.LogModuleNameEnum;
import com.engine.organization.enums.OperateTypeEnum;
import com.engine.organization.mapper.comp.CompMapper;
import com.engine.organization.mapper.department.DepartmentMapper;
import com.engine.organization.mapper.extend.ExtMapper;
import com.engine.organization.mapper.hrmresource.SystemDataMapper;
import com.engine.organization.mapper.job.JobMapper;
import com.engine.organization.util.db.MapperProxyFactory;
import com.engine.organization.util.relation.EcHrmRelationUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import weaver.general.Util;
import weaver.hrm.User;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author:dxfeng
 * @createTime: 2022/07/12
 * @version: 1.0
 */
public class OrganizationRunable implements Runnable {
    private LogModuleNameEnum moduleName;
    private OperateTypeEnum operateType;
    private Map<String, Object> params;
    private User user;
    private JobPO oldJobPO;

    private static final String HRM_COMPANY = "hrmsubcompany";
    private static final String HRM_DEPARTMENT = "hrmdepartment";

    private static final String JCL_COMPANY = "jcl_org_comp";
    private static final String JCL_DEPARTMENT = "jcl_org_dept";

    private SystemDataMapper getSystemDataMapper() {
        return MapperProxyFactory.getProxy(SystemDataMapper.class);
    }

    private ExtMapper getExtMapper() {
        return MapperProxyFactory.getProxy(ExtMapper.class);
    }

    public OrganizationRunable(User user, LogModuleNameEnum moduleName, OperateTypeEnum operateType, Map<String, Object> params) {
        this.moduleName = moduleName;
        this.operateType = operateType;
        this.params = params;
        this.user = user;
    }

    public OrganizationRunable(User user, LogModuleNameEnum moduleName, OperateTypeEnum operateType, Map<String, Object> params, JobPO oldJobPO) {
        this.moduleName = moduleName;
        this.operateType = operateType;
        this.params = params;
        this.user = user;
        this.oldJobPO = oldJobPO;
    }


    @Override
    public void run() {
        switch (moduleName) {
            case COMPANY:
                refreshCompany();
                break;
            case DEPARTMENT:
                refreshDepartment();
                break;
            case JOB:
                refreshJob();
                break;
            default:
                break;
        }
    }

    /**
     * 刷新HrmSubCompany表数据
     */
    private void refreshCompany() {
        switch (operateType) {
            case ADD:
                addCompany();
                break;
            case UPDATE:
                updateCompany();
                break;
            case CANCELED:
                cancelCompany();
                break;
            default:
                break;
        }
    }

    /**
     * 刷新HrmDepartment表数据
     */
    private void refreshDepartment() {
        switch (operateType) {
            case ADD:
                addDepartment();
                break;
            case UPDATE:
                updateDepartment();
                break;
            case CANCELED:
                cancelDepartment();
                break;
            default:
                break;
        }
    }

    private void refreshJob() {
        switch (operateType) {
            case ADD:
                addJob();
                break;
            case UPDATE:
                updateJob();
                break;
            case CANCELED:
                cancelJob();
                break;
            default:
                break;
        }
    }

    /**
     * 新增岗位
     *
     * <p>
     * 1、EC表HrmJobTitles
     * <p>
     * 2、系统中新建“聚才林”、“默认职务”（sql写入）
     * <p>
     * 3、检索岗位名称jobtitlename，如果已存在，判断是否封存，对已封存数据解封操作
     * <p>
     * 4、如果不存在，在“聚才林--默认职务”下新建岗位
     */
    private void addJob() {
        // 判断是否存在同名岗位、存在不做处理，不存在，在“默认职务分类--默认职务”下新建岗位
        String jobName = Util.null2String(params.get("job_name"));
        RecordInfo hrmJobActivity = getSystemDataMapper().getHrmJobTitleByName(jobName);
        Map<String, Object> map = new HashMap<>();
        //存在且已封存，对岗位解封
        if (null != hrmJobActivity && "1".equals(hrmJobActivity.getCanceled())) {
            map.put("ids", hrmJobActivity.getId());
            map.put("canceled", "docanceled");
            ServiceUtil.getService(HrmJobServiceImpl.class, user).doCanceled(map, user);
        } else {
            // 不存在则新建职务
            map.put("operateIp", Util.null2String(user.getLoginip()));
            map.put("jobtitlemark", jobName);
            map.put("jobtitlename", jobName);
            map.put("jobactivityid", Util.null2String(params.get("jobactivityid")));
            map.put("jobresponsibility", Util.null2String(params.get("work_duty")));
            map.put("jobcompetency", Util.null2String(params.get("work_authority")));
            map.put("jobtitleremark", Util.null2String(params.get("description")));
            map.put("jobtitlecode", Util.null2String(params.get("job_no")));

            ServiceUtil.getService(HrmJobServiceImpl.class, user).addJobTitle(map, user);
        }
    }

    /**
     * 更新岗位
     */
    private void updateJob() {
        Long jclJobId = oldJobPO.getId();
        String oldName = oldJobPO.getJobName();

        String newName = Util.null2String(params.get("job_name"));
        RecordInfo oldHrmJobTitle = getSystemDataMapper().getHrmJobTitleByName(oldName);

        Map<String, Object> map = new HashMap<>();
        // 修改前不存在共用
        if (EcHrmRelationUtil.isNotExistJob(oldName, jclJobId)) {
            // 修改后不存在共用、直接修改EC岗位表数据
            if (EcHrmRelationUtil.isNotExistJob(newName, jclJobId)) {
                // 查询ec表ID
                RecordInfo hrmJobTitle = getSystemDataMapper().getHrmJobTitleByName(oldName);
                map.put("id", Util.null2String(hrmJobTitle.getId()));
                map.put("operateIp", Util.null2String(user.getLoginip()));
                map.put("jobtitlemark", newName);
                map.put("jobtitlename", newName);
                map.put("jobactivityid", Util.null2String(params.get("jobactivityid")));
                map.put("jobresponsibility", Util.null2String(params.get("work_duty")));
                map.put("jobcompetency", Util.null2String(params.get("work_authority")));
                map.put("jobtitleremark", Util.null2String(params.get("description")));
                map.put("jobtitlecode", Util.null2String(params.get("job_no")));
                // 修改岗位表数据
                ServiceUtil.getService(HrmJobServiceImpl.class, user).editJobTitle(map, user);
            } else {
                // 修改后存在共用、不修改岗位表数据，更新对应人员的岗位信息为当前岗位的ID
                RecordInfo hrmJobTitle = getSystemDataMapper().getHrmJobTitleByName(newName);
                // 查询原分部、原岗位下的人员，并更新岗位ID
                List<Long> hrmResourceIds = getSystemDataMapper().getHrmResourceIds(oldJobPO.getParentDept(), oldHrmJobTitle.getId());
                getSystemDataMapper().updateResourceJobTitleByIds(Util.null2String(hrmJobTitle.getId()), hrmResourceIds);
                // 封存原名称岗位
                map.clear();
                map.put("ids", oldHrmJobTitle.getId());
                map.put("canceled", "canceled");
                ServiceUtil.getService(HrmJobServiceImpl.class, user).doCanceled(map, user);
            }
        } else {
            // 修改前存在共用，不对原有数据进行操作。

            // 修改后不存在共用、新建岗位，更新原有岗位下人员的岗位ID
            if (EcHrmRelationUtil.isNotExistJob(newName, jclJobId)) {
                // 不存在则新建职务
                map.put("operateIp", Util.null2String(user.getLoginip()));
                map.put("jobtitlemark", newName);
                map.put("jobtitlename", newName);
                map.put("jobactivityid", Util.null2String(params.get("jobactivityid")));
                map.put("jobresponsibility", Util.null2String(params.get("work_duty")));
                map.put("jobcompetency", Util.null2String(params.get("work_authority")));
                map.put("jobtitleremark", Util.null2String(params.get("description")));
                map.put("jobtitlecode", Util.null2String(params.get("job_no")));
                ServiceUtil.getService(HrmJobServiceImpl.class, user).addJobTitle(map, user);
                // 新建岗位
                RecordInfo hrmJobTitle = getSystemDataMapper().getHrmJobTitleByName(newName);
                // 查询原分部、原岗位下的人员，并更新岗位ID
                List<Long> hrmResourceIds = getSystemDataMapper().getHrmResourceIds(oldJobPO.getParentDept(), oldHrmJobTitle.getId());
                getSystemDataMapper().updateResourceJobTitleByIds(Util.null2String(hrmJobTitle.getId()), hrmResourceIds);
            } else {
                // 修改后存在共用，更新原有岗位下人员的岗位ID
                RecordInfo hrmJobTitle = getSystemDataMapper().getHrmJobTitleByName(newName);
                // 查询原分部、原岗位下的人员，并更新岗位ID
                List<Long> hrmResourceIds = getSystemDataMapper().getHrmResourceIds(oldJobPO.getParentDept(), oldHrmJobTitle.getId());
                getSystemDataMapper().updateResourceJobTitleByIds(Util.null2String(hrmJobTitle.getId()), hrmResourceIds);
            }
        }
    }

    /**
     * 封存、解封岗位
     */
    private void cancelJob() {
        Map<String, Object> map = new HashMap<>();
        RecordInfo hrmJobTitleByName = getSystemDataMapper().getHrmJobTitleByName(oldJobPO.getJobName());
        if (0 == oldJobPO.getForbiddenTag()) {
            // 启用
            map.put("ids", hrmJobTitleByName.getId());
            map.put("canceled", "docanceled");
            ServiceUtil.getService(HrmJobServiceImpl.class, user).doCanceled(map, user);
        } else {
            // 禁用
            List<JobPO> jobPOS = MapperProxyFactory.getProxy(JobMapper.class).listByNameExceptId(oldJobPO.getJobName(), oldJobPO.getId());
            // 不存在共用
            if (CollectionUtils.isEmpty(jobPOS)) {
                map.put("ids", hrmJobTitleByName.getId());
                map.put("canceled", "canceled");
                ServiceUtil.getService(HrmJobServiceImpl.class, user).doCanceled(map, user);
            } else {
                List<JobPO> collect = jobPOS.stream().filter(item -> 0 == item.getForbiddenTag()).collect(Collectors.toList());
                // 不存在非禁用
                if (CollectionUtils.isEmpty(collect)) {
                    map.put("ids", hrmJobTitleByName.getId());
                    map.put("canceled", "canceled");
                    ServiceUtil.getService(HrmJobServiceImpl.class, user).doCanceled(map, user);
                }
            }
        }
    }

    /**
     * 新增部门
     */
    private void addDepartment() {
        Map<String, Object> map = new HashMap<>();
        map.put("departmentmark", Util.null2String(params.get("dept_name_short")));
        map.put("departmentname", Util.null2String(params.get("dept_name")));

        // 上级分部通过UUID联查ec表ID
        String parentCompany = Util.null2String(params.get("parent_comp"));
        if (StringUtils.isNotBlank(parentCompany)) {
            map.put("subcompanyid1", EcHrmRelationUtil.getEcCompanyId(parentCompany));
        }

        // 上级部门通过UUID联查ec表ID
        String parentDepartment = Util.null2String(params.get("parent_dept"));
        if (StringUtils.isNotBlank(parentDepartment)) {
            map.put("supdepid", EcHrmRelationUtil.getEcDepartmentId(parentDepartment));
        }

        map.put("showorder", Util.null2String(params.get("show_order")));
        map.put("departmentcode", Util.null2String(params.get("dept_no")));
        map.put("coadjutant", Util.null2String(params.get("dept_principal")));
        Map<String, Object> returnMap = ServiceUtil.getService(OrganizationServiceImpl.class, user).addDepartment(map, user);
        // 更新jcl_org_dept表 uuid字段
        if ("1".equals(Util.null2String(returnMap.get("status"))) && null != returnMap.get("id")) {
            updateJclUUID(Util.null2String(returnMap.get("id")), HRM_DEPARTMENT, JCL_DEPARTMENT);
        }
    }

    /**
     * 封存、解封部门
     */
    private void cancelDepartment() {
        String departmentIds = Util.null2String(params.get("id"));
        String forbiddenTag = Util.null2String(params.get("forbiddenTag"));
        List<String> idList = new ArrayList<>();
        String[] split = departmentIds.split(",");
        if (StringUtils.isBlank(forbiddenTag)) {
            long currentTimeMillis = System.currentTimeMillis();
            for (String s : split) {
                DepartmentPO departmentPO = MapperProxyFactory.getProxy(DepartmentMapper.class).getDeptById(Long.parseLong(s));
                params.put("dept_name_short", departmentPO.getDeptNameShort() + currentTimeMillis);
                params.put("dept_name", departmentPO.getDeptName() + currentTimeMillis);
                params.put("parent_comp", departmentPO.getParentComp());
                params.put("parent_dept", departmentPO.getParentDept());
                params.put("show_order", departmentPO.getShowOrder());
                params.put("dept_no", departmentPO.getDeptNo());
                params.put("dept_principal", departmentPO.getDeptPrincipal());
                updateDepartment();
                idList.add(EcHrmRelationUtil.getEcDepartmentId(s));
            }
        } else {
            for (String s : split) {
                idList.add(EcHrmRelationUtil.getEcDepartmentId(s));
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", StringUtils.join(idList, ","));
        if ("0".equals(forbiddenTag)) {
            // 解封
            ServiceUtil.getService(OrganizationServiceImpl.class, user).doDepartmentISCanceled(map, user);
        } else {
            // 封存
            ServiceUtil.getService(OrganizationServiceImpl.class, user).doDepartmentCancel(map, user);
        }
    }

    /**
     * 更新部门
     */
    private void updateDepartment() {
        Map<String, Object> map = new HashMap<>();
        // 获取ec表ID
        map.put("id", EcHrmRelationUtil.getEcDepartmentId(Util.null2String(params.get("id"))));
        map.put("departmentmark", Util.null2String(params.get("dept_name_short")));
        map.put("departmentname", Util.null2String(params.get("dept_name")));

        // 上级分部通过UUID联查ec表ID
        String parentCompany = Util.null2String(params.get("parent_comp"));
        if (StringUtils.isNotBlank(parentCompany)) {
            map.put("subcompanyid1", EcHrmRelationUtil.getEcCompanyId(parentCompany));
        }

        // 上级部门通过UUID联查ec表ID
        String parentDepartment = Util.null2String(params.get("parent_dept"));
        if (StringUtils.isNotBlank(parentDepartment)) {
            map.put("supdepid", EcHrmRelationUtil.getEcDepartmentId(parentDepartment));
        }

        map.put("showorder", Util.null2String(params.get("show_order")));
        map.put("departmentcode", Util.null2String(params.get("dept_no")));
        map.put("coadjutant", Util.null2String(params.get("dept_principal")));
        ServiceUtil.getService(OrganizationServiceImpl.class, user).editDepartment(map, user);
    }

    /**
     * 新增分部
     */
    private void addCompany() {
        Map<String, Object> map = new HashMap<>();
        map.put("subcompanyname", Util.null2String(params.get("comp_name_short")));

        // 上级分部通过UUID联查ec表ID
        String parentCompany = Util.null2String(params.get("parent_company"));
        if (StringUtils.isNotBlank(parentCompany)) {
            map.put("supsubcomid", EcHrmRelationUtil.getEcCompanyId(parentCompany));
        }

        map.put("subcompanycode", params.get("comp_no").toString());
        map.put("subcompanydesc", params.get("comp_name").toString());
        map.put("showorder", Util.null2String(params.get("show_order")));
        Map<String, Object> returnMap = ServiceUtil.getService(OrganizationServiceImpl.class, user).addSubCompany(map, user);

        // 更新jcl_org_comp表 uuid字段
        if ("1".equals(Util.null2String(returnMap.get("status"))) && null != returnMap.get("id")) {
            updateJclUUID(Util.null2String(returnMap.get("id")), HRM_COMPANY, JCL_COMPANY);
        }
    }

    /**
     * 更新分部
     */
    private void updateCompany() {
        Map<String, Object> map = new HashMap<>();
        // 获取ec表ID
        map.put("id", EcHrmRelationUtil.getEcCompanyId(Util.null2String(params.get("id"))));

        // 上级分部通过UUID联查ec表ID
        String parentCompany = Util.null2String(params.get("parent_company"));
        if (StringUtils.isNotBlank(parentCompany)) {
            map.put("supsubcomid", EcHrmRelationUtil.getEcCompanyId(parentCompany));
        }
        map.put("subcompanycode", Util.null2String(params.get("comp_no")));
        map.put("subcompanyname", Util.null2String(params.get("comp_name_short")));
        map.put("subcompanydesc", Util.null2String(params.get("comp_name")));
        map.put("showorder", Util.null2String(params.get("show_order")));
        ServiceUtil.getService(OrganizationServiceImpl.class, user).editSubCompany(map, user);
    }

    /**
     * 封存、解封分部
     */
    private void cancelCompany() {
        String companyIds = Util.null2String(params.get("id"));
        String forbiddenTag = Util.null2String(params.get("forbiddenTag"));
        List<String> idList = new ArrayList<>();
        String[] split = companyIds.split(",");
        if (StringUtils.isBlank(forbiddenTag)) {
            long currentTimeMillis = System.currentTimeMillis();
            for (String s : split) {
                // 更新名称为：名称+时间戳
                CompPO comp = MapperProxyFactory.getProxy(CompMapper.class).listById(Long.parseLong(s));
                params.put("parent_company", comp.getParentCompany());
                params.put("comp_no", comp.getCompNo());
                params.put("comp_name", comp.getCompName() + currentTimeMillis);
                params.put("comp_name_short", comp.getCompNameShort() + currentTimeMillis);
                params.put("show_order", comp.getShowOrder());
                updateCompany();
                idList.add(EcHrmRelationUtil.getEcCompanyId(s));
            }
        } else {
            for (String s : split) {
                idList.add(EcHrmRelationUtil.getEcCompanyId(s));
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", StringUtils.join(idList, ","));

        if ("0".equals(forbiddenTag)) {
            // 解封
            ServiceUtil.getService(OrganizationServiceImpl.class, user).doSubCompanyISCanceled(map, user);
        } else {
            // 删除封存、禁用封存
            ServiceUtil.getService(OrganizationServiceImpl.class, user).doSubCompanyCancel(map, user);
        }
    }


    /**
     * 更新聚才林组织UUID
     *
     * @param id
     * @param ecTableName
     * @param jclTableName
     */
    private void updateJclUUID(String id, String ecTableName, String jclTableName) {
        RecordInfo hrmDepartment = getSystemDataMapper().getHrmObjectByID(ecTableName, id);
        String uuid = hrmDepartment.getUuid();
        Map<String, Object> departmentMap = new HashMap<>();
        departmentMap.put("uuid", uuid);
        long jclTableId = Long.parseLong(Util.null2String(params.get("id")));
        ExtendInfoParams infoParams = ExtendInfoParams.builder().tableName(jclTableName).params(departmentMap).id(jclTableId).build();
        getExtMapper().updateTable(infoParams);
    }

}
