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

import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.PageDomain;
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.DictDataBo;
import com.cpop.system.business.bo.DictDataPageBo;
import com.cpop.system.business.vo.DictDataListVo;
import com.cpop.system.business.vo.DictDataPageVo;
import com.cpop.system.business.vo.DictDataVo;
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.DictData;
import com.cpop.system.business.mapper.DictDataMapper;
import com.cpop.system.business.service.DictDataService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

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

/**
 * 系统-字典数据表 服务层实现。
 *
 * @author DB
 * @since 2023-12-01
 */
@Service("dictDataService")
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements DictDataService {

    /**
     * 获取字典数据分页
     *
     * @param bo 请求参数
     * @return Page<DictDataPageVo>
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public Page<DictDataPageVo> getDictDataPage(DictDataPageBo bo) {
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        return this.pageAs(Page.of(pageDomain.getPageNum(), pageDomain.getPageSize()),
                QueryWrapper.create()
                        .select(DICT_DATA.ID, DICT_DATA.DICT_LABEL, DICT_DATA.DICT_VALUE, DICT_DATA.DICT_TYPE, DICT_DATA.UPDATE_TIME,DICT_DATA.STATUS,DICT_DATA.DICT_SORT)
                        .where(DICT_DATA.USER_TYPE.eq(loginUser.getUserType().toString()))
                        .and(DICT_DATA.DICT_TYPE.eq(bo.getDictType()))
                        .and(DICT_DATA.DICT_LABEL.like(bo.getDictLabel()))
                        .and(DICT_DATA.STATUS.eq(bo.getStatus()))
                        .orderBy(DICT_DATA.DICT_SORT.asc()),
                DictDataPageVo.class);
    }

    /**
     * 根据主键获取字典数据详情
     *
     * @param id 主键
     * @return DictDataVo
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public DictDataVo getDictDataInfo(String id) {
        return BeanUtils.mapToClass(this.getById(id), DictDataVo.class);
    }

    /**
     * 根据字典类型获取字典数据
     *
     * @param dictType 字典类型
     * @return List<DictDataVo>
     * @author DB
     * @since 2023/12/01
     */
    @Override
    public List<DictData> getDictDataByDictType(String dictType) {
        List<DictData> dictCache = DictUtils.getDictCache(dictType);
        if (dictCache != null && !dictCache.isEmpty()) {
            return dictCache;
        }
        //获取当前用户信息
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        dictCache = this.list(QueryWrapper.create().select(DICT_DATA.ALL_COLUMNS)
                .where(DICT_DATA.STATUS.eq(1))
                .and(DICT_DATA.DICT_TYPE.eq(dictType))
                .and(DICT_DATA.USER_TYPE.eq(loginUser.getUserType().toString()))
                .orderBy(DICT_DATA.DICT_SORT.asc()));
        if (StringUtils.isNotEmpty(dictCache)) {
            DictUtils.setDictCache(dictType, dictCache);
            return dictCache;
        }
        return new ArrayList<>();
    }

    /**
     * 新增字典数据
     * @author DB
     * @since 2023/12/01
     * @param bo 请求参数
     */
    @Override
    public void insertDictData(DictDataBo bo) {
        DictData dictData = BeanUtils.mapToClass(bo, DictData.class);
        LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
        dictData.setUserType(loginUser.getUserType().toString());
        boolean save = this.save(dictData);
        if (save) {
            List<DictData> dictDatas = getDictDataByDictType(dictData.getDictType());
            //判断新增的数据是否在缓存中
            if (!dictDatas.stream().map(DictData::getId).collect(Collectors.toSet()).contains(dictData.getId())) {
                dictDatas.add(dictData);
            }
            //排序
            DictUtils.setDictCache(dictData.getDictType(), dictDatas);
        }
    }

    /**
     * 修改字典数据
     * @author DB
     * @since 2023/12/01
     * @param bo 请求
     */
    @Override
    public void updateDictData(DictDataBo bo) {
        DictData dictData = BeanUtils.mapToClass(bo, DictData.class);
        boolean save = this.updateById(dictData);
        if (save) {
            List<DictData> dictDatas = getDictDataByDictType(dictData.getDictType());
            //判断新增的数据是否在缓存中
            List<DictData> filterList = dictDatas.stream().filter(item -> !StringUtils.equals(item.getId(), dictData.getId())).collect(Collectors.toList());
            filterList.add(getById(dictData.getId()));
            //排序
            DictUtils.setDictCache(dictData.getDictType(), filterList);
        }
    }

    /**
     * 删除字典数据
     * @author DB
     * @since 2023/12/01
     * @param id 主键
     */
    @Override
    public void removeDictData(String id) {
        DictDataVo data = getDictDataInfo(id);
        this.removeById(id);
        List<DictData> dictDatas = getDictDataByDictType(data.getDictType());
        DictUtils.setDictCache(data.getDictType(), dictDatas);
    }
}
