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

import com.xisc.boot.common.feign.pojo.MtUserInfo;
import com.xisc.boot.common.sys.UserClient;
import com.xisc.pm.app.service.PmCdRuleSetService;
import com.xisc.pm.domain.entity.PmCdRuleItem;
import com.xisc.pm.domain.entity.PmCdRuleSet;
import com.xisc.pm.domain.repository.PmCdRuleItemRepository;
import com.xisc.pm.domain.repository.PmCdRuleSetRepository;
import io.choerodon.core.domain.Page;
import io.choerodon.mybatis.domain.AuditDomain;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.hzero.boot.platform.code.builder.CodeRuleBuilder;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 充当规则集(PmCdRuleSet)应用服务
 *
 * @author 蒋雨航 yuhang.jiang02@hand-china.com
 * @since 2024-08-16 10:57:16
 */
@Service
public class PmCdRuleSetServiceImpl implements PmCdRuleSetService {
    @Autowired
    private PmCdRuleSetRepository pmCdRuleSetRepository;

    @Autowired
    private PmCdRuleItemRepository pmCdRuleItemRepository;

    @Autowired
    private UserClient userClient;

    @Autowired
    private CodeRuleBuilder codeRuleBuilder;

    @Override
    public Page<PmCdRuleSet> selectList(PageRequest pageRequest, PmCdRuleSet pmCdRuleSet) {
        Page<PmCdRuleSet> page = PageHelper.doPageAndSort(pageRequest, () -> pmCdRuleSetRepository.selectList(pmCdRuleSet));
        page.getContent().sort(Comparator.comparing(PmCdRuleSet::getRuleSetType)
                .thenComparing(PmCdRuleSet::getRuleSeqNo));
        //获取所有规则号
        if (CollectionUtils.isNotEmpty(page.getContent())) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            List<Long> ruleNoList = page.getContent().stream().map(PmCdRuleSet::getRuleNo).collect(Collectors.toList());
            List<Long> userIdList = page.getContent().stream().map(AuditDomain::getCreatedBy).collect(Collectors.toList());
            List<Long> updateUserIdList = page.getContent().stream().map(AuditDomain::getLastUpdatedBy).collect(Collectors.toList());
            List<PmCdRuleItem> itemList = pmCdRuleItemRepository.selectByCondition(Condition.builder(PmCdRuleItem.class)
                    .andWhere(Sqls.custom()
                            .andEqualTo(PmCdRuleItem.FIELD_TENANT_ID, page.getContent().get(0).getTenantId())
                            .andIn(PmCdRuleItem.FIELD_RULE_NO, ruleNoList))
                    .build());
            Map<Long, PmCdRuleItem> map = itemList.stream().collect(Collectors.toMap(PmCdRuleItem::getRuleNo, Function.identity()));
            Map<Long, MtUserInfo> userInfoMap = userClient.userInfoBatchGet(page.getContent().get(0).getTenantId(), userIdList);
            Map<Long, MtUserInfo> updateUserInfoMap = userClient.userInfoBatchGet(page.getContent().get(0).getTenantId(), updateUserIdList);
            page.getContent().forEach(item -> {
                //规则描述
                PmCdRuleItem pmCdRuleItem = map.get(item.getRuleNo());
                if (Objects.nonNull(pmCdRuleItem)) {
                    item.setRuleDesc(pmCdRuleItem.getRuleDesc());
                }
                //记录创建责任者
                MtUserInfo mtUserInfo = userInfoMap.get(item.getCreatedBy());
                if (Objects.nonNull(mtUserInfo)) {
                    item.setRecCreator(mtUserInfo.getLoginName() + mtUserInfo.getRealName());
                }
                //记录创建时刻 格式年年年年月月日日时时分分秒秒
                item.setRecCreateTime(sdf.format(item.getCreationDate()));
                //记录修改责任者
                MtUserInfo updateUserInfo = updateUserInfoMap.get(item.getLastUpdatedBy());
                if (Objects.nonNull(updateUserInfo)) {
                    item.setRecRevisor(updateUserInfo.getLoginName() + updateUserInfo.getRealName());
                }
                //记录修改时刻 年年年年月月日日时时分分秒秒
                item.setRecReviseTime(sdf.format(item.getLastUpdateDate()));
            });
        }
        return page;
    }

    @Override
    public void saveData(List<PmCdRuleSet> pmCdRuleSets) {
        List<PmCdRuleSet> insertList = pmCdRuleSets.stream().filter(line -> line.getRuleSetId() == null).collect(Collectors.toList());
        List<PmCdRuleSet> updateList = pmCdRuleSets.stream().filter(line -> line.getRuleSetId() != null).collect(Collectors.toList());
        List<String> ruleSetTypeList = insertList.stream().map(PmCdRuleSet::getRuleSetType).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(insertList)) {
            //查询规则集类型对应的数据
            List<PmCdRuleSet> pmCdRuleSetList = pmCdRuleSetRepository.selectByCondition(Condition.builder(PmCdRuleSet.class)
                    .andWhere(Sqls.custom()
                            .andEqualTo(PmCdRuleSet.FIELD_TENANT_ID, insertList.get(0).getTenantId())
                            .andIn(PmCdRuleSet.FIELD_RULE_SET_TYPE, ruleSetTypeList))
                    .build());
            List<PmCdRuleSet> insertData = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(pmCdRuleSetList)) {
                Map<String, List<PmCdRuleSet>> map = pmCdRuleSetList.stream().collect(Collectors.groupingBy(PmCdRuleSet::getRuleSetType));
                Map<String, List<PmCdRuleSet>> insertMap = pmCdRuleSets.stream().collect(Collectors.groupingBy(PmCdRuleSet::getRuleSetType));
                for (Map.Entry<String, List<PmCdRuleSet>> entry : map.entrySet()) {
                    //规则集类型
                    String key = entry.getKey();
                    List<PmCdRuleSet> valueList = entry.getValue();
                    List<PmCdRuleSet> inserts = insertMap.get(key);
                    long size = valueList.size();
                    for (PmCdRuleSet insert : inserts) {
                        insert.setRuleSeqNo(size + 1);
                        size++;
                        //生效标记（0：不生效，1：生效）默认生效
                        insert.setValidFlag(1L);
                    }
                    insertData.addAll(inserts);
                }
            } else {
                //insertList按照规则集类型分组
                Map<String, List<PmCdRuleSet>> map = insertList.stream().collect(Collectors.groupingBy(PmCdRuleSet::getRuleSetType));
                for (Map.Entry<String, List<PmCdRuleSet>> entry : map.entrySet()) {
                    long i = 1;
                    List<PmCdRuleSet> valueList = entry.getValue();
                    for (PmCdRuleSet pmCdRuleSet : valueList) {
                        pmCdRuleSet.setRuleSeqNo(i);
                        //生效标记（0：不生效，1：生效）默认生效
                        pmCdRuleSet.setValidFlag(1L);
                        i++;
                    }
                    insertData.addAll(valueList);
                }
            }
            pmCdRuleSetRepository.batchInsert(insertData);
        }
        pmCdRuleSetRepository.batchUpdateByPrimaryKeySelective(updateList);
    }

    @Override
    public void remove(List<PmCdRuleSet> pmCdRuleSets, Long organizationId) {
        //获取的所有的id
        List<Long> ruleSetIdList = pmCdRuleSets.stream().map(PmCdRuleSet::getRuleSetId).collect(Collectors.toList());
        //查询所有的id对应的数据
        List<PmCdRuleSet> pmCdRuleSetList = pmCdRuleSetRepository.selectByCondition(Condition.builder(PmCdRuleSet.class)
                .andWhere(Sqls.custom()
                        .andEqualTo(PmCdRuleSet.FIELD_TENANT_ID, organizationId)
                        .andIn(PmCdRuleSet.FIELD_RULE_SET_ID, ruleSetIdList))
                .build());
        //过滤出当前删除数据的规则集类型
        List<String> typeList = pmCdRuleSetList.stream().map(PmCdRuleSet::getRuleSetType).distinct().collect(Collectors.toList());
        pmCdRuleSetRepository.batchDeleteByPrimaryKey(pmCdRuleSets);
        //删除后需对目前数据库中规则进行重新排序
        pmCdRuleSetList = pmCdRuleSetRepository.selectByCondition(Condition.builder(PmCdRuleSet.class).
                andWhere(Sqls.custom().andEqualTo(PmCdRuleSet.FIELD_TENANT_ID, organizationId)
                        .andIn(PmCdRuleSet.FIELD_RULE_SET_TYPE, typeList)).build());
        Map<String, List<PmCdRuleSet>> map = pmCdRuleSetList.stream().collect(Collectors.groupingBy(PmCdRuleSet::getRuleSetType));
        List<PmCdRuleSet> updateList = new ArrayList<>();
        for (Map.Entry<String, List<PmCdRuleSet>> entry : map.entrySet()) {
            List<PmCdRuleSet> valueList = entry.getValue();
            //valueList根据创建时间排序
            valueList.sort(Comparator.comparing(PmCdRuleSet::getCreationDate));
            for (int i = 0; i < valueList.size(); i++) {
                valueList.get(i).setRuleSeqNo((long) i + 1);
            }
            updateList.addAll(valueList);
        }
        pmCdRuleSetRepository.batchUpdateByPrimaryKey(updateList);
    }
}

