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


import com.xisc.pm.api.dto.export.PmPlateSpecYieldBtDTO;
import com.xisc.pm.app.service.PmPlateSpecYieldBtService;
import com.xisc.pm.domain.entity.PmPlateSpecYieldBt;
import com.xisc.pm.domain.entity.PmPlateSpecYieldBtTra;
import com.xisc.pm.domain.repository.PmPlateSpecYieldBtRepository;
import com.xisc.pm.domain.repository.PmPlateSpecYieldBtTraRepository;
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;

/**
 * 钢板轧制规格对应收得率基准表(PmPlateSpecYieldBt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-23 16:29:25
 */
@Service
public class PmPlateSpecYieldBtServiceImpl implements PmPlateSpecYieldBtService {

    private PmPlateSpecYieldBtRepository pmPlateSpecYieldBtRepository;

    private PmPlateSpecYieldBtTraRepository pmPlateSpecYieldBtTraRepository;

    private LovAdapter lovAdapter;

    public PmPlateSpecYieldBtServiceImpl(PmPlateSpecYieldBtRepository pmPlateSpecYieldBtRepository, PmPlateSpecYieldBtTraRepository pmPlateSpecYieldBtTraRepository, LovAdapter lovAdapter) {
        this.pmPlateSpecYieldBtRepository = pmPlateSpecYieldBtRepository;
        this.pmPlateSpecYieldBtTraRepository = pmPlateSpecYieldBtTraRepository;
        this.lovAdapter = lovAdapter;
    }

