package com.engine.salary.report.service.impl;

import com.engine.core.impl.Service;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.enums.sicategory.DeleteTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.report.SalaryStatisticsItemMapper;
import com.engine.salary.report.entity.param.SalaryStatisticsItemSaveParam;
import com.engine.salary.report.entity.po.SalaryStatisticsItemPO;
import com.engine.salary.report.enums.UnitTypeEnum;
import com.engine.salary.report.service.SalaryStatisticsItemService;
import com.engine.salary.util.SalaryAssert;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

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

/**
 * 薪酬报表自定义统计项目
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalaryStatisticsItemServiceImpl extends Service implements SalaryStatisticsItemService {


    private SalaryStatisticsItemMapper getSalaryStatisticsItemMapper() {
        return MapperProxyFactory.getProxy(SalaryStatisticsItemMapper.class);
    }

    @Override
    public SalaryStatisticsItemPO getById(Long id) {
        if (id == null) {
            return null;
        }
        return getSalaryStatisticsItemMapper().getById(id);
    }

    @Override
    public List<SalaryStatisticsItemPO> listByStatisticsReportId(Long statisticsReportId) {
        if (statisticsReportId == null) {
            return new ArrayList<>();
        }
        return getSalaryStatisticsItemMapper().listSome(SalaryStatisticsItemPO.builder().statReportId(statisticsReportId).build());
    }

    public List<SalaryStatisticsItemPO> listByIds(Collection<Long> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }

        return getSalaryStatisticsItemMapper().listSome(SalaryStatisticsItemPO.builder().ids(ids).build());
    }

    @Override
    public String delete(Collection<Long> ids) {
        SalaryAssert.notEmpty(ids, SalaryI18nUtil.getI18nLabel(152638, "id不可为空"));
        List<SalaryStatisticsItemPO> list = this.listByIds(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            getSalaryStatisticsItemMapper().deleteByIds(ids);
           list.forEach(po -> {
               LoggerContext<SalaryStatisticsItemPO> loggerContext = new LoggerContext<>();
               loggerContext.setUser(user);
               loggerContext.setTargetId(String.valueOf(po.getId()));
               loggerContext.setTargetName(po.getItemName());
               loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
               loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除统计项目"));
               loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除统计项目"));
               loggerContext.setOldValues(po);
               SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
           });
        }
        return StringUtils.EMPTY;
    }

    @Override
    public String save(SalaryStatisticsItemSaveParam saveParam) {
        // 新建
        if (Objects.isNull(saveParam.getId())) {
            if (Objects.isNull(saveParam.getStatReportId())) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(163034, "统计报表id不能为空"));
            }
            if (CollectionUtils.isEmpty(saveParam.getItemValue())) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(152640, "统计项目必填"));
            }
            if (StringUtils.isEmpty(saveParam.getItemName())) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(152641, "统计项名称必填"));
            }

            List<SalaryStatisticsItemPO> itemPOList = listByStatisticsReportId(saveParam.getStatReportId());
            boolean isRepeat = itemPOList.stream().anyMatch(po -> saveParam.getItemName().equals(po.getItemName()));
            if (isRepeat) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(152642, "统计项目名称已经存在"));
            }

            List<Integer> indexValues = itemPOList.stream().map(SalaryStatisticsItemPO::getIndexValue).collect(Collectors.toList());
            Integer max = CollectionUtils.isEmpty(indexValues) ? 1 : Collections.max(indexValues);

            Date now = new Date();

            SalaryStatisticsItemPO subTableItemPO = SalaryStatisticsItemPO.builder()
                    .id(IdGenerator.generate())
                    .createTime(now)
                    .deleteType(DeleteTypeEnum.NOT_DELETED.getValue())
                    .itemName(saveParam.getItemName())
                    .itemValue(StringUtils.join(saveParam.getItemValue(), ","))
                    .countRule(SalaryEntityUtil.toJSONString(saveParam.getCountRule()))
                    .sumRule(SalaryEntityUtil.toJSONString(saveParam.getSumRule()))
                    .avgRule(SalaryEntityUtil.toJSONString(saveParam.getAvgRule()))
                    .maxRule(SalaryEntityUtil.toJSONString(saveParam.getMaxRule()))
                    .minRule(SalaryEntityUtil.toJSONString(saveParam.getMinRule()))
                    .medianRule(SalaryEntityUtil.toJSONString(saveParam.getMedianRule()))
                    .lastRule(SalaryEntityUtil.toJSONString(saveParam.getLastRule()))
                    .oldRule(SalaryEntityUtil.toJSONString(saveParam.getOldRule()))
                    .frequentRule(SalaryEntityUtil.toJSONString(saveParam.getFrequentRule()))
                    .tileRule(SalaryEntityUtil.toJSONString(saveParam.getTileRule()))
                    .indexValue(max + 1)
                    .statReportId(saveParam.getStatReportId())
                    .unitType(saveParam.getUnitType() == null ? UnitTypeEnum.YUAN.getValue() : saveParam.getUnitType())
                    .creator((long) user.getUID())
                    .updateTime(now)
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .build();
            getSalaryStatisticsItemMapper().insertIgnoreNull(subTableItemPO);

            // 记录操作日志
           LoggerContext<SalaryStatisticsItemPO> loggerContext = new LoggerContext<>();
           loggerContext.setUser(user);
           loggerContext.setTargetId(String.valueOf(subTableItemPO.getId()));
           loggerContext.setTargetName(subTableItemPO.getItemName());
           loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
           loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "新增统计项目"));
           loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "新增统计项目"));
           loggerContext.setNewValues(subTableItemPO);
           SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
            // 更新
        } else {
            SalaryStatisticsItemPO itemPO = this.getById(saveParam.getId());
            SalaryAssert.notNull(itemPO, SalaryI18nUtil.getI18nLabel(152591, "统计项目不存在"));
            Optional.ofNullable(saveParam.getItemName()).ifPresent(itemPO::setItemName);

            SalaryStatisticsItemPO oldPO = new SalaryStatisticsItemPO();
            BeanUtils.copyProperties(itemPO, oldPO);

            if (Objects.nonNull(saveParam.getUnitType())) {
                itemPO.setUnitType(saveParam.getUnitType());
            } else {
                itemPO.setItemValue(StringUtils.join(saveParam.getItemValue(), ","));
                itemPO.setCountRule(SalaryEntityUtil.toJSONString(saveParam.getCountRule()));
                itemPO.setSumRule(SalaryEntityUtil.toJSONString(saveParam.getSumRule()));
                itemPO.setAvgRule(SalaryEntityUtil.toJSONString(saveParam.getAvgRule()));
                itemPO.setMaxRule(SalaryEntityUtil.toJSONString(saveParam.getMaxRule()));
                itemPO.setMinRule(SalaryEntityUtil.toJSONString(saveParam.getMinRule()));
                itemPO.setMedianRule(SalaryEntityUtil.toJSONString(saveParam.getMedianRule()));
                itemPO.setLastRule(SalaryEntityUtil.toJSONString(saveParam.getLastRule()));
                itemPO.setOldRule(SalaryEntityUtil.toJSONString(saveParam.getOldRule()));
                itemPO.setFrequentRule(SalaryEntityUtil.toJSONString(saveParam.getFrequentRule()));
                itemPO.setTileRule(SalaryEntityUtil.toJSONString(saveParam.getTileRule()));
            }

            getSalaryStatisticsItemMapper().updateIgnoreNull(itemPO);

            // 记录操作日志
            LoggerContext<SalaryStatisticsItemPO> loggerContext = new LoggerContext<>();
            loggerContext.setUser(user);
            loggerContext.setTargetId(itemPO.getId().toString());
            loggerContext.setTargetName(itemPO.getItemName());
            loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
            loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "新增统计项目"));
            loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "新增统计项目"));
            loggerContext.setOldValues(oldPO);
            loggerContext.setNewValues(itemPO);
            SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
        }
        return StringUtils.EMPTY;
    }

    @Override
    public void saveOrUpdateBatch(List<SalaryStatisticsItemPO> salaryStatisticsItemList) {
        salaryStatisticsItemList.forEach(po -> {
            Long id = po.getId();
            SalaryStatisticsItemPO item = getSalaryStatisticsItemMapper().getById(id);
            if (item == null) {
                getSalaryStatisticsItemMapper().insertIgnoreNull(po);
            } else {
                getSalaryStatisticsItemMapper().update(po);
            }
        });
    }

    @Override
    public void deleteByReportIds(List<Long> reportIds) {
        getSalaryStatisticsItemMapper().deleteByReportIds(reportIds);
    }
}
