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.PmIrsubableSlab;
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.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.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
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_ST")
public class PmRetainStImportImpl implements IBatchImportService {

    private final ObjectMapper objectMapper;

    private final PmRetainStRepository pmRetainStRepository;

    private final PmRetainStMapper pmRetainStMapper;



    public PmRetainStImportImpl(ObjectMapper objectMapper, PmRetainStRepository pmRetainStRepository, PmRetainStMapper pmRetainStMapper) {
        this.objectMapper = objectMapper;
        this.pmRetainStRepository = pmRetainStRepository;
        this.pmRetainStMapper = pmRetainStMapper;
    }

    @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<PmRetainSt> list = new ArrayList<>(data.size());

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

        // 提取传入数据的 stNo并去重
        List<String> uniqueIncomingCombinationList = list.stream()
                .map(stack -> stack.getStNo())
                .distinct()
                .collect(Collectors.toList());
        // 检查传入数据的唯一性
        if (uniqueIncomingCombinationList.size() < list.size()) {
            throw new CommonException("pm.retain_st_001");
        }

        List<PmRetainSt> checkList = pmRetainStMapper.checkList(uniqueIncomingCombinationList);

        Map<String, PmRetainSt> checkListMap = checkList.stream()
                .collect(Collectors.toMap(
                        st -> st.getStNo(),
                        st -> st
                ));

        // 遍历list，根据组合字符串查找checkListMap中的id并赋值
        list.forEach(st -> {
            String key = st.getStNo();
            if (checkListMap.containsKey(key)) {
                PmRetainSt existingSt = checkListMap.get(key);
                st.setId(existingSt.getId());
                st.setObjectVersionNumber(existingSt.getObjectVersionNumber());
            }
        });

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

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