package com.engine.salary.biz;

import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.encrypt.EncryptUtil;
import com.engine.salary.entity.salaryarchive.dto.SalaryItemAdjustRecordListDTO;
import com.engine.salary.entity.salaryarchive.param.SalaryArchiveItemQueryParam;
import com.engine.salary.entity.salaryarchive.param.SalaryItemAdjustRecordQueryParam;
import com.engine.salary.entity.salaryarchive.po.SalaryArchiveItemPO;
import com.engine.salary.mapper.archive.SalaryArchiveItemMapper;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.SalaryLoggerUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.SqlSession;
import weaver.conn.mybatis.MyBatisFactory;
import weaver.hrm.User;

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

public class SalaryArchiveItemBiz {
    public EncryptUtil encryptUtil = new EncryptUtil();

    public List<SalaryArchiveItemPO> getCurrentEffectiveItemList(SalaryArchiveItemQueryParam build) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            List<SalaryArchiveItemPO> salaryArchiveItemPOS = mapper.listByParam(build);
            return encryptUtil.decryptList(salaryArchiveItemPOS, SalaryArchiveItemPO.class);
        } finally {
            sqlSession.close();
        }
    }

    public List<SalaryArchiveItemPO> listByParam(SalaryArchiveItemQueryParam build) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            if (CollectionUtils.isNotEmpty(build.getEmployeeIds())) {
                List<SalaryArchiveItemPO> salaryArchiveItemPOS = new ArrayList<>();
                List<List<Long>> partition = Lists.partition((List<Long>) build.getEmployeeIds(), 500);
                partition.forEach(l -> {
                    build.setEmployeeIds(l);
                    salaryArchiveItemPOS.addAll(mapper.listByParam(build));
                });
                return encryptUtil.decryptList(salaryArchiveItemPOS, SalaryArchiveItemPO.class);
            } else {
                List<SalaryArchiveItemPO> salaryArchiveItemPOS = mapper.listByParam(build);
                return encryptUtil.decryptList(salaryArchiveItemPOS, SalaryArchiveItemPO.class);
            }
        } finally {
            sqlSession.close();
        }
    }

    public SalaryArchiveItemPO getById(Long salaryArchiveItemId) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            return encryptUtil.decrypt(mapper.getById(salaryArchiveItemId), SalaryArchiveItemPO.class);
        } finally {
            sqlSession.close();
        }
    }

    public List<SalaryArchiveItemPO> getIneffectiveSalaryItems(SalaryArchiveItemQueryParam build) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            List<SalaryArchiveItemPO> ineffectiveSalaryItems = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(build.getSalaryArchivesIds())) {
                List<Long> salaryArchivesIds = (List<Long>) build.getSalaryArchivesIds();
                List<List<Long>> partition = Lists.partition(salaryArchivesIds, 1000);
                partition.forEach(list -> {
                    build.setSalaryArchivesIds(list);
                    ineffectiveSalaryItems.addAll(mapper.getIneffectiveSalaryItems(build));
                });
            }
            return encryptUtil.decryptList(ineffectiveSalaryItems, SalaryArchiveItemPO.class);
        } finally {
            sqlSession.close();
        }
    }

    public List<SalaryArchiveItemPO> getEffectiveSalaryItems(SalaryArchiveItemQueryParam build) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            List<SalaryArchiveItemPO> effectiveSalaryItems = mapper.getEffectiveSalaryItems(build);
            return encryptUtil.decryptList(effectiveSalaryItems, SalaryArchiveItemPO.class);
        } finally {
            sqlSession.close();
        }
    }

    public void deleteBatchIds(List<Long> effectiveSalaryItemDels) {

        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            List<List<Long>> partition = Lists.partition(effectiveSalaryItemDels, 999);
            partition.forEach(mapper::deleteBatchIds);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }

    public void batchInsert(List<SalaryArchiveItemPO> salaryArchiveItemNews, User user) {
        if (CollectionUtils.isEmpty(salaryArchiveItemNews)) {
            return;
        }

        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            encryptUtil.encryptList(salaryArchiveItemNews, SalaryArchiveItemPO.class);
            List<List<SalaryArchiveItemPO>> partition = Lists.partition(salaryArchiveItemNews, 100);
            partition.forEach(mapper::batchInsert);
            sqlSession.commit();

            // 记录日志
            List<Long> archiveIdList = salaryArchiveItemNews.stream().map(SalaryArchiveItemPO::getSalaryArchiveId).distinct().collect(Collectors.toList());
            List<Long> itemIdList = salaryArchiveItemNews.stream().map(SalaryArchiveItemPO::getSalaryItemId).distinct().collect(Collectors.toList());
            // 查出保存的id
            List<SalaryArchiveItemPO> savePO = getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().salaryArchivesIds(archiveIdList).salaryItemIds(itemIdList).build());
            Map<String, SalaryArchiveItemPO> saveMap = SalaryEntityUtil.convert2Map(savePO, p -> p.getSalaryArchiveId() + p.getSalaryItemId() + SalaryDateUtil.getFormatDate(p.getEffectiveTime()));
            String operateName = SalaryI18nUtil.getI18nLabel(0, "新增调薪记录");
            salaryArchiveItemNews.forEach(e -> {
                SalaryArchiveItemPO archive = saveMap.getOrDefault(e.getSalaryArchiveId() + e.getSalaryItemId() + SalaryDateUtil.getFormatDate(e.getEffectiveTime()), SalaryArchiveItemPO.builder().build());
                SalaryLoggerUtil.recordAddSingleLog(SalaryElogConfig.salaryArchiveItemAdjustLoggerTemplate,
                        archive.getId(),
                        operateName + ":" + archive.getId(),
                        operateName,
                        operateName,
                        archive,
                        user);
            });
        } finally {
            sqlSession.close();
        }
    }

    public void updateById(SalaryArchiveItemPO salaryArchiveItem) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            encryptUtil.encrypt(salaryArchiveItem, SalaryArchiveItemPO.class);
            mapper.update(salaryArchiveItem);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }


    public void updateIgnoreNull(SalaryArchiveItemPO salaryArchiveItem) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            encryptUtil.encrypt(salaryArchiveItem, SalaryArchiveItemPO.class);
            mapper.updateIgnoreNull(salaryArchiveItem);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }


    public List<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordList(SalaryItemAdjustRecordQueryParam queryParam, List<Long> salaryItemIds) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            List<Long> salaryArchiveIds = queryParam.getSalaryArchiveIds();
            if (CollectionUtils.isEmpty(salaryArchiveIds)) {
                List<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordListDTOS = mapper.salaryItemAdjustRecordList(queryParam, salaryItemIds);
                return encryptUtil.decryptList(salaryItemAdjustRecordListDTOS, SalaryItemAdjustRecordListDTO.class);
            } else {
                List<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordListDTOS = new ArrayList<>();
                List<List<Long>> salaryArchiveIdsPartition = Lists.partition(salaryArchiveIds, 500);
                salaryArchiveIdsPartition.forEach(l -> {
                    queryParam.setSalaryArchiveIds(l);
                    salaryItemAdjustRecordListDTOS.addAll(mapper.salaryItemAdjustRecordList(queryParam, salaryItemIds));
                });
                return encryptUtil.decryptList(salaryItemAdjustRecordListDTOS, SalaryItemAdjustRecordListDTO.class);
            }

        } finally {
            sqlSession.close();
        }
    }

    public void deleteBySalaryArchiveId(List<Long> salaryArchiveIds) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            mapper.deleteBySalaryArchiveId(salaryArchiveIds);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }

    public PageInfo<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordListPage(SalaryItemAdjustRecordQueryParam queryParam, List<Long> salaryItemIds) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);

            List<Long> salaryArchiveIds = queryParam.getSalaryArchiveIds();
            if (CollectionUtils.isEmpty(salaryArchiveIds)) {
                List<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordListDTOS = mapper.salaryItemAdjustRecordList(queryParam, salaryItemIds);
                PageInfo<SalaryItemAdjustRecordListDTO> page = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
                        salaryItemAdjustRecordListDTOS,
                        SalaryItemAdjustRecordListDTO.class);
                encryptUtil.decryptList(page.getList(), SalaryItemAdjustRecordListDTO.class);
                return page;
            } else {
                List<SalaryItemAdjustRecordListDTO> salaryItemAdjustRecordListDTOS = new ArrayList<>();
                List<List<Long>> salaryArchiveIdsPartition = Lists.partition(salaryArchiveIds, 500);
                salaryArchiveIdsPartition.forEach(l -> {
                    queryParam.setSalaryArchiveIds(l);
                    salaryItemAdjustRecordListDTOS.addAll(mapper.salaryItemAdjustRecordList(queryParam, salaryItemIds));
                });
                PageInfo<SalaryItemAdjustRecordListDTO> page = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
                        salaryItemAdjustRecordListDTOS,
                        SalaryItemAdjustRecordListDTO.class);
                encryptUtil.decryptList(page.getList(), SalaryItemAdjustRecordListDTO.class);
                return page;
            }
        } finally {
            sqlSession.close();
        }
    }

    public void batchDeleteHistoryData(SalaryArchiveItemPO build) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            SalaryArchiveItemMapper mapper = sqlSession.getMapper(SalaryArchiveItemMapper.class);
            mapper.batchDeleteHistoryData(build);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
}
