package com.persagy.dmp.message.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrFormatter;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.persagy.dmp.common.constant.ValidEnum;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.message.dao.MessageTypeMapper;
import com.persagy.dmp.message.model.vo.MessageType;
import com.persagy.dmp.message.service.IMessageTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 消息类型 服务实现
 * @author linhuili
 * @date 2021-09-26
 */
@Service
@Transactional
public class MessageTypeServiceImpl extends ServiceImpl<MessageTypeMapper, MessageType> implements IMessageTypeService {

    @Autowired
    private MessageTypeMapper dao;

    /**
     * 分页查询消息类型
     * @param page 分页条件
     * @param queryWrapper 查询条件
     * @return
     */
    @Override
    public Page queryByCondition(Page page, Wrapper<MessageType> queryWrapper) {
        return dao.selectPage(page, queryWrapper);
    }

    /**
     * 新增消息类型
     * @param voList
     * @return
     */
    @Override
    public List<MessageType> insertMessageType(List<MessageType> voList) {
        //消息类型编码校验
        validateOnSave(voList,false);
        //批量保存消息类型
        saveBatch(voList);
        return voList;
    }

    /**
     * 修改消息类型
     * @param voList
     * @return
     */
    @Override
    public List<MessageType> updateMessageType(List<MessageType> voList) {
        //消息类型编码校验
        validateOnSave(voList,true);
        //批量保存消息类型
        saveOrUpdateBatch(voList);
        return voList;
    }

    /**
     * 删除消息类型
     * @param ids
     */
    @Override
    public void deleteMessageType(List<String> ids) {
        List<MessageType> voList = load(ids);
        if(CollUtil.isEmpty(voList)){
            throw new BusinessException("消息类型不存在");
        }
        //数据置为无效状态
        voList.forEach(item->item.setValid(ValidEnum.FALSE.getType()));
        saveOrUpdateBatch(voList);
    }

    /**
     * 根据id查询消息类型
     * * @param id
     * @return
     */
    @Override
    public MessageType load(String id) {
        return getById(id);
    }

    /**
     * 根据id批量查询消息类型
     * @param ids
     * @return
     */
    public List<MessageType> load(List<String> ids) {
       return dao.selectBatchIds(ids);
    }

    /**
     * 保存校验
     * 编码全局唯一
     * @param voList
     * @param isUpdate
     */
    private void validateOnSave(List<MessageType> voList, Boolean isUpdate) {
        Set<String> codeSet = new HashSet<>();
        List<String> idList = new ArrayList<>();
        for(MessageType vo:voList) {
            // 编码重复
            if(!codeSet.add(vo.getTypeCode())) {
                throw new BusinessException(StrFormatter.format("存在重复编码{}，不允许保存！", vo.getTypeCode()));
            }
            if(isUpdate) {
                idList.add(vo.getId());
            }
            // 补充valid值
            if (null==vo.getValid()){
                vo.setValid(ValidEnum.TRUE.getType());
            }
        }
        // 查询条件
        LambdaQueryWrapper<MessageType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(MessageType::getTypeCode);
        queryWrapper.in(MessageType::getValid, ValidEnum.TRUE.getType());
        queryWrapper.in(MessageType::getTypeCode, codeSet);
        if(isUpdate) {
            queryWrapper.notIn(MessageType::getId, idList);
        }
        // 查询重复的编码
        List<MessageType> dbList = dao.selectList(queryWrapper);
        if(CollUtil.isEmpty(dbList)) {
            return;
        }
        List<String> codes = CollUtil.getFieldValues(voList, "typeCode", String.class);
        throw new BusinessException(StrFormatter.format("存在重复编码{}，不允许保存！", codes));
    }

}
