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

import com.xisc.pm.app.service.PmHotConfigService;
import com.xisc.pm.domain.entity.PmHotConfig;
import com.xisc.pm.domain.entity.PmHotConfigTra;
import com.xisc.pm.domain.repository.PmHotConfigRepository;
import com.xisc.pm.domain.repository.PmHotConfigTraRepository;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 组炉默认热处理去向配置表(PmHotConfig)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-25 10:19:08
 */
@Service
public class PmHotConfigServiceImpl implements PmHotConfigService {

    private PmHotConfigRepository pmHotConfigRepository;

    private PmHotConfigTraRepository pmHotConfigTraRepository;


    public PmHotConfigServiceImpl(PmHotConfigRepository pmHotConfigRepository, PmHotConfigTraRepository pmHotConfigTraRepository) {
        this.pmHotConfigRepository = pmHotConfigRepository;
        this.pmHotConfigTraRepository = pmHotConfigTraRepository;
    }

    @Override
    public Page<PmHotConfig> selectList(PageRequest pageRequest, PmHotConfig pmHotConfig) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmHotConfigRepository.selectList(pmHotConfig));
    }

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

        // 新增记录之间校验区间是否重复
        Map<String, List<PmHotConfig>> pmHotConfigMap = pmHotConfigList.stream().collect(Collectors.groupingBy(this::getConfigKey));
        for (Map.Entry<String, List<PmHotConfig>> entry : pmHotConfigMap.entrySet()) {
            List<PmHotConfig> configList = entry.getValue();
            for (int i = 0; i < configList.size() - 1; i++) {
                for (int j = i + 1; j < configList.size(); j++) {
                    // 钢板厚度
                    boolean plateThickIntervalCheck = Utils.isIntersect(configList.get(i).getPlateThickFrom(),
                            configList.get(i).getPlateThickTo(), configList.get(j).getPlateThickFrom(), configList.get(j).getPlateThickTo());
                    if (!plateThickIntervalCheck) {
                        continue;
                    }

                    // 钢板宽度
                    boolean plateWidIntervalCheck = Utils.isIntersect(configList.get(i).getPlateWidFrom(),
                            configList.get(i).getPlateWidTo(), configList.get(j).getPlateWidFrom(), configList.get(j).getPlateWidTo());
                    if (!plateWidIntervalCheck) {
                        continue;
                    }

                    // 钢板长度
                    boolean plateLenIntervalCheck = Utils.isIntersect(configList.get(i).getPlateLenFrom(),
                            configList.get(i).getPlateLenTo(), configList.get(j).getPlateLenFrom(), configList.get(j).getPlateLenTo());
                    if (!plateLenIntervalCheck) {
                        continue;
                    }

                    throw new CommonException("pm.hot_config_001", configList.get(j).getPlateThickFrom(), configList.get(j).getPlateThickTo(),
                            configList.get(j).getPlateWidFrom(), configList.get(j).getPlateWidTo(),
                            configList.get(j).getPlateLenFrom(), configList.get(j).getPlateLenTo());
                }
            }
        }
        // 3、产线号+热处理模式+默认热处理去向
        Set<String> mscLineNoSet = new HashSet<>();
        Set<String> heatTreatModeSet = new HashSet<>();
        Set<String> defaultDestSet = new HashSet<>();
        List<Long> idList = new ArrayList<>();
        for (PmHotConfig pmHotConfig : pmHotConfigList) {
            mscLineNoSet.add(pmHotConfig.getMscLineNo());
            heatTreatModeSet.add(pmHotConfig.getHeatTreatMode());
            defaultDestSet.add(pmHotConfig.getDefaultDest());
            if (pmHotConfig.getId() != null) {
                idList.add(pmHotConfig.getId());
            }
        }
        // 校验与数据库的是否重复
        List<PmHotConfig> existPmHotConfigList = pmHotConfigRepository.selectByCondition(Condition.builder(PmHotConfig.class)
                .andWhere(Sqls.custom().andEqualTo(PmHotConfig.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmHotConfig.FIELD_MSC_LINE_NO, mscLineNoSet))
                .andWhere(Sqls.custom().andIn(PmHotConfig.FIELD_DEFAULT_DEST, defaultDestSet))
                .andWhere(Sqls.custom().andIn(PmHotConfig.FIELD_HEAT_TREAT_MODE, heatTreatModeSet))
                .andWhere(Sqls.custom().andNotIn(PmHotConfig.FIELD_ID, idList, true)).build());
        if (CollectionUtils.isNotEmpty(existPmHotConfigList)) {
            Map<String, List<PmHotConfig>> existMap = existPmHotConfigList.stream().collect(Collectors.groupingBy(this::getConfigKey));
            for (PmHotConfig pmHotConfig : pmHotConfigList) {
                if (existMap.containsKey(getConfigKey(pmHotConfig))) {
                    List<PmHotConfig> hotConfigList = existMap.get(getConfigKey(pmHotConfig));
                    for (PmHotConfig hotConfig : hotConfigList) {
                        // 钢板厚度
                        boolean plateThickIntervalCheck = Utils.isIntersect(pmHotConfig.getPlateThickFrom(),
                                pmHotConfig.getPlateThickTo(), hotConfig.getPlateThickFrom(), hotConfig.getPlateThickTo());
                        if (!plateThickIntervalCheck) {
                            continue;
                        }

                        // 钢板宽度
                        boolean plateWidIntervalCheck = Utils.isIntersect(pmHotConfig.getPlateWidFrom(),
                                pmHotConfig.getPlateWidTo(), hotConfig.getPlateWidFrom(), hotConfig.getPlateWidTo());
                        if (!plateWidIntervalCheck) {
                            continue;
                        }

                        // 钢板长度
                        boolean plateLenIntervalCheck = Utils.isIntersect(pmHotConfig.getPlateLenFrom(),
                                pmHotConfig.getPlateLenTo(), hotConfig.getPlateLenFrom(),hotConfig.getPlateLenTo());
                        if (!plateLenIntervalCheck) {
                            continue;
                        }

                        throw new CommonException("pm.hot_config_002", hotConfig.getPlateThickFrom(), hotConfig.getPlateThickTo(),
                                hotConfig.getPlateWidFrom(), hotConfig.getPlateWidTo(),
                                hotConfig.getPlateLenFrom(), hotConfig.getPlateLenTo());
                    }
                }
            }

        }

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

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

            // 记录历史表
            for (PmHotConfig pmHotConfig : updateList) {
                PmHotConfigTra pmHotConfigTra = new PmHotConfigTra();
                BeanUtils.copyProperties(pmHotConfig, pmHotConfigTra);

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

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

            for (PmHotConfig pmHotConfig : insertList) {
                PmHotConfigTra pmHotConfigTra = new PmHotConfigTra();
                BeanUtils.copyProperties(pmHotConfig, pmHotConfigTra);

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

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


    public String getConfigKey(PmHotConfig pmHotConfig) {
        return pmHotConfig.getMscLineNo() + pmHotConfig.getHeatTreatMode();
    }

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

            // 记录历史表
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmHotConfigTra> insertPmHotConfigTraList = new ArrayList<>(pmHotConfigList.size());
            for (PmHotConfig pmHotConfig : pmHotConfigList) {
                PmHotConfigTra pmHotConfigTra = new PmHotConfigTra();

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

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

    private String getPmHotConfigKey(PmHotConfig pmHotConfig) {
        return pmHotConfig.getMscLineNo() + pmHotConfig.getHeatTreatMode();
    }
}

