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

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xisc.pm.domain.entity.PmRetainSt;
import com.xisc.pm.domain.entity.PmRetainStack;
import com.xisc.pm.domain.repository.PmRetainStRepository;
import com.xisc.pm.domain.repository.PmRetainStackRepository;
import com.xisc.pm.infra.mapper.PmRetainStMapper;
import com.xisc.pm.infra.mapper.PmRetainStackMapper;
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;

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

    private final ObjectMapper objectMapper;

    private final PmRetainStackRepository pmRetainStackRepository;

    private final PmRetainStackMapper pmRetainStackMapper;



    public PmRetainStackImportImpl(ObjectMapper objectMapper, PmRetainStackRepository pmRetainStackRepository, PmRetainStackMapper pmRetainStackMapper) {
        this.objectMapper = objectMapper;
        this.pmRetainStackRepository = pmRetainStackRepository;
        this.pmRetainStackMapper = pmRetainStackMapper;
    }

    @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 = 0L;
        if (DetailsHelper.getUserDetails() != null && DetailsHelper.getUserDetails().getTenantId() != null) {
            tenantId = DetailsHelper.getUserDetails().getTenantId();
        }
        // 定义要插入的List
        List<PmRetainStack> list = new ArrayList<>(data.size());

        // 数据转对象
        for (String json : data) {
            try {
                PmRetainStack pmRetainStack = objectMapper.readValue(json, PmRetainStack.class);
                pmRetainStack.setTenantId(tenantId);
                list.add(pmRetainStack);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
            }
        }
        // 如果集合为空，则结束
        if (CollectionUtils.isEmpty(list)) {
            throw new CommonException("pm.import_data_is_empty_list");
        }

        // 提取传入数据的 stackNo 和 mainBacklogCode 组合并去重
        List<String> uniqueIncomingCombinationList = list.stream()
                .map(stack -> stack.getStackNo() + "_" + stack.getMainBacklogCode())
                .distinct()
                .collect(Collectors.toList());
        // 检查传入数据的唯一性
        if (uniqueIncomingCombinationList.size() < list.size()) {
            throw new CommonException("pm.retain_stack_001");
        }

        List<PmRetainStack> checkList = pmRetainStackMapper.checkList(uniqueIncomingCombinationList);

        Map<String, PmRetainStack> checkListMap = checkList.stream()
                .collect(Collectors.toMap(
                        stack -> stack.getStackNo() + "_" + stack.getMainBacklogCode(),
                        stack -> stack
                ));

        // 遍历list，根据组合字符串查找checkListMap中的id并赋值
        list.forEach(stack -> {
            String key = stack.getStackNo() + "_" + stack.getMainBacklogCode();
            if (checkListMap.containsKey(key)) {
                PmRetainStack existingStack = checkListMap.get(key);
                stack.setId(existingStack.getId());
                stack.setObjectVersionNumber(existingStack.getObjectVersionNumber());
            }
        });

        List<PmRetainStack> insertList = list.stream().filter(line -> line.getId() == null).collect(Collectors.toList());
        List<PmRetainStack> updateList = list.stream().filter(line -> line.getId() != null).collect(Collectors.toList());

        pmRetainStackRepository.batchInsertSelective(insertList);
        pmRetainStackRepository.batchUpdateByPrimaryKeySelective(updateList);
        return true;
    }
}
