package com.engine.salary.timer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.engine.common.util.ServiceUtil;
import com.engine.salary.encrypt.EncryptUtil;
import com.engine.salary.entity.siarchives.param.InsuranceArchivesListParam;
import com.engine.salary.entity.siarchives.po.InsuranceArchivesEmployeePO;
import com.engine.salary.entity.siarchives.po.InsuranceArchivesFundSchemePO;
import com.engine.salary.entity.siarchives.po.InsuranceArchivesSocialSchemePO;
import com.engine.salary.entity.siarchives.po.UfHrSbjsgzbPO;
import com.engine.salary.enums.siaccount.EmployeeStatusEnum;
import com.engine.salary.mapper.siarchives.FundSchemeMapper;
import com.engine.salary.mapper.siarchives.SocialSchemeMapper;
import com.engine.salary.service.SIArchivesService;
import com.engine.salary.service.UfHrSbjsgzbService;
import com.engine.salary.service.impl.SIArchivesServiceImpl;
import com.engine.salary.service.impl.UfHrSbjsgzbServiceImpl;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.sys.enums.OpenEnum;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.interfaces.schedule.BaseCronJob;

import java.util.*;
import java.util.stream.Collectors;

import static com.engine.salary.sys.constant.SalarySysConstant.WEL_BASE_DIFF_BY_PER_AND_COM;

/**
 * @ClassName SyncSIBaseJob
 * @author Harryxzy
 * @date 2024/12/20 9:55
 * @description 中航富士达 设置员工社保福利档案基数
 */
@Slf4j
public class SyncSIBaseJob extends BaseCronJob {

    private UfHrSbjsgzbService getUfHrSbjsgzbService(User user) {
        return ServiceUtil.getService(UfHrSbjsgzbServiceImpl.class, user);
    }

    private SocialSchemeMapper getSocialSchemeMapper() {
        return MapperProxyFactory.getProxy(SocialSchemeMapper.class);
    }