    @Override
    public Page<PmPlateSpecYieldBt> selectList(PageRequest pageRequest, PmPlateSpecYieldBt pmPlateSpecYieldBt) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmPlateSpecYieldBtRepository.selectList(pmPlateSpecYieldBt));
    }

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

        // 新增记录之间校验区间是否交叉
        for (int i = 0; i < pmPlateSpecYieldBtList.size() - 1; i++) {
            for (int j = i + 1; j < pmPlateSpecYieldBtList.size(); j++) {

                // 校验钢板厚度区间是否交叉
                boolean slabThickIntervalCheck = Utils.isIntersect(pmPlateSpecYieldBtList.get(i).getPlateThickFrom(), pmPlateSpecYieldBtList.get(i).getPlateThickTo(),
                        pmPlateSpecYieldBtList.get(j).getPlateThickFrom(), pmPlateSpecYieldBtList.get(j).getPlateThickTo());
                if (slabThickIntervalCheck) {
                    throw new CommonException("pm.cut_place_bt_001",pmPlateSpecYieldBtList.get(j).getPlateThickFrom(), pmPlateSpecYieldBtList.get(j).getPlateThickTo());
                }

                // 校验组合板宽度区间是否交叉
                boolean combinePlateWidthIntervalCheck = Utils.isIntersect(pmPlateSpecYieldBtList.get(i).getCombinePlateWidthFrom(), pmPlateSpecYieldBtList.get(i).getCombinePlateWidthTo(),
                        pmPlateSpecYieldBtList.get(j).getCombinePlateWidthFrom(), pmPlateSpecYieldBtList.get(j).getCombinePlateWidthTo());
                if (combinePlateWidthIntervalCheck) {
                    throw new CommonException("", pmPlateSpecYieldBtList.get(j).getCombinePlateWidthFrom(), pmPlateSpecYieldBtList.get(j).getCombinePlateWidthTo());
                }


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

        // 排除与要更新的数据相互校验
        List<PmPlateSpecYieldBt> existPlateSpecYieldBtList = pmPlateSpecYieldBtRepository.selectByCondition(Condition.builder(PmPlateSpecYieldBt.class)
                .andWhere(Sqls.custom().andEqualTo(PmPlateSpecYieldBt.FIELD_TENANT_ID, tenantId))
                .build());
        if (CollectionUtils.isNotEmpty(existPlateSpecYieldBtList)) {
            // 与数据库记录校验区间是否交叉
            for (int i = 0; i < pmPlateSpecYieldBtList.size(); i++) {
                for (int j = 0; j < existPlateSpecYieldBtList.size(); j++) {
                    // 如果是更新的话，不跟自己比较
                    if (pmPlateSpecYieldBtList.get(i).getPpsybId() != null &&
                            pmPlateSpecYieldBtList.get(i).getPpsybId().equals(existPlateSpecYieldBtList.get(j).getPpsybId())) {
                        continue;
                    }

                    // 校验钢板厚度区间是否交叉
                    boolean slabThickIntervalCheck = Utils.isIntersect(pmPlateSpecYieldBtList.get(i).getPlateThickFrom(),
                            pmPlateSpecYieldBtList.get(i).getPlateThickTo(), existPlateSpecYieldBtList.get(j).getPlateThickFrom(),
                            existPlateSpecYieldBtList.get(j).getPlateThickTo());
                    if (slabThickIntervalCheck) {
                        throw new CommonException("pm.cut_place_bt_001", existPlateSpecYieldBtList.get(j).getPlateThickFrom(), existPlateSpecYieldBtList.get(j).getPlateThickTo());
                    }

                    // 校验组合板宽度区间是否交叉
                    boolean combinePlateWidthIntervalCheck = Utils.isIntersect(pmPlateSpecYieldBtList.get(i).getCombinePlateWidthFrom(),
                            pmPlateSpecYieldBtList.get(i).getCombinePlateWidthTo(), existPlateSpecYieldBtList.get(j).getCombinePlateWidthFrom(),
                            existPlateSpecYieldBtList.get(j).getCombinePlateWidthTo());
                    if (combinePlateWidthIntervalCheck) {
                        throw new CommonException("pm.plate_spec_yield_bt", existPlateSpecYieldBtList.get(j).getCombinePlateWidthFrom(), existPlateSpecYieldBtList.get(j).getCombinePlateWidthTo());
                    }
                }
            }
        }

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


        // 记录历史表
        for (PmPlateSpecYieldBt pmPlateSpecYieldBt : updateList) {
            PmPlateSpecYieldBtTra pmPlateSpecYieldBtTra = new PmPlateSpecYieldBtTra();
            BeanUtils.copy(pmPlateSpecYieldBt, pmPlateSpecYieldBtTra);

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

        }
        // 更新或者新增
        pmPlateSpecYieldBtRepository.batchUpdateByPrimaryKeySelective(updateList);
        pmPlateSpecYieldBtRepository.batchInsertSelective(insertList);

        for (PmPlateSpecYieldBt pmPlateSpecYieldBt : insertList) {
            PmPlateSpecYieldBtTra pmPlateSpecYieldBtTra = new PmPlateSpecYieldBtTra();
            BeanUtils.copy(pmPlateSpecYieldBt, pmPlateSpecYieldBtTra);

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

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

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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmPlateSpecYieldBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmPlateSpecYieldBtList.size());
            for (PmPlateSpecYieldBt pmPlateSpecYieldBt : pmPlateSpecYieldBtList) {
                PmPlateSpecYieldBtTra pmPlateSpecYieldBtTra = new PmPlateSpecYieldBtTra();

                // 设置操作类型为删除（D），并记录操作时间和用户
                BeanUtils.copy(pmPlateSpecYieldBt, pmPlateSpecYieldBtTra);
                pmPlateSpecYieldBtTra.setOperationType("D");
                pmPlateSpecYieldBtTra.setOperationTime(now);
                pmPlateSpecYieldBtTra.setOperationUser(username);
                insertPmMoldSpecBtTraList.add(pmPlateSpecYieldBtTra);
            }
            // 插入删除记录到对应履历表
            pmPlateSpecYieldBtTraRepository.batchInsertSelective(insertPmMoldSpecBtTraList);
        }
    }

    @Override
    public List<PmPlateSpecYieldBtDTO> exportList(PmPlateSpecYieldBt pmPlateSpecYieldBt) {
        List<PmPlateSpecYieldBt> plateSpecYieldBtList = pmPlateSpecYieldBtRepository.selectList(pmPlateSpecYieldBt);
        // 如果集合为空，则返回
        if (CollectionUtils.isEmpty(plateSpecYieldBtList)) {
            return Collections.EMPTY_LIST;
        }
        // 获取坯料类型含义
        List<LovValueDTO> cgTypeLovList = lovAdapter.queryLovValue(Constants.LovCode.CC_TYPE, pmPlateSpecYieldBt.getTenantId());
        // 轧制产线号含义
        List<LovValueDTO> rollLineNoList = lovAdapter.queryLovValue(Constants.LovCode.ROLL_LINE_NO, pmPlateSpecYieldBt.getTenantId());
        Map<String, String> cgTypeLovMap = new HashMap<>(cgTypeLovList.size());
        Map<String, String> rollLineNoLovMap = new HashMap<>(rollLineNoList.size());

        // 赋值
        if (CollectionUtils.isNotEmpty(cgTypeLovList)) {
            cgTypeLovMap = cgTypeLovList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }
        if (CollectionUtils.isNotEmpty(rollLineNoList)) {
            rollLineNoLovMap = rollLineNoList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }

        List<PmPlateSpecYieldBtDTO> resultList = new ArrayList<>(plateSpecYieldBtList.size());
        for (PmPlateSpecYieldBt line : plateSpecYieldBtList) {
            if (!cgTypeLovMap.isEmpty()) {
                line.setCcTypeDesc(cgTypeLovMap.getOrDefault(line.getCcType(), ""));
            }
            if (!rollLineNoLovMap.isEmpty()) {
                line.setRollLineNoDesc(rollLineNoLovMap.getOrDefault(line.getRollLineNo(), ""));
            }
            PmPlateSpecYieldBtDTO pmPlateSpecYieldBtDTO = new PmPlateSpecYieldBtDTO();
            BeanUtils.copy(line, pmPlateSpecYieldBtDTO);
            resultList.add(pmPlateSpecYieldBtDTO);
        }
        return resultList;
    }
}


