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

import com.xisc.pm.api.dto.export.PmSlabReplBtDTO;
import com.xisc.pm.app.service.PmSlabReplBtService;
import com.xisc.pm.domain.entity.PmSlabReplBt;
import com.xisc.pm.domain.entity.PmSlabReplBtTra;
import com.xisc.pm.domain.repository.PmSlabReplBtRepository;
import com.xisc.pm.domain.repository.PmSlabReplBtTraRepository;
import com.xisc.pm.infra.constant.Constants;
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.boot.platform.lov.adapter.LovAdapter;
import org.hzero.boot.platform.lov.dto.LovValueDTO;
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.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 余材组板内部钢种以优充次对照表(PmSlabReplBt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-24 11:30:29
 */
@Service
public class PmSlabReplBtServiceImpl implements PmSlabReplBtService {

    private PmSlabReplBtRepository pmSlabReplBtRepository;

    private PmSlabReplBtTraRepository pmSlabReplBtTraRepository;

    private LovAdapter lovAdapter;

    public PmSlabReplBtServiceImpl(PmSlabReplBtRepository pmSlabReplBtRepository, PmSlabReplBtTraRepository pmSlabReplBtTraRepository, LovAdapter lovAdapter) {
        this.pmSlabReplBtRepository = pmSlabReplBtRepository;
        this.pmSlabReplBtTraRepository = pmSlabReplBtTraRepository;
        this.lovAdapter = lovAdapter;
    }

    @Override
    public Page<PmSlabReplBt> selectList(PageRequest pageRequest, PmSlabReplBt pmSlabReplBt) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmSlabReplBtRepository.selectList(pmSlabReplBt));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, List<PmSlabReplBt> pmSlabReplBtList) {
        // 检查列表是否为空，如果为空则直接返回。
        if (CollectionUtils.isEmpty(pmSlabReplBtList)) {
            return;
        }

        // a.	唯一性索引：以优充次顺序码、当前出钢记号
        // b.	唯一性索引：当前出钢记号、替代出钢记号
        Map<String, List<PmSlabReplBt>> slabMap = pmSlabReplBtList.stream().collect(Collectors
                .groupingBy(pmSlabReplBt -> pmSlabReplBt.getBetterToWorseSeq() + pmSlabReplBt.getCurStNo()));
        Map<String, List<PmSlabReplBt>> relMap = pmSlabReplBtList.stream().collect(Collectors
                .groupingBy(pmSlabReplBt -> pmSlabReplBt.getCurStNo() + pmSlabReplBt.getReplStNo()));
        for(Map.Entry<String, List<PmSlabReplBt>> entry : slabMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                throw new CommonException("pm.slab_repl_bt_001",entry.getValue().get(0).getBetterToWorseSeq(),
                        entry.getValue().get(0).getCurStNo());
            }
        }
        for(Map.Entry<String, List<PmSlabReplBt>>entry : relMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                throw new CommonException("pm.slab_repl_bt_002",entry.getValue().get(0).getCurStNo(),
                        entry.getValue().get(0).getReplStNo());
            }
        }
        List<Long> betterSeqList = pmSlabReplBtList.stream().map(PmSlabReplBt::getBetterToWorseSeq).distinct().collect(Collectors.toList());
        List<String> curStNoList = pmSlabReplBtList.stream().map(PmSlabReplBt::getCurStNo).distinct().collect(Collectors.toList());
        List<String> replStNoList = pmSlabReplBtList.stream().map(PmSlabReplBt::getReplStNo).distinct().collect(Collectors.toList());
        List<Long> idList = pmSlabReplBtList.stream().filter(item -> item.getPsrbId() != null).map(PmSlabReplBt::getPsrbId).collect(Collectors.toList());
        // a.	唯一性索引：以优充次顺序码、当前出钢记号
        List<PmSlabReplBt> existSlabReplBtList = pmSlabReplBtRepository.selectByCondition(Condition.builder(PmSlabReplBt.class)
                .andWhere(Sqls.custom().andIn(PmSlabReplBt.FIELD_BETTER_TO_WORSE_SEQ, betterSeqList))
                .andWhere(Sqls.custom().andIn(PmSlabReplBt.FIELD_CUR_ST_NO, curStNoList))
                .andWhere(Sqls.custom().andEqualTo(PmSlabReplBt.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andNotIn(PmSlabReplBt.FIELD_PSRB_ID, idList, true))
                .build());
        if (CollectionUtils.isNotEmpty(existSlabReplBtList)) {
            Map<String, PmSlabReplBt> existSlabMap = existSlabReplBtList.stream().collect(Collectors
                    .toMap(pmSlabReplBt -> pmSlabReplBt.getBetterToWorseSeq() + pmSlabReplBt.getCurStNo(), Function.identity(), (k,v)->k));
            for (PmSlabReplBt pmSlabReplBt : pmSlabReplBtList) {
                if (existSlabMap.containsKey(pmSlabReplBt.getBetterToWorseSeq() + pmSlabReplBt.getCurStNo())) {
                    PmSlabReplBt slabRelBt = existSlabMap.get(pmSlabReplBt.getBetterToWorseSeq() + pmSlabReplBt.getCurStNo());
                    throw new CommonException("pm.slab_repl_bt_003",slabRelBt.getBetterToWorseSeq(), slabRelBt.getCurStNo());
                }
            }
        }

        // b.	唯一性索引：当前出钢记号、替代出钢记号
        List<PmSlabReplBt> existRelSlabReplBtList = pmSlabReplBtRepository.selectByCondition(Condition.builder(PmSlabReplBt.class)
                .andWhere(Sqls.custom().andIn(PmSlabReplBt.FIELD_CUR_ST_NO, curStNoList))
                .andWhere(Sqls.custom().andIn(PmSlabReplBt.FIELD_REPL_ST_NO, replStNoList))
                .andWhere(Sqls.custom().andEqualTo(PmSlabReplBt.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andNotIn(PmSlabReplBt.FIELD_PSRB_ID, idList, true))
                .build());
        if (CollectionUtils.isNotEmpty(existRelSlabReplBtList)) {
            Map<String, PmSlabReplBt> existRelMap = existRelSlabReplBtList.stream().collect(Collectors
                    .toMap(pmSlabReplBt -> pmSlabReplBt.getCurStNo() + pmSlabReplBt.getReplStNo(), Function.identity(), (k,v)->k));
            for (PmSlabReplBt pmSlabReplBt : pmSlabReplBtList) {
                if (existRelMap.containsKey(pmSlabReplBt.getCurStNo() + pmSlabReplBt.getReplStNo())) {
                    PmSlabReplBt slabRelBt = existRelMap.get(pmSlabReplBt.getCurStNo() + pmSlabReplBt.getReplStNo());
                    throw new CommonException("pm.slab_repl_bt_004",slabRelBt.getCurStNo(), slabRelBt.getReplStNo());
                }
            }
        }

        // 获取当前时间和用户信息。
        Date now = new Date();
        String username = DetailsHelper.getUserDetails().getUsername();

        // 初始化用于记录操作历史的列表
        List<PmSlabReplBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmSlabReplBtList.size());

        // 分别筛选出待新增和待更新的
        List<PmSlabReplBt> insertList = pmSlabReplBtList.stream().filter(line -> line.getPsrbId() == null).collect(Collectors.toList());
        List<PmSlabReplBt> updateList = pmSlabReplBtList.stream().filter(line -> line.getPsrbId() != null).collect(Collectors.toList());


        // 记录历史表
        for (PmSlabReplBt pmSlabReplBt : updateList) {
            PmSlabReplBtTra pmSlabReplBtTra = new PmSlabReplBtTra();
            BeanUtils.copy(pmSlabReplBt, pmSlabReplBtTra);

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

        // 执行批量插入和更新操作
        pmSlabReplBtRepository.batchUpdateByPrimaryKey(updateList);
        pmSlabReplBtRepository.batchInsertSelective(insertList);

        // 处理待新增的生成操作历史记录。
        for (PmSlabReplBt pmSlabReplBt : insertList) {
            PmSlabReplBtTra pmSlabReplBtTra = new PmSlabReplBtTra();
            BeanUtils.copy(pmSlabReplBt, pmSlabReplBtTra);

            // 设置操作类型为插入（I），并记录操作时间和用户
            pmSlabReplBtTra.setOperationType("I");
            pmSlabReplBtTra.setOperationTime(now);
            pmSlabReplBtTra.setOperationUser(username);
            insertPmMoldSpecBtTraList.add(pmSlabReplBtTra);
        }

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


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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmSlabReplBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmSlabReplBtList.size());
            for (PmSlabReplBt pmSlabReplBt : pmSlabReplBtList) {
                PmSlabReplBtTra pmSlabReplBtTra = new PmSlabReplBtTra();

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

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

    @Override
    public List<PmSlabReplBtDTO> exportList(PmSlabReplBt pmSlabReplBt) {
        List<PmSlabReplBt> pmSlabReplBtList = pmSlabReplBtRepository.selectList(pmSlabReplBt);
        // 如果集合为空，则返回
        if (CollectionUtils.isEmpty(pmSlabReplBtList)) {
            return Collections.emptyList();
        }
        // 获取生效标记记含义
        List<LovValueDTO> validFlagList = lovAdapter.queryLovValue(Constants.LovCode.XISC_WHETHER_FLAG_01, pmSlabReplBt.getTenantId());

        Map<String, String> validFlagLovMap = new HashMap<>(validFlagList.size());


        // 赋值
        if (CollectionUtils.isNotEmpty(validFlagList)) {
            validFlagLovMap = validFlagList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }

        List<PmSlabReplBtDTO> resultList = new ArrayList<>(pmSlabReplBtList.size());
        for (PmSlabReplBt line : pmSlabReplBtList) {
            if (!validFlagLovMap.isEmpty()) {
                line.setValidFlagDesc(validFlagLovMap.getOrDefault(line.getValidFlag(), ""));
            }
            PmSlabReplBtDTO pmSlabReplBtDTO = new PmSlabReplBtDTO();
            BeanUtils.copy(line, pmSlabReplBtDTO);
            resultList.add(pmSlabReplBtDTO);
        }
        return resultList;
    }
}

