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

import com.xisc.pm.api.dto.export.PmSpeStAddvBtDTO;
import com.xisc.pm.app.service.PmSpeStAddvBtService;
import com.xisc.pm.domain.entity.PmSpeStAddvBt;
import com.xisc.pm.domain.entity.PmSpeStAddvBtTra;
import com.xisc.pm.domain.repository.PmSpeStAddvBtRepository;
import com.xisc.pm.domain.repository.PmSpeStAddvBtTraRepository;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.util.BeanUtils;
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.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.stream.Collectors;

/**
 * 特殊钢种余量增加表(PmSpeStAddvBt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-25 08:50:16
 */
@Service
public class PmSpeStAddvBtServiceImpl implements PmSpeStAddvBtService {

    private PmSpeStAddvBtRepository pmSpeStAddvBtRepository;

    private PmSpeStAddvBtTraRepository pmSpeStAddvBtTraRepository;

    private LovAdapter lovAdapter;

    public PmSpeStAddvBtServiceImpl(PmSpeStAddvBtRepository pmSpeStAddvBtRepository, PmSpeStAddvBtTraRepository pmSpeStAddvBtTraRepository, LovAdapter lovAdapter) {
        this.pmSpeStAddvBtRepository = pmSpeStAddvBtRepository;
        this.pmSpeStAddvBtTraRepository = pmSpeStAddvBtTraRepository;
        this.lovAdapter = lovAdapter;
    }

