package com.njcn.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.dto.SimpleTreeDTO;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.db.constant.DbConstant;
import com.njcn.system.enums.SystemResponseEnum;
import com.njcn.system.mapper.DictTypeMapper;
import com.njcn.system.pojo.param.DictTypeParam;
import com.njcn.system.pojo.po.DictType;
import com.njcn.system.pojo.vo.DictDataCache;
import com.njcn.system.service.IDictTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * @author hongawen
 * @since 2021-12-13
 */
@Service
@RequiredArgsConstructor
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements IDictTypeService {

    @Override
    public Page<DictType> listDictTypes(DictTypeParam.DictTypeQueryParam queryParam) {
        QueryWrapper<DictType> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(queryParam)) {
            //查询参数不为空，进行条件填充
            if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
                //字典类型表，仅提供名称、编码模糊查询
                queryWrapper
                        .and(param -> param.like("sys_dict_type.name", queryParam.getSearchValue())
                                .or().like("sys_dict_type.code", queryParam.getSearchValue())
                        );
            }
            //排序
            if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
                queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
            } else {
                //没有排序参数，默认根据sort字段排序，没有排序字段的，根据updateTime更新时间排序
                queryWrapper.orderBy(true, true, "sys_dict_type.sort");
            }
        }
        queryWrapper.ne("sys_dict_type.state", DataStateEnum.DELETED.getCode());
        return this.baseMapper.selectPage(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
    }

    @Override
    public boolean addDictType(DictTypeParam dictTypeParam) {
        checkDicTypeName(dictTypeParam, false);
        DictType dictType = new DictType();
        BeanUtil.copyProperties(dictTypeParam, dictType);
        //默认为正常状态
        dictType.setState(DataStateEnum.ENABLE.getCode());
        return this.save(dictType);
    }

    @Override
    public boolean updateDictType(DictTypeParam.DictTypeUpdateParam updateParam) {
        checkDicTypeName(updateParam, true);
        DictType dictType = new DictType();
        BeanUtil.copyProperties(updateParam, dictType);
        return this.updateById(dictType);
    }

    @Override
    public boolean deleteDictType(List<String> ids) {
        return this.lambdaUpdate()
                .set(DictType::getState, DataStateEnum.DELETED.getCode())
                .in(DictType::getId, ids)
                .update();
    }


    @Override
    public List<SimpleTreeDTO> dictDataCache() {
        List<DictDataCache> allDictData = this.baseMapper.dictDataCache();
        Map<Object, List<DictDataCache>> dictDataCacheMap = allDictData.stream()
                .collect(Collectors.groupingBy(DictDataCache::getTypeId));
        return dictDataCacheMap.keySet().stream().map(typeId -> {
            SimpleTreeDTO simpleTreeDTO = new SimpleTreeDTO();
            List<DictDataCache> dictDataCaches = dictDataCacheMap.get(typeId);
            List<SimpleDTO> simpleDTOList = dictDataCaches.stream().map(dictDataCache -> {
                simpleTreeDTO.setCode(dictDataCache.getTypeCode());
                simpleTreeDTO.setId(dictDataCache.getTypeId());
                simpleTreeDTO.setName(dictDataCache.getTypeName());
                SimpleDTO simpleDTO = new SimpleDTO();
                simpleDTO.setCode(dictDataCache.getCode());
                simpleDTO.setId(dictDataCache.getId());
                simpleDTO.setName(dictDataCache.getName());
                simpleDTO.setSort(dictDataCache.getSort());
                simpleDTO.setValue(dictDataCache.getValue());
                simpleDTO.setAlgoDescribe(dictDataCache.getAlgoDescribe());
                return simpleDTO;
            }).sorted(Comparator.comparing(SimpleDTO::getSort)).collect(Collectors.toList());
            simpleTreeDTO.setChildren(simpleDTOList);
            return simpleTreeDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public DictType getByName(String dicTypeName) {
        LambdaQueryWrapper<DictType> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DictType::getName, dicTypeName)
                .eq(DictType::getState, DataStateEnum.ENABLE.getCode());
        return this.baseMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public DictType addByName(String dicTypeName) {
        DictType dictType = new DictType();
        dictType.setName(dicTypeName);
        dictType.setCode(dicTypeName);
        dictType.setSort(0);
        dictType.setOpenDescribe(0);
        dictType.setOpenLevel(0);
        dictType.setState(DataStateEnum.ENABLE.getCode());
        this.save(dictType);
        return dictType;
    }



    /**
     * 校验参数，检查是否存在相同名称的字典类型
     */
    private void checkDicTypeName(DictTypeParam dictTypeParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<DictType> dictTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dictTypeLambdaQueryWrapper
                .eq(DictType::getName, dictTypeParam.getName())
                .eq(DictType::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (dictTypeParam instanceof DictTypeParam.DictTypeUpdateParam) {
                dictTypeLambdaQueryWrapper.ne(DictType::getId, ((DictTypeParam.DictTypeUpdateParam) dictTypeParam).getId());
            }
        }
        int countByAccount = this.count(dictTypeLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(SystemResponseEnum.DICT_TYPE_NAME_REPEAT);
        }
    }
}
