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

import com.xisc.pm.app.service.PmSlabLenConfigService;
import com.xisc.pm.domain.entity.PmSlabLenConfig;
import com.xisc.pm.domain.entity.PmSlabLenConfigTra;
import com.xisc.pm.domain.repository.PmSlabLenConfigRepository;
import com.xisc.pm.domain.repository.PmSlabLenConfigTraRepository;
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.stream.Collectors;

/**
 * 板坯组矩长度配置表(PmSlabLenConfig)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-25 10:30:14
 */
@Service
public class PmSlabLenConfigServiceImpl implements PmSlabLenConfigService {

    private PmSlabLenConfigRepository pmSlabLenConfigRepository;

    private PmSlabLenConfigTraRepository pmSlabLenConfigTraRepository;

    public PmSlabLenConfigServiceImpl(PmSlabLenConfigRepository pmSlabLenConfigRepository, PmSlabLenConfigTraRepository pmSlabLenConfigTraRepository) {
        this.pmSlabLenConfigRepository = pmSlabLenConfigRepository;
        this.pmSlabLenConfigTraRepository = pmSlabLenConfigTraRepository;
    }

    @Override
    public Page<PmSlabLenConfig> selectList(PageRequest pageRequest, PmSlabLenConfig pmSlabLenConfig) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmSlabLenConfigRepository.selectList(pmSlabLenConfig));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, List<PmSlabLenConfig> pmSlabLenConfigList) {
        // 检查数据列表是否为空，如果为空则直接返回
        if (CollectionUtils.isEmpty(pmSlabLenConfigList)) {
            return;
        }
        // 校验数据是否有效
        StringBuilder message = new StringBuilder();
        // 新增记录之间校验区间是否交叉
        for (int i = 0; i < pmSlabLenConfigList.size() - 1; i++) {
            for (int j = i + 1; j < pmSlabLenConfigList.size(); j++) {
                // 校验板坯长度区间是否交叉
                boolean slabLenIntervalCheck = Utils.isIntersect(pmSlabLenConfigList.get(i).getSlabMinLen(), pmSlabLenConfigList.get(i).getSlabMaxLen(),
                        pmSlabLenConfigList.get(j).getSlabMinLen(), pmSlabLenConfigList.get(j).getSlabMaxLen());
                if (slabLenIntervalCheck) {
                    throw new CommonException("pm.slab_len_config_001", pmSlabLenConfigList.get(j).getSlabMinLen(), pmSlabLenConfigList.get(j).getSlabMaxLen());
                }
            }
        }
        // 与数据库记录校验区间是否交叉
        List<Long> idList = pmSlabLenConfigList.stream().filter(item -> item.getId() != null).map(PmSlabLenConfig::getId).collect(Collectors.toList());
        List<PmSlabLenConfig> existPmSlabLenConfigList = pmSlabLenConfigRepository.selectByCondition(Condition.builder(PmSlabLenConfig.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabLenConfig.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andNotIn(PmSlabLenConfig.FIELD_ID, idList, true))
                .build());
        if (CollectionUtils.isNotEmpty(existPmSlabLenConfigList)) {
            for (int i = 0; i < pmSlabLenConfigList.size(); i++) {
                for (int j = 0; j < existPmSlabLenConfigList.size(); j++) {
                    // 校验钢板厚度区间是否交叉
                    boolean slabLenIntervalCheck = Utils.isIntersect(pmSlabLenConfigList.get(i).getSlabMinLen(),
                            pmSlabLenConfigList.get(i).getSlabMaxLen(), existPmSlabLenConfigList.get(j).getSlabMinLen(),
                            existPmSlabLenConfigList.get(j).getSlabMaxLen());
                    if (slabLenIntervalCheck) {
                        throw new CommonException("pm.slab_len_config_001", existPmSlabLenConfigList.get(j).getSlabMinLen(), existPmSlabLenConfigList.get(j).getSlabMaxLen());
                    }
                }
            }
        }
        if (message.length() > 0) {
            message.deleteCharAt(message.length() - 1);
            throw new CommonException(message.toString());
        }

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

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

        // 记录历史表
        for (PmSlabLenConfig pmSlabLenConfig : updateList) {
            PmSlabLenConfigTra pmSlabLenConfigTra = new PmSlabLenConfigTra();
            BeanUtils.copyProperties(pmSlabLenConfig, pmSlabLenConfigTra);

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

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

        for (PmSlabLenConfig pmSlabLenConfig : insertList) {
            PmSlabLenConfigTra pmSlabLenConfigTra = new PmSlabLenConfigTra();
            BeanUtils.copyProperties(pmSlabLenConfig, pmSlabLenConfigTra);

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

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

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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmSlabLenConfigTra> insertPmSlabLenConfigTraList = new ArrayList<>(pmSlabLenConfigList.size());
            for (PmSlabLenConfig pmSlabLenConfig : pmSlabLenConfigList) {
                PmSlabLenConfigTra pmSlabLenConfigTra = new PmSlabLenConfigTra();

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

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

