package com.engine.salary.service.impl;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.SalarySobCheckRuleBiz;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.entity.salarysob.bo.SalarySobCheckRuleBO;
import com.engine.salary.entity.salarysob.param.SalarySobCheckRuleQueryParam;
import com.engine.salary.entity.salarysob.param.SalarySobCheckRuleSaveParam;
import com.engine.salary.entity.salarysob.param.UpdateCheckRuleFormulaParam;
import com.engine.salary.entity.salarysob.po.SalarySobCheckRulePO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.SalarySobCheckRuleService;
import com.engine.salary.service.SalarySobService;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.valid.RuntimeTypeEnum;
import com.engine.salary.util.valid.ValidUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import weaver.hrm.User;

import java.util.*;

/**
 * 薪资账套的校验规则
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalarySobCheckRuleServiceImpl extends Service implements SalarySobCheckRuleService {

    private SalarySobCheckRuleBiz salarySobCheckRuleMapper = new SalarySobCheckRuleBiz();
    private SalarySobService getSalarySobService(User user) {
        return (SalarySobService) ServiceUtil.getService(SalarySobServiceImpl.class, user);
    }

    @Override
    public SalarySobCheckRulePO getById(Long id) {
        return salarySobCheckRuleMapper.getById(id);
    }

    @Override
    public List<SalarySobCheckRulePO> listByIds(Collection<Long> ids) {
        return salarySobCheckRuleMapper.listSome(SalarySobCheckRulePO.builder().ids(ids).build());
    }

    @Override
    public List<SalarySobCheckRulePO> listBySalarySobId(Long salarySobId) {
        return salarySobCheckRuleMapper.listSome(SalarySobCheckRulePO.builder().salarySobId(salarySobId).build());
    }

    @Override
    public List<SalarySobCheckRulePO> listBySalarySobIdAndName(Long salarySobId, String name) {
        return salarySobCheckRuleMapper.listSome(SalarySobCheckRulePO.builder().salarySobId(salarySobId).name(name).build());
    }

    @Override
    public PageInfo<SalarySobCheckRulePO> listPageByParam(SalarySobCheckRuleQueryParam queryParam) {

        return salarySobCheckRuleMapper.listPageByParam(queryParam);

    }

    @Override
    public void save(SalarySobCheckRuleSaveParam saveParam) {
        ValidUtil.doValidator(saveParam);

        // 查询薪资账套的校验规则
        List<SalarySobCheckRulePO> salarySobCheckRulePOS = listBySalarySobIdAndName(saveParam.getSalarySobId(), saveParam.getName());
        if (CollectionUtils.isNotEmpty(salarySobCheckRulePOS)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98629, "名称已经存在"));
        }
        // 查询薪资账套
        SalarySobPO salarySobPO = getSalarySobService(user).getById(saveParam.getSalarySobId());
        if (Objects.isNull(salarySobPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98379, "参数错误，薪资账套不存在或者已被删除"));
        }
        // 保存参数转换成薪资账套的校验规则po
        SalarySobCheckRulePO salarySobCheckRulePO = SalarySobCheckRuleBO.convert2PO(saveParam, (long) user.getUID());
        // 保存
        salarySobCheckRuleMapper.insert(salarySobCheckRulePO);
        //记录日志
        LoggerContext<SalarySobCheckRulePO> loggerContext = new LoggerContext<>();
        loggerContext.setTargetId("" + salarySobPO.getId());
        loggerContext.setTargetName(salarySobPO.getName());
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(93872, "添加校验规则"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(93872, "添加校验规则") + ": " + salarySobCheckRulePO.getName());
        loggerContext.setNewValues(salarySobCheckRulePO);
        SalaryElogConfig.salarySobLoggerTemplate.write(loggerContext);
    }

    @Override
    public void batchSave(Collection<SalarySobCheckRulePO> salarySobCheckRulePOS) {
        salarySobCheckRuleMapper.batchInsert(salarySobCheckRulePOS);
    }

    @Override
    public void update(SalarySobCheckRuleSaveParam updateParam) {

        ValidUtil.doValidator(updateParam, RuntimeTypeEnum.UPDATE);

        // 名称不允许重复
        List<SalarySobCheckRulePO> salarySobCheckRulePOS = listBySalarySobIdAndName(updateParam.getSalarySobId(), updateParam.getName());
        boolean nameExist = salarySobCheckRulePOS.stream().anyMatch(salarySobCheckRulePO -> !Objects.equals(salarySobCheckRulePO.getId(), updateParam.getId()));
        if (nameExist) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98629, "名称已经存在"));
        }
        // 查询薪资账套的校验规则
        SalarySobCheckRulePO salarySobCheckRulePO = getById(updateParam.getId());
        if (Objects.isNull(salarySobCheckRulePO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98636, "校验规则不存在或者已被删除"));
        }
        // 查询薪资账套
        SalarySobPO salarySobPO = getSalarySobService(user).getById(updateParam.getSalarySobId());
        if (Objects.isNull(salarySobPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98379, "参数错误，薪资账套不存在或者已被删除"));
        }
        // 更新
        SalarySobCheckRulePO newSalarySobCheckRulePO = new SalarySobCheckRulePO();
        BeanUtils.copyProperties(salarySobCheckRulePO, newSalarySobCheckRulePO);
        newSalarySobCheckRulePO.setName(updateParam.getName());
        newSalarySobCheckRulePO.setFormulaId(updateParam.getFormulaId());
        newSalarySobCheckRulePO.setUpdateTime(new Date());
        salarySobCheckRuleMapper.updateById(newSalarySobCheckRulePO);
        //todo 记录日志
        LoggerContext<SalarySobCheckRulePO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId("" + salarySobPO.getId());
        loggerContext.setTargetName(salarySobPO.getName());
        loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "编辑校验规则"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "编辑校验规则") + ": " + newSalarySobCheckRulePO.getName());
        loggerContext.setOldValues(salarySobCheckRulePO);
        loggerContext.setNewValues(newSalarySobCheckRulePO);
        SalaryElogConfig.salarySobLoggerTemplate.write(loggerContext);
    }

    @Override
    public void updateFormulaId(UpdateCheckRuleFormulaParam updateParam) {
        ValidUtil.doValidator(updateParam);

        // 查询薪资账套的校验规则
        SalarySobCheckRulePO salarySobCheckRulePO = getById(updateParam.getId());
        if (Objects.isNull(salarySobCheckRulePO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98636, "校验规则不存在或者已被删除"));
        }
        // 更新
        SalarySobCheckRuleSaveParam salarySobCheckRuleSaveParam = new SalarySobCheckRuleSaveParam()
                .setId(updateParam.getId())
                .setName(salarySobCheckRulePO.getName())
                .setSalarySobId(salarySobCheckRulePO.getSalarySobId())
                .setFormulaId(updateParam.getFormulaId())
                .setDescription(salarySobCheckRulePO.getDescription());
        update(salarySobCheckRuleSaveParam);
    }

    @Override
    public void deleteByIds(Collection<Long> ids) {
        // 查询薪资账套的校验规则
        List<SalarySobCheckRulePO> salarySobCheckRulePOS = listByIds(ids);
        if (CollectionUtils.isEmpty(salarySobCheckRulePOS)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98636, "校验规则不存在或者已被删除"));
        }
        // 删除薪资账套的考验规则
        ids = SalaryEntityUtil.properties(salarySobCheckRulePOS, SalarySobCheckRulePO::getId);
        salarySobCheckRuleMapper.deleteByIds(ids);
        // 查询薪资账套
        Set<Long> salarySobIds = SalaryEntityUtil.properties(salarySobCheckRulePOS, SalarySobCheckRulePO::getSalarySobId);
        List<SalarySobPO> salarySobPOS = getSalarySobService(user).listByIds(salarySobIds);
        // 将薪资账套list转换成map
        Map<Long, SalarySobPO> salarySobPOMap = SalaryEntityUtil.convert2Map(salarySobPOS, SalarySobPO::getId);
        //todo 记录日志
        salarySobCheckRulePOS.forEach(salarySobCheckRulePO -> {
            SalarySobPO salarySobPO = salarySobPOMap.get(salarySobCheckRulePO.getSalarySobId());
            LoggerContext<SalarySobCheckRulePO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId("" + salarySobPO.getId());
            loggerContext.setTargetName(salarySobPO.getName());
            loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除校验规则"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除校验规则") + ": " + salarySobCheckRulePO.getName());
            loggerContext.setOldValues(salarySobCheckRulePO);
            SalaryElogConfig.salarySobLoggerTemplate.write(loggerContext);
        });
    }

    @Override
    public void deleteBySalarySobIds(Collection<Long> salarySobIds) {
        salarySobCheckRuleMapper.deleteBySalarySobIds(salarySobIds);
    }
}
