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

import com.xisc.pm.api.dto.export.PmMoldSpecBtDTO;
import com.xisc.pm.app.service.PmMoldSpecBtService;
import com.xisc.pm.domain.entity.PmMoldSpecBt;
import com.xisc.pm.domain.entity.PmMoldSpecBtTra;
import com.xisc.pm.domain.repository.PmMoldSpecBtRepository;
import com.xisc.pm.domain.repository.PmMoldSpecBtTraRepository;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.util.BeanUtils;
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.math.BigDecimal;
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.function.Function;
import java.util.stream.Collectors;

/**
 * 结晶器规格基准表(PmMoldSpecBt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-07-22 14:11:31
 */
@Service
public class PmMoldSpecBtServiceImpl implements PmMoldSpecBtService {

    private PmMoldSpecBtRepository pmMoldSpecBtRepository;

    private PmMoldSpecBtTraRepository pmMoldSpecBtTraRepository;

    private LovAdapter lovAdapter;

    public PmMoldSpecBtServiceImpl(PmMoldSpecBtRepository pmMoldSpecBtRepository, PmMoldSpecBtTraRepository pmMoldSpecBtTraRepository,
                                   LovAdapter lovAdapter) {
        this.pmMoldSpecBtRepository = pmMoldSpecBtRepository;
        this.pmMoldSpecBtTraRepository = pmMoldSpecBtTraRepository;
        this.lovAdapter = lovAdapter;
    }

