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

import com.xisc.pm.app.service.PmSdivStLimitBtService;
import com.xisc.pm.domain.entity.PmSdivStLimitBt;
import com.xisc.pm.domain.entity.PmSdivStLimitBtTra;
import com.xisc.pm.domain.repository.PmSdivStLimitBtRepository;
import com.xisc.pm.domain.repository.PmSdivStLimitBtTraRepository;
import com.xisc.pm.infra.util.Utils;
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.beans.BeanUtils;
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;

/**
 * 剖分组板钢种限制表(PmSdivStLimitBt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-25 08:15:36
 */
@Service
public class PmSdivStLimitBtServiceImpl implements PmSdivStLimitBtService {

    private PmSdivStLimitBtRepository pmSdivStLimitBtRepository;

    private PmSdivStLimitBtTraRepository pmSdivStLimitBtTraRepository;

    public PmSdivStLimitBtServiceImpl(PmSdivStLimitBtRepository pmSdivStLimitBtRepository, PmSdivStLimitBtTraRepository pmSdivStLimitBtTraRepository) {
        this.pmSdivStLimitBtRepository = pmSdivStLimitBtRepository;
        this.pmSdivStLimitBtTraRepository = pmSdivStLimitBtTraRepository;
    }

    @Override
    public Page<PmSdivStLimitBt> selectList(PageRequest pageRequest, PmSdivStLimitBt pmSdivStLimitBt) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmSdivStLimitBtRepository.selectList(pmSdivStLimitBt));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, List<PmSdivStLimitBt> pmSdivStLimitBtList) {
        // 检查数据列表是否为空，如果为空则直接返回
        if (CollectionUtils.isEmpty(pmSdivStLimitBtList)) {
            return;
        }
        Map<String, List<PmSdivStLimitBt>> pmSdivStLimitBtMap = pmSdivStLimitBtList.stream().collect(Collectors.groupingBy(this::getKey));
        for (Map.Entry<String, List<PmSdivStLimitBt>> entry : pmSdivStLimitBtMap.entrySet()) {
            List<PmSdivStLimitBt> sdivStLimitBtList = entry.getValue();
            for (int i = 0; i < sdivStLimitBtList.size() - 1; i++) {
                for (int j = i + 1; j < sdivStLimitBtList.size(); j++) {
                    // 校验板坯厚度区间是否交叉
                    boolean slabThickIntervalCheck = Utils.isIntersect(sdivStLimitBtList.get(i).getSlabThickFrom(),
                            sdivStLimitBtList.get(i).getSlabThickTo(), sdivStLimitBtList.get(j).getSlabThickFrom(),
                            sdivStLimitBtList.get(j).getSlabThickTo());
                    if (!slabThickIntervalCheck) {
                        continue;
                    }

                    // 校验板坯宽度区间是否交叉
                    boolean slabWidthIntervalCheck = Utils.isIntersect(sdivStLimitBtList.get(i).getSlabWidthFrom(),
                            sdivStLimitBtList.get(i).getSlabWidthTo(), sdivStLimitBtList.get(j).getSlabWidthFrom(),
                            sdivStLimitBtList.get(j).getSlabWidthTo());
                    if (!slabWidthIntervalCheck) {
                        continue;
                    }

                    throw new CommonException("pm.wm_ww_bt_009", sdivStLimitBtList.get(j).getSlabThickFrom(),
                            sdivStLimitBtList.get(j).getSlabThickTo(), sdivStLimitBtList.get(j).getSlabWidthFrom(),
                            sdivStLimitBtList.get(j).getSlabWidthTo());
                }
            }
        }

        List<String> stNoList = pmSdivStLimitBtList.stream().map(PmSdivStLimitBt::getStNo).distinct().collect(Collectors.toList());
        List<String> sgSignList = pmSdivStLimitBtList.stream().map(PmSdivStLimitBt::getSgSign).distinct().collect(Collectors.toList());
        List<Long> idList = pmSdivStLimitBtList.stream().filter(item -> item.getPsslbId() != null).map(PmSdivStLimitBt::getPsslbId).collect(Collectors.toList());
        List<PmSdivStLimitBt> sdivStLimitBtList = pmSdivStLimitBtRepository.selectByCondition(Condition.builder(PmSdivStLimitBt.class)
                .andWhere(Sqls.custom().andIn(PmSdivStLimitBt.FIELD_ST_NO, stNoList))
                .andWhere(Sqls.custom().andIn(PmSdivStLimitBt.FIELD_SG_SIGN, sgSignList))
                .andWhere(Sqls.custom().andEqualTo(PmSdivStLimitBt.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andNotIn(PmSdivStLimitBt.FIELD_PSSLB_ID, idList, true))
                .build());
        if (CollectionUtils.isNotEmpty(sdivStLimitBtList)) {
            Map<String, List<PmSdivStLimitBt>> existMap = sdivStLimitBtList.stream().collect(Collectors.groupingBy(this::getKey));
            for (PmSdivStLimitBt pmSdivStLimitBt : pmSdivStLimitBtList) {
                if (existMap.containsKey(getKey(pmSdivStLimitBt))) {
                    List<PmSdivStLimitBt> stLimitBtList = existMap.get(getKey(pmSdivStLimitBt));
                    for (PmSdivStLimitBt stLimitBt : stLimitBtList) {
                        // 校验板坯厚度区间是否交叉
                        boolean slabThickIntervalCheck = Utils.isIntersect(pmSdivStLimitBt.getSlabThickFrom(),
                                pmSdivStLimitBt.getSlabThickTo(), stLimitBt.getSlabThickFrom(),
                                stLimitBt.getSlabThickTo());
                        if (!slabThickIntervalCheck) {
                            continue;
                        }

                        // 校验板坯宽度区间是否交叉
                        boolean slabWidthIntervalCheck = Utils.isIntersect(pmSdivStLimitBt.getSlabWidthFrom(),
                                pmSdivStLimitBt.getSlabWidthTo(), stLimitBt.getSlabWidthFrom(),
                                stLimitBt.getSlabWidthTo());
                        if (!slabWidthIntervalCheck) {
                            continue;
                        }

                        throw new CommonException("pm.wm_ww_bt_010", stLimitBt.getSlabThickFrom(),
                                stLimitBt.getSlabThickTo(), stLimitBt.getSlabWidthFrom(),
                                stLimitBt.getSlabWidthTo());
                    }
                }

            }
        }
        // 获取当前时间及操作人信息
        Date now = new Date();
        String username = DetailsHelper.getUserDetails().getUsername();
        List<PmSdivStLimitBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmSdivStLimitBtList.size());

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

        // 记录历史表
        for (PmSdivStLimitBt pmSdivStLimitBt : updateList) {
            PmSdivStLimitBtTra pmSdivStLimitBtTra = new PmSdivStLimitBtTra();
            BeanUtils.copyProperties(pmSdivStLimitBt, pmSdivStLimitBtTra);

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

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

        for (PmSdivStLimitBt pmSdivStLimitBt : insertList) {
            PmSdivStLimitBtTra pmSdivStLimitBtTra = new PmSdivStLimitBtTra();
            BeanUtils.copyProperties(pmSdivStLimitBt, pmSdivStLimitBtTra);

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

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

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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmSdivStLimitBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmSdivStLimitBtList.size());
            for (PmSdivStLimitBt pmSdivStLimitBt : pmSdivStLimitBtList) {
                PmSdivStLimitBtTra pmSdivStLimitBtTra = new PmSdivStLimitBtTra();

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

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

    public String getKey(PmSdivStLimitBt pmSdivStLimitBt) {
        return pmSdivStLimitBt.getSgSign() + pmSdivStLimitBt.getStNo();
    }
}

