package cn.iocoder.yudao.module.system.service.worklog;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.dal.dataobject.worklog.LogUseDO;
import cn.iocoder.yudao.module.system.dal.mysql.worklog.LogUseMapper;
import cn.iocoder.yudao.module.system.service.worklog.dto.LogUseSaveReqDTO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.LOG_USE_NOT_EXISTS;

/**
 * 日志模板使用者 Service 实现类
 *
 * @author 符溶馨
 */
@Service
@Validated
public class LogUseServiceImpl implements LogUseService {

    @Resource
    private LogUseMapper logUseMapper;

    @Override
    public void createLogUse(List<LogUseSaveReqDTO> createReqVO) {
        // 插入
        List<LogUseDO> logUse = BeanUtils.toBean(createReqVO, LogUseDO.class);
        logUseMapper.insertBatch(logUse);
    }

    @Override
    public void updateLogUse(List<LogUseSaveReqDTO> updateReqVO,  Long formId) {
        // 校验存在
        validateLogUseExists(formId);
        List<LogUseDO> logUseDOS = BeanUtils.toBean(updateReqVO, LogUseDO.class);

        List<Long> oldLogUserS = convertList(logUseMapper.selectList(LogUseDO::getFormId, formId), LogUseDO::getUseUserId);
        List<Long> newLogUsers = convertList(updateReqVO, LogUseSaveReqDTO::getUseUserId);

        Collection<Long> createLogUses = CollUtil.subtract(newLogUsers, oldLogUserS);
        Collection<Long> deleteLogUses = CollUtil.subtract(oldLogUserS, newLogUsers);

        if (CollUtil.isNotEmpty(createLogUses)) {
            logUseMapper.insertBatch(logUseDOS.stream().filter(user -> createLogUses.contains(user.getUseUserId())).collect(Collectors.toList()));
        }
        if (CollUtil.isNotEmpty(deleteLogUses)) {
            logUseMapper.deleteByFormId(formId, deleteLogUses);
        }
    }

    private void validateLogUseExists(Long formId) {
        if (logUseMapper.selectCount(LogUseDO::getFormId, formId) == 0L) {
            throw exception(LOG_USE_NOT_EXISTS);
        }
    }

    @Override
    public List<Long> getDeptByFormId(Long formId) {

        return logUseMapper.getDeptByFormId(formId);
    }

    @Override
    public List<Long> getUserByFormId(Long formId) {

        List<LogUseDO> logUseDOS = logUseMapper.selectList(LogUseDO::getFormId, formId);
        return convertList(logUseDOS, LogUseDO::getUseUserId);
    }

    @Override
    public Long getCountByUser(Long formId, Long userId) {

        return logUseMapper.getCountByUser(formId, userId);
    }

    @Override
    public List<Long> getFormIdByUserId(Long userId) {

        List<LogUseDO> logUseDOS = logUseMapper.selectList(LogUseDO::getUseUserId, userId);
        return convertList(logUseDOS, LogUseDO::getFormId);
    }

    @Override
    public void deletByFormId(Long formId) {

        logUseMapper.delete(LogUseDO::getFormId, formId);
    }
}