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

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xisc.pm.api.dto.PmSgDetermineImportDTO;
import com.xisc.pm.domain.entity.PmRetainSt;
import com.xisc.pm.domain.entity.PmSgDetermine;
import com.xisc.pm.domain.repository.PmRetainStRepository;
import com.xisc.pm.domain.repository.PmSgDetermineRepository;
import com.xisc.pm.infra.mapper.PmRetainStMapper;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.DetailsHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.hzero.boot.imported.app.service.IBatchImportService;
import org.hzero.boot.imported.infra.validator.annotation.ImportService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author BKGY
 * @since 2024年12月19日09:05:39
 */
@Slf4j
@ImportService(templateCode = "PM.SG_DETERMINE")
public class PmSgDetermineImportImpl implements IBatchImportService {

    private final ObjectMapper objectMapper;

    private final PmSgDetermineRepository pmSgDetermineRepository;




    public PmSgDetermineImportImpl(ObjectMapper objectMapper, PmSgDetermineRepository pmSgDetermineRepository) {
        this.objectMapper = objectMapper;
        this.pmSgDetermineRepository = pmSgDetermineRepository;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean doImport(List<String> data) {
        // 如果集合为空，则返回
        if (CollectionUtils.isEmpty(data)) {
            throw new CommonException("pm.import_data_is_empty_list");
        }
        // 获取租户id以及用户信息
        Long tenantId;
        if (DetailsHelper.getUserDetails() != null && DetailsHelper.getUserDetails().getTenantId() != null) {
            tenantId = DetailsHelper.getUserDetails().getTenantId();
        } else {
            tenantId = 0L;
        }
        // 定义获取数据的List
        List<PmSgDetermineImportDTO> listImportData = new ArrayList<>(data.size());
        List<PmSgDetermine> list = new ArrayList<>();
        // 数据转对象
        for (String json : data) {
            try {
                PmSgDetermineImportDTO pmSgDetermineImportDTO = objectMapper.readValue(json, PmSgDetermineImportDTO.class);
                listImportData.add(pmSgDetermineImportDTO);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
            }
        }
        // 如果集合为空，则结束
        if (CollectionUtils.isEmpty(listImportData)) {
            throw new CommonException("pm.import_data_is_empty_list");
        }

        //list 的 数据中有 stNo，linkupStNo，mscLineNo 和 alterableStNo1，alterableStNo2，alterableStNo3，alterableStNo4，alterableStNo5  后面的12345可能为空
        // 我需要将list 整理出一个有stNo，linkupStNo，mscLineNo 和 一个 alterableStNo 的新的 集合 List<PmSgDetermine> list1
        //假设 list 的数据为：[{stNo：123，linkupStNo：456，mscLineNo：789，alterableStNo1：111，alterableStNo2：""，alterableStNo3：""，alterableStNo4：""，alterableStNo5：555}]
        // 那么 list1 的数据为：[{stNo：123，linkupStNo：456，mscLineNo：789，alterableStNo：111},{stNo：123，linkupStNo：456，mscLineNo：789，alterableStNo：555}]
        for(int i = 0; i < listImportData.size(); i++){
            PmSgDetermine pmSgDetermine = new PmSgDetermine();
            pmSgDetermine.setStNo(listImportData.get(i).getStNo());
            if(listImportData.get(i).getLinkupStNo() == null){
                listImportData.get(i).setLinkupStNo("");
            }
            pmSgDetermine.setLinkupStNo(listImportData.get(i).getLinkupStNo());
            pmSgDetermine.setMscLineNo(listImportData.get(i).getMscLineNo());
            if(listImportData.get(i).getAlterableStNo1() != null && !listImportData.get(i).getAlterableStNo1().isEmpty()){
                pmSgDetermine.setAlterableStNo(listImportData.get(i).getAlterableStNo1());
                list.add(pmSgDetermine);
            }
            if(listImportData.get(i).getAlterableStNo2() != null && !listImportData.get(i).getAlterableStNo2().isEmpty()){
                pmSgDetermine.setAlterableStNo(listImportData.get(i).getAlterableStNo2());
                list.add(pmSgDetermine);
            }
            if(listImportData.get(i).getAlterableStNo3() != null && !listImportData.get(i).getAlterableStNo3().isEmpty()){
                pmSgDetermine.setAlterableStNo(listImportData.get(i).getAlterableStNo3());
                list.add(pmSgDetermine);
            }
            if(listImportData.get(i).getAlterableStNo4() != null && !listImportData.get(i).getAlterableStNo4().isEmpty()){
                pmSgDetermine.setAlterableStNo(listImportData.get(i).getAlterableStNo4());
                list.add(pmSgDetermine);
            }
            if(listImportData.get(i).getAlterableStNo5() != null && !listImportData.get(i).getAlterableStNo5().isEmpty()){
                pmSgDetermine.setAlterableStNo(listImportData.get(i).getAlterableStNo5());
                list.add(pmSgDetermine);
            }  
        }


        // 提取传入数据的 stNo并去重
        List<String> uniqueIncomingCombinationList = list.stream()
                .map(stack -> stack.getStNo() + "-" + stack.getLinkupStNo() + "-" + stack.getAlterableStNo() + "-" + stack.getMscLineNo())
                .distinct()
                .collect(Collectors.toList());

        List<String> checkList = pmSgDetermineRepository.checkList(uniqueIncomingCombinationList);

        // 找出 uniqueIncomingCombinationList 中存在但在 checkList 中不存在的元素
        List<String> differenceList = uniqueIncomingCombinationList.stream()
                .filter(item -> !checkList.contains(item))
                .collect(Collectors.toList());

        List<PmSgDetermine> insertList = differenceList.stream()
                .map(combination -> {
                    String[] split = combination.split("-");
                    PmSgDetermine pmSgDetermine = new PmSgDetermine();
                    pmSgDetermine.setIsFlag("0");
                    pmSgDetermine.setTenantId(tenantId);
                    pmSgDetermine.setStNo(split[0]);
                    pmSgDetermine.setLinkupStNo(split[1]);
                    pmSgDetermine.setAlterableStNo(split[2]);
                    pmSgDetermine.setMscLineNo(split[3]);
                    return pmSgDetermine;
                })
                .collect(Collectors.toList());
        pmSgDetermineRepository.batchInsertSelective(insertList);

        return true;
    }
}
