package com.ruoyi.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.solon.service.impl.ServiceImpl;
import com.ruoyi.common.constants.CacheConstant;
import com.ruoyi.common.enums.DictEnum;
import com.ruoyi.common.utils.RedisUtil;
import com.ruoyi.common.web.exception.ServiceException;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.system.mapper.SysDictTypeMapper;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据字典类型 服务层实现
 * @author ruoyi
 */
@Component
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {

    @Inject
    SysDictTypeMapper sysDictTypeMapper;

    @Inject
    ISysDictDataService sysDictDataService;

    @Inject
    RedisUtil redisUtil;

    /**
     * 新增数据字典类型
     * @param sysDictType
     * @return
     */
    @Override
    public int add(SysDictType sysDictType) {
        if (!checkDictTypeUnique(sysDictType)) {
            throw new ServiceException("字典类型已存在");
        }
        int row = sysDictTypeMapper.insert(sysDictType);
        if (row > 0 && DictEnum.COMMON_STATUS.OK.getValue().equals(sysDictType.getStatus())) {
            String cacheKey = getCacheKey(sysDictType.getDictType());
            redisUtil.deleteCacheList(cacheKey);
            redisUtil.setCacheList(cacheKey, new ArrayList<>());  // 空集合并不会产生缓存键值对
        }
        return row;
    }

    /**
     * 修改数据字典类型
     * @param sysDictType
     * @return
     */
    @Override
    public int edit(SysDictType sysDictType) {
        if (!checkDictTypeUnique(sysDictType)) {
            throw new ServiceException("字典类型已存在");
        }
        SysDictType oldDict = sysDictTypeMapper.selectOneById(sysDictType.getDictId());
        boolean b = DictEnum.COMMON_STATUS.OK.getValue().equals(sysDictType.getStatus());
        if(!oldDict.getDictType().equals(sysDictType.getDictType())) {
            sysDictDataService.updateDictDataType(oldDict.getDictType(), sysDictType.getDictType(), b);
            redisUtil.deleteCacheList(getCacheKey(oldDict.getDictType()));
        } else {
            redisUtil.deleteCacheList(getCacheKey(sysDictType.getDictType()));
            if(b) {
                sysDictDataService.cacheDictDataType(sysDictType.getDictType());
            }
        }
        return sysDictTypeMapper.update(sysDictType);
    }

    /**
     * 删除数据字典类型
     * @param dictIds
     * @return
     */
    @Override
    public void delete(List<Long> dictIds) {
        List<SysDictType> sysDictTypes = sysDictTypeMapper.selectListByIds(dictIds);
        for (SysDictType sysDictType : sysDictTypes) {
            if(sysDictDataService.countDictDataByType(sysDictType.getDictType()) > 0) {
                throw new ServiceException("字典已分配,不能删除");
            }
            sysDictTypeMapper.deleteById(sysDictType.getDictId());
            redisUtil.deleteCacheList(getCacheKey(sysDictType.getDictType()));
        }
    }

    /**
     * 校验字典类型是否唯一
     * @param sysDictType
     * @return
     */
    private boolean checkDictTypeUnique(SysDictType sysDictType) {
        long dictId = sysDictType.getDictId() == null ? -1L : sysDictType.getDictId();
        QueryWrapper qw = QueryWrapper.create();
        qw.and(SysDictType::getDictType).eq(sysDictType.getDictType());
        qw.limit(1);
        SysDictType sdt = sysDictTypeMapper.selectOneByQuery(qw);
        return ObjectUtil.isNull(sdt) || sdt.getDictId() == dictId;
    }

    private String getCacheKey(String key) {
        return CacheConstant.SYS_DICT_KEY + key;
    }

}
