package com.xisc.pm.app.service.impl;

import com.xisc.pm.app.service.PmPnsortService;
import com.xisc.pm.domain.entity.PmPnsort;
import com.xisc.pm.domain.entity.PmPnsortTra;
import com.xisc.pm.domain.repository.PmPnsortRepository;
import com.xisc.pm.domain.repository.PmPnsortTraRepository;
import com.xisc.pm.infra.util.BeanUtils;
import io.choerodon.core.domain.Page;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.DetailsHelper;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import org.apache.commons.collections.CollectionUtils;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 组炉规则配置表(PmPnsort)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-09-11 15:59:47
 */
@Service
public class PmPnsortServiceImpl implements PmPnsortService {

    private PmPnsortRepository pmPnsortRepository;

    private PmPnsortTraRepository pmPnsortTraRepository;

    public PmPnsortServiceImpl(PmPnsortRepository pmPnsortRepository, PmPnsortTraRepository pmPnsortTraRepository) {
        this.pmPnsortRepository = pmPnsortRepository;
        this.pmPnsortTraRepository = pmPnsortTraRepository;
    }

    @Override
    public Page<PmPnsort> selectList(PageRequest pageRequest, PmPnsort pmPnsort) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmPnsortRepository.selectList(pmPnsort));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, List<PmPnsort> pmPnsortList) {
        // 获取当前时间及操作人信息
        Date now = new Date();
        String username = DetailsHelper.getUserDetails().getUsername();
        List<PmPnsortTra> insertTraList = new ArrayList<>(pmPnsortList.size());

        // 校验唯一性
        Map<String, List<PmPnsort>> pmPnsortMap = pmPnsortList.stream().collect(Collectors.groupingBy(this::getKey));
        for (Map.Entry<String, List<PmPnsort>> entry : pmPnsortMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                PmPnsort pmPnsort = entry.getValue().get(0);
                throw new CommonException("pm.pnsort_002", pmPnsort.getMainBacklogCode(), pmPnsort.getCcType(),
                        pmPnsort.getPriority1(), pmPnsort.getPriority2(), pmPnsort.getPriority3(), pmPnsort.getPriority4()
                        , pmPnsort.getPriority5(), pmPnsort.getPriority6(), pmPnsort.getPriority7(), pmPnsort.getPriority8(),
                        pmPnsort.getSortFlag());
            }
        }

        List<String> mainBacklogCodeList = pmPnsortList.stream().map(PmPnsort::getMainBacklogCode).distinct().collect(Collectors.toList());
        List<String> ccTypeList = pmPnsortList.stream().map(PmPnsort::getCcType).distinct().collect(Collectors.toList());
        List<String> priority1List = pmPnsortList.stream().map(PmPnsort::getPriority1).distinct().collect(Collectors.toList());
        List<String> priority2List = pmPnsortList.stream().map(PmPnsort::getPriority2).distinct().collect(Collectors.toList());
        List<String> priority3List = pmPnsortList.stream().map(PmPnsort::getPriority3).distinct().collect(Collectors.toList());
        List<String> priority4List = pmPnsortList.stream().map(PmPnsort::getPriority4).distinct().collect(Collectors.toList());
        List<String> priority5List = pmPnsortList.stream().map(PmPnsort::getPriority5).distinct().collect(Collectors.toList());
        List<String> priority6List = pmPnsortList.stream().map(PmPnsort::getPriority6).distinct().collect(Collectors.toList());
        List<String> priority7List = pmPnsortList.stream().map(PmPnsort::getPriority7).distinct().collect(Collectors.toList());
        List<String> priority8List = pmPnsortList.stream().map(PmPnsort::getPriority8).distinct().collect(Collectors.toList());
        List<String> sortFlagList = pmPnsortList.stream().map(PmPnsort::getSortFlag).distinct().collect(Collectors.toList());
        List<Long> idList = pmPnsortList.stream().filter(item -> item.getId() != null).map(PmPnsort::getId).collect(Collectors.toList());
        List<PmPnsort> existList = pmPnsortRepository.selectByCondition(Condition.builder(PmPnsort.class)
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_MAIN_BACKLOG_CODE, mainBacklogCodeList))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_CC_TYPE, ccTypeList))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY1, priority1List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY2, priority2List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY3, priority3List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY4, priority4List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY5, priority5List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY6, priority6List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY7, priority7List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_PRIORITY8, priority8List))
                .andWhere(Sqls.custom().andIn(PmPnsort.FIELD_SORT_FLAG, sortFlagList))
                .andWhere(Sqls.custom().andNotIn(PmPnsort.FIELD_ID, idList, true))
                .andWhere(Sqls.custom().andEqualTo(PmPnsort.FIELD_TENANT_ID, tenantId))
                .build());
        if (CollectionUtils.isNotEmpty(existList)) {
            Map<String, List<PmPnsort>> existMap = existList.stream().collect(Collectors.groupingBy(this::getKey));
            for (PmPnsort pmPnsort : pmPnsortList) {
                if (existMap.containsKey(getKey(pmPnsort))) {
                    throw new CommonException("pm.pnsort_001", pmPnsort.getMainBacklogCode(), pmPnsort.getCcType(),
                            pmPnsort.getPriority1(), pmPnsort.getPriority2(), pmPnsort.getPriority3(), pmPnsort.getPriority4()
                            , pmPnsort.getPriority5(), pmPnsort.getPriority6(), pmPnsort.getPriority7(), pmPnsort.getPriority8(),
                            pmPnsort.getSortFlag());
                }
            }
        }

        // 分离需要插入和更新的列表
        List<PmPnsort> insertList = pmPnsortList.stream().filter(line -> line.getId() == null).collect(Collectors.toList());
        List<PmPnsort> updateList = pmPnsortList.stream().filter(line -> line.getId() != null).collect(Collectors.toList());

        // 记录历史表
        for (PmPnsort pmPnsort : updateList) {
            PmPnsortTra pmPnsortTra = new PmPnsortTra();
            BeanUtils.copy(pmPnsort, pmPnsortTra);

            // 设置操作类型为更新（U），并记录操作时间和用户
            pmPnsortTra.setOperationType("U");
            pmPnsortTra.setOperationTime(now);
            pmPnsortTra.setOperationUser(username);
            insertTraList.add(pmPnsortTra);

        }
        // 更新或者新增
        pmPnsortRepository.batchUpdateByPrimaryKey(updateList);
        pmPnsortRepository.batchInsertSelective(insertList);

        for (PmPnsort pmPnsort : insertList) {
            PmPnsortTra pmPnsortTra = new PmPnsortTra();
            BeanUtils.copy(pmPnsort, pmPnsortTra);

            // 设置操作类型为新增（I），并记录操作时间和用户
            pmPnsortTra.setOperationType("I");
            pmPnsortTra.setOperationTime(now);
            pmPnsortTra.setOperationUser(username);
            insertTraList.add(pmPnsortTra);

        }
        // 插入保存或者更新记录到对应履历表
        pmPnsortTraRepository.batchInsertSelective(insertTraList);
    }

    public String getKey(PmPnsort pmPnsort) {
        return pmPnsort.getMainBacklogCode() + pmPnsort.getCcType() + pmPnsort.getPriority1() + pmPnsort.getPriority2()
                + pmPnsort.getPriority3() + pmPnsort.getPriority4() + pmPnsort.getPriority5() + pmPnsort.getPriority6()
                + pmPnsort.getPriority7() + pmPnsort.getPriority8() + pmPnsort.getSortFlag();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteForUi(List<PmPnsort> pmPnsortList) {
        if (CollectionUtils.isNotEmpty(pmPnsortList)) {
            // 删除
            pmPnsortRepository.batchDeleteByPrimaryKey(pmPnsortList);

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmPnsortTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmPnsortList.size());
            for (PmPnsort pmPnsort : pmPnsortList) {
                PmPnsortTra pmPnsortTra = new PmPnsortTra();

                // 设置操作类型为删除（D），并记录操作时间和用户
                BeanUtils.copy(pmPnsort, pmPnsortTra);
                pmPnsortTra.setOperationType("D");
                pmPnsortTra.setOperationTime(now);
                pmPnsortTra.setOperationUser(username);
                insertPmMoldSpecBtTraList.add(pmPnsortTra);

            }
            // 插入删除记录到对应履历表
            pmPnsortTraRepository.batchInsertSelective(insertPmMoldSpecBtTraList);
        }
    }
}