    @Override
    public Page<PmSpeStAddvBt> selectList(PageRequest pageRequest, PmSpeStAddvBt pmSpeStAddvBt) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmSpeStAddvBtRepository.selectList(pmSpeStAddvBt));
    }

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

                    throw new CommonException("pm.spe_st_addv_bt_001",
                            speStAddvBtList.get(j).getPlateThickFrom(), speStAddvBtList.get(j).getPlateThickTo(),
                            speStAddvBtList.get(j).getSlabThickFrom(), speStAddvBtList.get(j).getSlabThickTo());
                }
            }
        }

        // 与数据库记录校验区间是否交叉
        List<String> mscLineList = pmSpeStAddvBtList.stream().map(PmSpeStAddvBt::getMscLineNo).distinct().collect(Collectors.toList());
        List<String> stNoList = pmSpeStAddvBtList.stream().map(PmSpeStAddvBt::getStNo).distinct().collect(Collectors.toList());
        List<String> sgSignList = pmSpeStAddvBtList.stream().map(PmSpeStAddvBt::getSgSign).distinct().collect(Collectors.toList());
        List<PmSpeStAddvBt> existSpeStAddvBtList = pmSpeStAddvBtRepository.selectByCondition(Condition.builder(PmSpeStAddvBt.class)
                .andWhere(Sqls.custom().andIn(PmSpeStAddvBt.FIELD_MSC_LINE_NO, mscLineList))
                .andWhere(Sqls.custom().andIn(PmSpeStAddvBt.FIELD_ST_NO, stNoList))
                .andWhere(Sqls.custom().andIn(PmSpeStAddvBt.FIELD_SG_SIGN, sgSignList))
                .andWhere(Sqls.custom().andEqualTo(PmSpeStAddvBt.FIELD_TENANT_ID, tenantId))
                .build());
        if (CollectionUtils.isNotEmpty(existSpeStAddvBtList)) {
            Map<String, List<PmSpeStAddvBt>> existMap = existSpeStAddvBtList.stream().collect(Collectors.groupingBy(this::getTmpKey));
            for (PmSpeStAddvBt pmSpeStAddvBt : pmSpeStAddvBtList) {
                if (existMap.containsKey(getTmpKey(pmSpeStAddvBt))) {
                    List<PmSpeStAddvBt> existBtList = existMap.get(getTmpKey(pmSpeStAddvBt));
                    for (PmSpeStAddvBt speStAddvBt : existBtList) {
                        // 校验钢板厚度区间是否交叉
                        boolean plateThickIntervalCheck = Utils.isIntersect(pmSpeStAddvBt.getPlateThickFrom(), pmSpeStAddvBt.getPlateThickTo(),
                                speStAddvBt.getPlateThickFrom(), speStAddvBt.getPlateThickTo());
                        if (!plateThickIntervalCheck) {
                            continue;
                        }

                        // 校验板坯厚度区间是否交叉
                        boolean slabThickIntervalCheck = Utils.isIntersect(pmSpeStAddvBt.getSlabThickFrom(), pmSpeStAddvBt.getSlabThickTo(),
                                speStAddvBt.getSlabThickFrom(), speStAddvBt.getSlabThickTo());
                        if (!slabThickIntervalCheck) {
                            continue;
                        }
                        throw new CommonException("pm.spe_st_addv_bt_002",
                                speStAddvBt.getPlateThickFrom(), speStAddvBt.getPlateThickTo(),
                                speStAddvBt.getSlabThickFrom(), speStAddvBt.getSlabThickTo());
                    }
                }
            }
        }

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

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

        // 记录历史表
        for (PmSpeStAddvBt pmSpeStAddvBt : updateList) {
            PmSpeStAddvBtTra pmSpeStAddvBtTra = new PmSpeStAddvBtTra();
            BeanUtils.copy(pmSpeStAddvBt, pmSpeStAddvBtTra);

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

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

        for (PmSpeStAddvBt pmSpeStAddvBt : insertList) {
            PmSpeStAddvBtTra pmSpeStAddvBtTra = new PmSpeStAddvBtTra();
            BeanUtils.copy(pmSpeStAddvBt, pmSpeStAddvBtTra);

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

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

    @Override
    public String getTmpKey(PmSpeStAddvBt pmSpeStAddvBt) {
        return pmSpeStAddvBt.getMscLineNo() + pmSpeStAddvBt.getStNo() + pmSpeStAddvBt.getSgSign();
    }

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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmSpeStAddvBtTra> insertPmSpeStAddvBtTraList = new ArrayList<>(pmSpeStAddvBtList.size());
            for (PmSpeStAddvBt pmSpeStAddvBt : pmSpeStAddvBtList) {
                PmSpeStAddvBtTra pmSpeStAddvBtTra = new PmSpeStAddvBtTra();

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

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

    @Override
    public List<PmSpeStAddvBtDTO> exportList(PmSpeStAddvBt pmSpeStAddvBt) {
        List<PmSpeStAddvBt> pmSpeStAddvBtList = pmSpeStAddvBtRepository.selectList(pmSpeStAddvBt);
        // 如果集合为空，则返回
        if (CollectionUtils.isEmpty(pmSpeStAddvBtList)) {
            return Collections.emptyList();
        }
        // 获取生效标记记含义
        List<LovValueDTO> validFlagList = lovAdapter.queryLovValue(Constants.LovCode.XISC_WHETHER_FLAG_01, pmSpeStAddvBt.getTenantId());
        // 产线号含义
        List<LovValueDTO> mscLineNoList = lovAdapter.queryLovValue("PM.MSC_LINE_NO", pmSpeStAddvBt.getTenantId());
        Map<String, String> validFlagLovMap = new HashMap<>(validFlagList.size());
        Map<String, String> mscLineNoLovMap = new HashMap<>(mscLineNoList.size());

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

        List<PmSpeStAddvBtDTO> resultList = new ArrayList<>();
        for (PmSpeStAddvBt line : pmSpeStAddvBtList) {
            if (!validFlagLovMap.isEmpty()) {
                line.setValidFlagDesc(validFlagLovMap.getOrDefault(line.getValidFlag(), ""));
            }
            if (!mscLineNoLovMap.isEmpty()) {
                line.setMscLineNoDesc(mscLineNoLovMap.getOrDefault(line.getMscLineNo(), ""));
            }
            PmSpeStAddvBtDTO pmSpeStAddvBtDTO = new PmSpeStAddvBtDTO();
            BeanUtils.copy(line, pmSpeStAddvBtDTO);
            resultList.add(pmSpeStAddvBtDTO);
        }
        return resultList;
    }
}

