package com.engine.salary.service.impl;

import com.api.formmode.mybatis.util.SqlProxyHandle;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.salaryBill.param.SalaryBillItemNameSaveParam;
import com.engine.salary.entity.salaryBill.po.SalaryBillItemNamePO;
import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salarybill.SalaryBillItemNameMapper;
import com.engine.salary.service.SalaryBillItemNameService;
import com.engine.salary.service.SalaryItemService;
import com.engine.salary.service.SalaryTemplateService;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import com.engine.salary.util.db.IdGenerator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.hrm.User;

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

/**
 * @author Harryxzy
 * @ClassName SalaryBillItemNameServiceImpl
 * @date 2023/07/18 16:17
 * @description
 */
public class SalaryBillItemNameServiceImpl extends Service implements SalaryBillItemNameService {

    private SalaryBillItemNameMapper getSalaryBillItemNameMapper() {
        return SqlProxyHandle.getProxy(SalaryBillItemNameMapper.class);
    }

    private SalaryItemService getSalaryItemService(User user) {
        return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
    }

    private SalaryTemplateService getSalaryTemplateService(User user) {
        return ServiceUtil.getService(SalaryTemplateServiceImpl.class, user);
    }
    @Override
    public List<SalaryBillItemNamePO> listAll() {
        return getSalaryBillItemNameMapper().listAll();
    }

    @Override
    public SalaryBillItemNamePO getById(Long id) {
        return getSalaryBillItemNameMapper().getById(id);
    }

    @Override
    public int insertIgnoreNull(SalaryBillItemNamePO salaryBillItemNamePO) {
        return getSalaryBillItemNameMapper().insertIgnoreNull(salaryBillItemNamePO);
    }

    @Override
    public int update(SalaryBillItemNamePO salaryBillItemNamePO) {
        return getSalaryBillItemNameMapper().update(salaryBillItemNamePO);
    }

    @Override
    public int updateIgnoreNull(SalaryBillItemNamePO salaryBillItemNamePO) {
        return getSalaryBillItemNameMapper().updateIgnoreNull(salaryBillItemNamePO);
    }

    @Override
    public int delete(Long id) {
        return getSalaryBillItemNameMapper().delete(id);
    }

    @Override
    public List<SalaryBillItemNamePO> ListByTemplateAndType(SalaryBillItemNamePO param) {
        return getSalaryBillItemNameMapper().listSome(param);
    }

    @Override
    public void saveItemShowName(List<SalaryBillItemNameSaveParam> saveList) {
        saveList= saveList.stream().filter(param -> !Objects.isNull(param.getSalaryTemplateId()) && CollectionUtils.isNotEmpty(param.getItemShowNameSetting())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(saveList))
            return;
        List<Long> templateIdList = saveList.stream().map(SalaryBillItemNameSaveParam::getSalaryTemplateId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(templateIdList) || templateIdList.size()>1){
            throw new SalaryRunTimeException("工资单模板id为空，或存在多个工资单模板id");
        }
        Long salaryTemplateId = templateIdList.get(0);
        SalaryTemplatePO salaryTemplatePO = getSalaryTemplateService(user).getById(salaryTemplateId);
        if(Objects.isNull(salaryTemplatePO)){
            throw new SalaryRunTimeException("工资单模板不存在或已被删除");
        }
        List<SalaryBillItemNamePO> needInsertList = new ArrayList<>();
        List<SalaryBillItemNamePO> needUpdateList = new ArrayList<>();
        Date now = new Date();
        // 根据模板类型分组
        Map<Integer, List<SalaryBillItemNameSaveParam.itemShowNameSetting>> saveMap = SalaryEntityUtil.convert2Map(saveList, SalaryBillItemNameSaveParam::getSalaryBillType, SalaryBillItemNameSaveParam::getItemShowNameSetting);

        for(Map.Entry<Integer, List<SalaryBillItemNameSaveParam.itemShowNameSetting>> entry : saveMap.entrySet()){
            // 获取已经设置的展示名
            List<SalaryBillItemNamePO> billItemNameList = ListByTemplateAndType(SalaryBillItemNamePO.builder().salaryTemplateId(salaryTemplateId).salaryBillType(entry.getKey()).build());
            Map<Long, SalaryBillItemNamePO> billItemNameMap = SalaryEntityUtil.convert2Map(billItemNameList, SalaryBillItemNamePO::getSalaryItemId);
            List<Long> needDeleteItemIdList = new ArrayList<>();

            entry.getValue().stream().forEach(setting -> {
                if(StringUtils.isBlank(setting.getSalaryItemShowName())){
                    // 显示名为空则删除设置
                    needDeleteItemIdList.add(setting.getSalaryItemId());
                }else{
                    if(billItemNameMap.containsKey(setting.getSalaryItemId())){
                        // 更新
                        SalaryBillItemNamePO po = billItemNameMap.get(setting.getSalaryItemId());
                        po.setSalaryItemShowName(setting.getSalaryItemShowName());
                        po.setUpdateTime(now);
                        needUpdateList.add(po);
                    }else{
                        // 新增
                        needInsertList.add(SalaryBillItemNamePO.builder()
                                .id(IdGenerator.generate())
                                .salaryItemId(setting.getSalaryItemId())
                                .salaryItemShowName(setting.getSalaryItemShowName())
                                .salaryTemplateId(salaryTemplateId)
                                .salaryBillType(entry.getKey())
                                .createTime(now)
                                .updateTime(now)
                                .creator(Long.valueOf(user.getUID()))
                                .deleteType(NumberUtils.INTEGER_ZERO)
                                .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                                .build());
                    }
                }
            });
            // 删除
            batchDeleteByItemIdsAndTemplateId(needDeleteItemIdList, salaryTemplateId, entry.getKey());
        }
        // 入库
        batchUpdate(needUpdateList);
        batchInsert(needInsertList);
    }

    @Override
    public void batchUpdate(List<SalaryBillItemNamePO> needUpdateList) {
        if(CollectionUtils.isEmpty(needUpdateList)){
            return;
        }
        List<List<SalaryBillItemNamePO>> partition = Lists.partition(needUpdateList, 500);
        partition.forEach(getSalaryBillItemNameMapper()::batchUpdate);
    }

    @Override
    public void batchInsert(List<SalaryBillItemNamePO> needInsertList) {
        if(CollectionUtils.isEmpty(needInsertList)){
            return;
        }
        List<List<SalaryBillItemNamePO>> partition = Lists.partition(needInsertList, 500);
        partition.forEach(getSalaryBillItemNameMapper()::batchInsert);
    }

    @Override
    public void deleteByIds(List<Long> needDeleteIds) {
        if(CollectionUtils.isEmpty(needDeleteIds)){
            return;
        }
        List<List<Long>> partition = Lists.partition(needDeleteIds, 1000);
        partition.forEach(getSalaryBillItemNameMapper()::deleteByIds);
    }

    public void batchDeleteByItemIdsAndTemplateId(List<Long> salaryItemIds, Long salaryTemplateId, Integer salaryBillType) {
        if(CollectionUtils.isEmpty(salaryItemIds) || Objects.isNull(salaryTemplateId) || Objects.isNull(salaryBillType))
            return;
        getSalaryBillItemNameMapper().deleteByItemIdsAndTemplateId(salaryItemIds, salaryTemplateId, salaryBillType);
    }

    @Override
    public void deleteByTemplateIds(Collection<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return;
        }
        getSalaryBillItemNameMapper().deleteByTemplateIds(ids);
    }
}