    @Override
    public Page<PmMoldSpecBt> selectList(PageRequest pageRequest, PmMoldSpecBt pmMoldSpecBt) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmMoldSpecBtRepository.selectList(pmMoldSpecBt));
    }

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

        // 校验新增更新的数据之间是否重复
        Map<String, List<PmMoldSpecBt>> pmMoldSpecBtMap = pmMoldSpecBtList.stream().collect(Collectors.groupingBy(pmMoldSpecBt ->
                pmMoldSpecBt.getCcType() + "-" + pmMoldSpecBt.getCastThick() + "-" + pmMoldSpecBt.getCastWidth() + "-"
                + pmMoldSpecBt.getMscLineNo()));
        for (Map.Entry<String, List<PmMoldSpecBt>> entry : pmMoldSpecBtMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                throw new CommonException("pm.mold_spec_bt_002", entry.getValue().get(0).getCcType(),
                        entry.getValue().get(0).getCastThick(), entry.getValue().get(0).getCastWidth(),
                        entry.getValue().get(0).getMscLineNo());
            }
        }

        // 获取字段集合，查询数据库该范围内数据
        List<String> ccTypeList = pmMoldSpecBtList.stream().map(PmMoldSpecBt::getCcType).distinct().collect(Collectors.toList());
        List<BigDecimal> castThickList = pmMoldSpecBtList.stream().map(PmMoldSpecBt::getCastThick).distinct().collect(Collectors.toList());
        List<BigDecimal> castWidthList = pmMoldSpecBtList.stream().map(PmMoldSpecBt::getCastWidth).distinct().collect(Collectors.toList());
        List<String> rollLineNoList = pmMoldSpecBtList.stream().map(PmMoldSpecBt::getMscLineNo).distinct().collect(Collectors.toList());
        List<Long> idList = pmMoldSpecBtList.stream().filter(item->item.getPmsbId() != null).map(PmMoldSpecBt::getPmsbId).collect(Collectors.toList());
        List<PmMoldSpecBt> existPmMoldSpecBtList = pmMoldSpecBtRepository.selectByCondition(Condition.builder(PmMoldSpecBt.class)
                .andWhere(Sqls.custom().andEqualTo(PmMoldSpecBt.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmMoldSpecBt.FIELD_CC_TYPE, ccTypeList))
                .andWhere(Sqls.custom().andIn(PmMoldSpecBt.FIELD_CAST_THICK, castThickList))
                .andWhere(Sqls.custom().andIn(PmMoldSpecBt.FIELD_CAST_WIDTH, castWidthList))
                .andWhere(Sqls.custom().andIn(PmMoldSpecBt.FIELD_MSC_LINE_NO, rollLineNoList))
                .andWhere(Sqls.custom().andNotIn(PmMoldSpecBt.FIELD_PMSB_ID, idList, true))
                .build());

        // 与数据库数据之间是否重复
        if (CollectionUtils.isNotEmpty(existPmMoldSpecBtList)) {
            // 根据四个字段校验唯一性
            Map<String, PmMoldSpecBt> existPmMoldSpecBtMap = existPmMoldSpecBtList.stream().collect(Collectors.toMap(pmMoldSpecBt -> pmMoldSpecBt.getCcType() + "-"
                    + pmMoldSpecBt.getCastThick() + "-" + pmMoldSpecBt.getCastWidth() + "-"
                    + pmMoldSpecBt.getMscLineNo(), Function.identity(), (v1, v2) -> v1));
            for (PmMoldSpecBt pmMoldSpecBt : pmMoldSpecBtList) {
                String key = pmMoldSpecBt.getCcType() + "-" + pmMoldSpecBt.getCastThick() + "-" + pmMoldSpecBt.getCastWidth() + "-"
                        + pmMoldSpecBt.getMscLineNo();
                if (existPmMoldSpecBtMap.containsKey(key)) {
                    throw new CommonException("pm.mold_spec_bt_001", pmMoldSpecBt.getCcType(),  pmMoldSpecBt.getCastThick(), pmMoldSpecBt.getCastWidth(), pmMoldSpecBt.getMscLineNo());
                }
            }
        }

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

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

        // 记录历史表
        for (PmMoldSpecBt pmMoldSpecBt : updateList) {
            PmMoldSpecBtTra pmMoldSpecBtTra = new PmMoldSpecBtTra();
            BeanUtils.copy(pmMoldSpecBt, pmMoldSpecBtTra);

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

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

        for (PmMoldSpecBt pmMoldSpecBt : insertList) {
            PmMoldSpecBtTra pmMoldSpecBtTra = new PmMoldSpecBtTra();
            BeanUtils.copy(pmMoldSpecBt, pmMoldSpecBtTra);

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

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

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

            // 获取时间和当前操作人信息
            Date now = new Date();
            String username = DetailsHelper.getUserDetails().getUsername();
            List<PmMoldSpecBtTra> insertPmMoldSpecBtTraList = new ArrayList<>(pmMoldSpecBtList.size());
            for (PmMoldSpecBt pmMoldSpecBt : pmMoldSpecBtList) {
                PmMoldSpecBtTra pmMoldSpecBtTra = new PmMoldSpecBtTra();

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

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

    }

    @Override
    public List<PmMoldSpecBtDTO> exportList(Long tenantId, PmMoldSpecBt pmMoldSpecBt) {
        List<PmMoldSpecBt> pmMoldSpecBtList = pmMoldSpecBtRepository.selectList(pmMoldSpecBt);
        // 如果集合为空，则返回
        if (CollectionUtils.isEmpty(pmMoldSpecBtList)) {
            return Collections.EMPTY_LIST;
        }
        List<PmMoldSpecBtDTO> resultList = new ArrayList<>();
        // 获取设计产线号值集含义
        List<LovValueDTO> mscLineNoList = lovAdapter.queryLovValue(Constants.LovCode.MSC_LINE_NO, tenantId);
        Map<String, String> mscLineNoLovMap = new HashMap<>(mscLineNoList.size());
        // 赋值
        // 赋值
        if (CollectionUtils.isNotEmpty(mscLineNoList)) {
            mscLineNoLovMap = mscLineNoList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }
        for (PmMoldSpecBt line : pmMoldSpecBtList) {
            PmMoldSpecBtDTO dto = new PmMoldSpecBtDTO();
            BeanUtils.copy(line, dto);
            dto.setMscLineNoDesc(mscLineNoLovMap.getOrDefault(line.getMscLineNo(), line.getMscLineNo()));
            resultList.add(dto);
        }
        return resultList;
    }
}

