package com.engine.salary.biz;

import com.engine.salary.encrypt.EncryptUtil;
import com.engine.salary.entity.datacollection.AddUpSituation;
import com.engine.salary.entity.datacollection.dto.AddUpSituationDTO;
import com.engine.salary.entity.datacollection.dto.AddUpSituationRecordDTO;
import com.engine.salary.entity.datacollection.param.AddUpSituationQueryParam;
import com.engine.salary.mapper.datacollection.AddUpSituationMapper;
import com.engine.salary.util.SalaryI18nUtil;
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.general.BaseBean;

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

public class AddUpSituationBiz extends BaseBean {

    private EncryptUtil encryptUtil = new EncryptUtil();

    /**
     * 关联查询查询列表
     *
     * @param param
     * @return
     */
    public List<AddUpSituationDTO> list(AddUpSituationQueryParam param) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            List<AddUpSituationDTO> list = mapper.list(param);
            encryptUtil.decryptList(list, AddUpSituationDTO.class);
            return SalaryI18nUtil.i18nList(list);
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 条件查询
     *
     * @param param
     * @return
     */
    public List<AddUpSituation> listSome(AddUpSituation param) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            if (CollectionUtils.isNotEmpty(param.getEmployeeIds())) {
                List<AddUpSituation> addUpSituations = new ArrayList<>();
                List<List<Long>> partition = Lists.partition((List<Long>) param.getEmployeeIds(), 500);
                partition.forEach(l -> {
                    param.setEmployeeIds(l);
                    addUpSituations.addAll(mapper.listSome(param));
                });
                return encryptUtil.decryptList(addUpSituations, AddUpSituation.class);
            } else {
                List<AddUpSituation> addUpSituations = mapper.listSome(param);
                return encryptUtil.decryptList(addUpSituations, AddUpSituation.class);
            }
        } finally {
            sqlSession.close();
        }
    }


    /**
     * 根据id获取
     *
     * @param id
     * @return
     */
    public AddUpSituation getById(Long id) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            AddUpSituation byId = mapper.getById(id);
            return encryptUtil.decrypt(byId, AddUpSituation.class);
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 详情列表
     *
     * @param param
     * @return
     */
    public List<AddUpSituationRecordDTO> recordList(AddUpSituationQueryParam param) {
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            List<AddUpSituationRecordDTO> addUpSituationRecordDTOS = mapper.recordList(param);
            return encryptUtil.decryptList(addUpSituationRecordDTOS, AddUpSituationRecordDTO.class);
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 批量插入
     *
     * @param param
     * @return
     */
    public void batchSave(List<AddUpSituation> param) {
        if (CollectionUtils.isEmpty(param)) {
            return;
        }
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            encryptUtil.encryptList(param, AddUpSituation.class);
            List<List<AddUpSituation>> partition = Lists.partition(param, 50);
            partition.forEach(mapper::insertData);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 批量插入
     *
     * @param param
     * @return
     */
    public void batchUpdate(List<AddUpSituation> param) {
        if (CollectionUtils.isEmpty(param)) {
            return;
        }
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            encryptUtil.encryptList(param, AddUpSituation.class);
            List<List<AddUpSituation>> partition = Lists.partition(param, 50);
            partition.forEach(mapper::updateData);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }


    public void handleImportData(List<AddUpSituation> pos) {
        if (CollectionUtils.isEmpty(pos)) {
            return;
        }
        AddUpSituation po = pos.get(0);
        // 多条相同人的则以第一条为准，如果逆序排列（用于重复的则以最后一条为准）Collections.reverse(pos);
        // 去重（通过记录的唯一条件(申报月份，人员id，个税扣缴义务人id)拼接）
        List<AddUpSituation> finalPos = pos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getEmployeeId() + "-" + f.getTaxAgentId()))), ArrayList::new));
        // 查询已有数据
        List<AddUpSituation> list = listSome(AddUpSituation.builder().taxYearMonth(po.getTaxYearMonth()).build());
        // 待修改的 本地已存在则更新【交集】
        List<AddUpSituation> updateList = list.stream().map(m -> {
            Optional<AddUpSituation> optional = finalPos.stream().filter(p -> (p.getEmployeeId() + "-" + p.getTaxAgentId()).equals(m.getEmployeeId() + "-" + m.getTaxAgentId())).findFirst();
            AddUpSituation temp = null;
            if (optional.isPresent()) {
                temp = optional.get();
                // 换成本地库的id
                temp.setId(m.getId());
            }
            return temp;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        // 待新增的 导入比本地多，则新增【差集(导入 - local)】
        List<AddUpSituation> saveList = finalPos.stream().map(m -> {
            Optional<AddUpSituation> optional = list.stream().filter(p -> (p.getEmployeeId() + "-" + p.getTaxAgentId()).equals(m.getEmployeeId() + "-" + m.getTaxAgentId())).findFirst();
            AddUpSituation temp = null;
            if (!optional.isPresent()) {
                temp = m;
            }
            return temp;
        }).filter(Objects::nonNull).collect(Collectors.toList());

        // 修改
        if (CollectionUtils.isNotEmpty(updateList)) {
            batchUpdate(updateList);
        }
        // 保存
        if (CollectionUtils.isNotEmpty(saveList)) {
            batchSave(saveList);
        }
    }


    /**
     * @return void
     * @description 批量删除数据
     * @author Harryxzy
     * @date 2022/10/27 22:39
     */
    public void batchDeleteByIDS(List<Long> deleteIds) {
        if (CollectionUtils.isEmpty(deleteIds)) {
            return;
        }
        SqlSession sqlSession = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            AddUpSituationMapper mapper = sqlSession.getMapper(AddUpSituationMapper.class);
            List<List<Long>> partition = Lists.partition(deleteIds, 100);
            partition.forEach(mapper::deleteData);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
}
