package com.cpop.system.business.service.impl;

import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.system.business.bo.DictTypeBo;
import com.cpop.system.business.entity.DictData;
import com.cpop.system.business.service.DictDataService;
import com.cpop.system.business.vo.DictTypePageVo;
import com.cpop.system.framework.utils.DictUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.cpop.system.business.entity.DictType;
import com.cpop.system.business.mapper.DictTypeMapper;
import com.cpop.system.business.service.DictTypeService;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.cpop.system.business.entity.table.DictDataTableDef.DICT_DATA;
import static com.cpop.system.business.entity.table.DictTypeTableDef.DICT_TYPE;

/**
 * 系统-字典表 服务层实现。
 *
 * @author DB
 * @since 2023-12-01
 */
@Service("dictTypeService")
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {

    /**
     * 获取系统字典类型分页
     *
     * @param dictName 字典名
     * @return R<Page < DictTypePageVo>>
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public Page<DictTypePageVo> getDictTypePage(String dictName) {
        //获取分页参数
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        //获取当前登陆用户类型
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        return this.pageAs(Page.of(pageDomain.getPageNum(), pageDomain.getPageSize()),
                QueryWrapper.create().select(DICT_TYPE.ID,DICT_TYPE.STATUS, DICT_TYPE.DICT_NAME, DICT_TYPE.DICT_TYPE_, DICT_TYPE.UPDATE_TIME)
                        .where(DICT_TYPE.USER_TYPE.eq(loginUser.getUserType().toString()))
                        .and(DICT_TYPE.DICT_NAME.like(dictName)),
                DictTypePageVo.class);
    }

    /**
     * 查询系统类型是否存在
     *
     * @param bo 请求参数
     * @return boolean
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public Boolean checkDictTypeUnique(DictTypeBo bo) {
        String dictId = StringUtils.isNotBlank(bo.getId()) ? bo.getId() : "-1";
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        DictType dictType = this.getOne(QueryWrapper.create()
                .where(DICT_TYPE.DICT_TYPE_.eq(bo.getDictType()))
                .and(DICT_TYPE.USER_TYPE.eq(loginUser.getUserType().toString())));
        return dictType == null || StringUtils.equals(dictId, dictType.getId());
    }

    /**
     * 根据主键删除字典类型
     *
     * @param id 主键
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public void removeDataAndCache(String id) {
        //查询数据
        DictType dictType = this.getById(id);
        //查询字典数据
        if (SpringUtils.getBean(DictDataService.class).count(QueryWrapper.create().where(DICT_DATA.DICT_TYPE.eq(dictType.getDictType()))) > 0) {
            throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
        }
        this.removeById(id);
        //删除缓存
        DictUtils.removeDictCache(dictType.getDictType());
    }

    /**
     * 重置字典缓存数据
     */
    @Override
    public void resetDictCache() {
        clearDictCache();
        loadingDictCache();
    }

    /**
     * 清空字典缓存数据
     */
    @Override
    public void clearDictCache() {
        DictUtils.clearDictCache();
    }

    /**
     * 加载字典缓存
     *
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public void loadingDictCache() {
        DictData dictData = new DictData();
        dictData.setStatus(false);
        Map<String, List<DictData>> dictDataMap = SpringUtils.getBean(DictDataService.class)
                .list(QueryWrapper.create().orderBy(DICT_DATA.DICT_SORT.asc()))
                .stream().collect(Collectors.groupingBy(DictData::getDictType));
        for (Map.Entry<String, List<DictData>> entry : dictDataMap.entrySet()) {
            DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(DictData::getDictSort)).collect(Collectors.toList()));
        }
    }
}