    public SIArchivesService getSIArchivesService(User user) {
        return ServiceUtil.getService(SIArchivesServiceImpl.class,user);
    }

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }

    private FundSchemeMapper getFundSchemeMapper() {
        return MapperProxyFactory.getProxy(FundSchemeMapper.class);
    }

    @Override
    public void execute() {
        User user = new User();
        user.setUid(1);
        EncryptUtil encryptUtil = new EncryptUtil();
        // 获取建模基数信息
        List<UfHrSbjsgzbPO> ufHrSbjsgzbList = getUfHrSbjsgzbService(user).listAll();
        // 岗位规则
        Map<Long, UfHrSbjsgzbPO> gwGzMap = new HashMap<>();
        // 岗位分类规则
        Map<Long, List<UfHrSbjsgzbPO>> gwflGzMap = new HashMap<>();
        // 工龄规则
        List<UfHrSbjsgzbPO> glGzList = new ArrayList<>();
        for (UfHrSbjsgzbPO po : ufHrSbjsgzbList) {
            if (StringUtils.isNotBlank(po.getGw())) {
                // 岗位不为空
                Arrays.stream(po.getGw().split(","))
                        .map(Long::valueOf)
                        .forEach(gw -> {
                            gwGzMap.put(Long.valueOf(gw), po);
                        });
            } else if (NumberUtils.isCreatable(po.getGwfl())) {
                // 岗位分类（职务）不为空
                List<UfHrSbjsgzbPO> list = gwflGzMap.computeIfAbsent(Long.valueOf(NumberUtils.isCreatable(po.getGwfl()) ? po.getGwfl() : "0"), k -> new ArrayList<>());
                list.add(po);
                gwflGzMap.put(Long.valueOf(po.getGwfl()), list);
            } else {
                // 剩余根据工龄匹配
                glGzList.add(po);
            }
        }

        // 获取社保福利档案信息（只获取在缴、待减员数据）
        List<String> statusList = Arrays.asList(EmployeeStatusEnum.PAYING.getValue(), EmployeeStatusEnum.STAY_DEL.getValue());
        InsuranceArchivesListParam archivesListParam = InsuranceArchivesListParam.builder().runStatuses(statusList).build();
        List<InsuranceArchivesEmployeePO> insuranceArchivesEmployeePOS = getSocialSchemeMapper().queryEmployeeList(archivesListParam);
        // 获取这些人的社保具体数据
        List<Long> socialIdList = insuranceArchivesEmployeePOS.stream().map(InsuranceArchivesEmployeePO::getSocialId).collect(Collectors.toList());
        List<InsuranceArchivesSocialSchemePO> socialArchiveList = getSIArchivesService(user).listInsuranceArchivesSocialSchemeByIds(socialIdList);
        encryptUtil.decryptList(socialArchiveList, InsuranceArchivesSocialSchemePO.class);
        Map<Long, InsuranceArchivesSocialSchemePO> socialArchiveMap = SalaryEntityUtil.convert2Map(socialArchiveList, InsuranceArchivesSocialSchemePO::getId);
        // 获取这些人的公积金具体数据
        List<Long> fundIdList = insuranceArchivesEmployeePOS.stream().map(InsuranceArchivesEmployeePO::getFundId).collect(Collectors.toList());
        List<InsuranceArchivesFundSchemePO> fundArchiveList = getSIArchivesService(user).listInsuranceArchivesFundSchemeByIds(fundIdList);
        encryptUtil.decryptList(fundArchiveList, InsuranceArchivesFundSchemePO.class);
        Map<Long, InsuranceArchivesFundSchemePO> fundArchiveMap = SalaryEntityUtil.convert2Map(fundArchiveList, InsuranceArchivesFundSchemePO::getId);

        //判断是否要区分个人和单位福利基数
        SalarySysConfPO welBaseDiff = getSalarySysConfService(user).getOneByCode(WEL_BASE_DIFF_BY_PER_AND_COM);
        boolean welBaseDiffSign = welBaseDiff != null && welBaseDiff.getConfValue().equals(OpenEnum.OPEN.getValue());

        insuranceArchivesEmployeePOS.stream().forEach(archiveEmp -> {
            // 确定唯一规则
            UfHrSbjsgzbPO gzPO = getSIArchivesService(user).getGzByEmp(archiveEmp, gwGzMap, gwflGzMap, glGzList);
            // 处理社保数据
            InsuranceArchivesSocialSchemePO socialArchive = socialArchiveMap.get(archiveEmp.getSocialId());
            if (socialArchive != null && socialArchive.getSocialSchemeId() != null && gzPO != null) {
                Map<String, Object> socialJson = JSON.parseObject(socialArchive.getSocialPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (socialJson != null) {
                    for (Map.Entry<String, Object> entry : socialJson.entrySet()) {
                        if (entry.getKey().equals("9001")) {
                            socialJson.put("9001",Util.null2String(gzPO.getYanglaojs()));
                        } else if (entry.getKey().equals("9002")) {
                            socialJson.put("9002",Util.null2String(gzPO.getYiliaojs()));
                        } else if (entry.getKey().equals("9003")) {
                            socialJson.put("9003",Util.null2String(gzPO.getGongshangjs()));
                        } else if (entry.getKey().equals("9004")) {
                            socialJson.put("9004",Util.null2String(gzPO.getShiyejs()));
                        } else if (entry.getKey().equals("9005")) {
                            socialJson.put("9005",Util.null2String(gzPO.getShengyujs()));
                        }
                    }
                    socialArchive.setSocialPaymentBaseString(JSON.toJSONString(socialJson));
                    socialArchive.setUpdateTime(new Date());
                }
                //如果需要区分个人和公司福利基数
                if (welBaseDiffSign) {
                    Map<String, Object> socialComJson = JSON.parseObject(socialArchive.getSocialPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (socialComJson != null) {
                        for (Map.Entry<String, Object> entry : socialComJson.entrySet()) {
                            if (entry.getKey().equals("9001")) {
                                socialComJson.put("9001",Util.null2String(gzPO.getYanglaojs()));
                            } else if (entry.getKey().equals("9002")) {
                                socialComJson.put("9002",Util.null2String(gzPO.getYiliaojs()));
                            } else if (entry.getKey().equals("9003")) {
                                socialComJson.put("9003",Util.null2String(gzPO.getGongshangjs()));
                            } else if (entry.getKey().equals("9004")) {
                                socialComJson.put("9004",Util.null2String(gzPO.getShiyejs()));
                            } else if (entry.getKey().equals("9005")) {
                                socialComJson.put("9005",Util.null2String(gzPO.getShengyujs()));
                            }
                        }
                        socialArchive.setSocialPaymentComBaseString(JSON.toJSONString(socialComJson));
                    }
                }
                // 更新(加密)
                encryptUtil.encrypt(socialArchive, InsuranceArchivesSocialSchemePO.class);
                getSocialSchemeMapper().updateById(socialArchive);
            }

            // 处理公积金数据
            InsuranceArchivesFundSchemePO fundArchive = fundArchiveMap.get(archiveEmp.getFundId());
            if (fundArchive != null && fundArchive.getFundSchemeId() != null && gzPO != null) {
                Map<String, Object> fundJson = JSON.parseObject(fundArchive.getFundPaymentBaseString(), new TypeReference<Map<String, Object>>() {
                });
                if (fundJson != null) {
                    for (Map.Entry<String, Object> entry : fundJson.entrySet()) {
                        if (entry.getKey().equals("9006")) {
                            fundJson.put("9006", Util.null2String(gzPO.getGjjjs()));
                        }
                    }
                    fundArchive.setFundPaymentBaseString(JSON.toJSONString(fundJson));
                    fundArchive.setUpdateTime(new Date());
                }
                //如果需要区分个人和公司福利基数
                if (welBaseDiffSign) {
                    Map<String, Object> fundComJson = JSON.parseObject(fundArchive.getFundPaymentComBaseString(), new TypeReference<Map<String, Object>>() {
                    });
                    if (fundComJson != null) {
                        for (Map.Entry<String, Object> entry : fundComJson.entrySet()) {
                            if (entry.getKey().equals("9006")) {
                                fundComJson.put("9006",Util.null2String(gzPO.getGjjjs()));
                            }
                        }
                        fundArchive.setFundPaymentComBaseString(JSON.toJSONString(fundComJson));
                    }
                }
                // 更新(加密)
                encryptUtil.encrypt(fundArchive, InsuranceArchivesFundSchemePO.class);
                getFundSchemeMapper().updateById(fundArchive);
            }
        });
    }
}
