package org.nl.system.service.dict.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
import org.nl.system.service.dict.ISysDictService;
import org.nl.system.service.dict.dao.Dict;
import org.nl.system.service.dict.dao.mapper.SysDictMapper;
import org.nl.system.service.dict.dto.DictQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 字典表 服务实现类
 * </p>
 *
 * @author generator
 * @since 2022-12-14
 */
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, Dict> implements ISysDictService {
    @Autowired
    private SysDictMapper sysDictMapper;

    @Override
    public IPage<Dict> queryAll(Map whereJson, PageQuery page) {
        String blurry = null;
        if (ObjectUtil.isNotEmpty(whereJson.get("blurry"))) blurry = whereJson.get("blurry").toString();
        IPage<Dict> pages = this.page(new Page<>(page.getPage() + 1, page.getSize()), new QueryWrapper<Dict>()
                .select("MAX(dict_id) AS dict_id, code, name")
                .lambda()
                .like(ObjectUtil.isNotEmpty(blurry), Dict::getCode, blurry)
                .or(ObjectUtil.isNotEmpty(blurry))
                .like(ObjectUtil.isNotEmpty(blurry), Dict::getName, blurry)
                        .orderBy(true, true, Dict::getCode)
                .groupBy(Dict::getCode, Dict::getName));
        return pages;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Dict dict) {
        String currentUserId = SecurityUtils.getCurrentUserId();
        String nickName = SecurityUtils.getCurrentNickName();
        String date = DateUtil.now();
        List<Dict> oldDict = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>()
                .eq(ObjectUtil.isNotEmpty(dict.getCode()), Dict::getCode, dict.getCode()));
        if (ObjectUtil.isNotEmpty(oldDict)) throw new BadRequestException("字典[" + dict.getCode() + "]已存在");
        dict.setDict_id(IdUtil.getSnowflake(1, 1).nextIdStr());
        dict.setCreate_id(currentUserId);
        dict.setCreate_name(nickName);
        dict.setCreate_time(date);
        dict.setUpdate_id(currentUserId);
        dict.setUpdate_name(nickName);
        dict.setUpdate_time(date);
        sysDictMapper.insert(dict);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDict(Dict dto) {
        Dict dict = sysDictMapper.selectById(dto.getDict_id());
        if (ObjectUtil.isEmpty(dict)) {
            throw new BadRequestException("字典不存在");
        }
        List<Dict> dictList = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, dto.getCode()));
        if (ObjectUtil.isNotEmpty(dictList) && !dto.getCode().equals(dict.getCode()))
            throw new BadRequestException("字典[" + dto.getCode() + "]已存在");
        String currentUserId = SecurityUtils.getCurrentUserId();
        String currentNickName = SecurityUtils.getCurrentNickName();
        // 根据code获取所有字典
        List<Dict> dicts = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, dict.getCode()));
        dicts.forEach(di -> {
            di.setCode(dto.getCode());
            di.setName(dto.getName());
            di.setUpdate_id(currentUserId);
            di.setUpdate_name(currentNickName);
            di.setUpdate_time(DateUtil.now());
            sysDictMapper.updateById(di);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchByIds(Set<String> ids) {
        // 查找code删除
        ids.forEach(id -> {
            String code = sysDictMapper.selectById(id).getCode();
            sysDictMapper.delete(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, code));
        });
    }

    @Override
    public IPage<Dict> queryAllDetail(DictQuery criteria, PageQuery page) {
        LambdaQueryWrapper<Dict> lam = new LambdaQueryWrapper<>();
        lam.eq(Dict::getCode, criteria.getCode())
                .isNotNull(Dict::getLabel)
                .ne(Dict::getLabel, "")
                .orderBy(true, true, Dict::getDict_sort);
        IPage<Dict> pages = new Page<>(page.getPage() + 1, page.getSize());
        sysDictMapper.selectPage(pages, lam);
        return pages;
    }

    @Override
    public List<Dict> getDictByName(String name) {
        List<Dict> dictList = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, name)
                .isNotNull(Dict::getLabel)
                .ne(Dict::getLabel, ""));
        return dictList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDetail(Dict dict) {
        // 校验是否已经有标签
        Dict one = sysDictMapper.selectOne(new LambdaQueryWrapper<Dict>().eq(Dict::getLabel, dict.getLabel())
                .eq(Dict::getCode, dict.getCode()));
        if (ObjectUtil.isNotEmpty(one)) throw new BadRequestException("标签[" + dict.getLabel() + "]已存在");
        // 判断是否有空的值
        List<Dict> selectOne = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, dict.getCode()));
        Dict dic = selectOne.get(0);
        if (ObjectUtil.isEmpty(dic.getLabel())) {
            // 空就赋值
            dic.setCode(dict.getCode());
            dic.setLabel(dict.getLabel());
            dic.setValue(dict.getValue());
            dic.setDict_sort(dict.getDict_sort());
            dic.setDict_type(dict.getDict_type());
            dic.setPara1(dict.getPara1());
            dic.setPara2(dict.getPara2());
            dic.setPara3(dict.getPara3());
            sysDictMapper.updateById(dic);
            return;
        }
        // 插入新的数据
        dict.setDict_id(IdUtil.getSnowflake(1, 1).nextIdStr());
        dict.setCode(dic.getCode());
        dict.setName(dic.getName());
        dict.setCreate_id(SecurityUtils.getCurrentUserId());
        dict.setCreate_name(SecurityUtils.getCurrentNickName());
        dict.setCreate_time(DateUtil.now());
        dict.setUpdate_id(SecurityUtils.getCurrentUserId());
        dict.setUpdate_name(SecurityUtils.getCurrentNickName());
        dict.setUpdate_time(DateUtil.now());
        sysDictMapper.insert(dict);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDetail(Dict resources) {
        Dict dict = sysDictMapper.selectById(resources.getDict_id());
        if (ObjectUtil.isEmpty(dict)) {
            throw new BadRequestException("被删除或无权限，操作失败!");
        }
        // 校验是否已经有标签
        List<Dict> dictList = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getLabel, resources.getLabel())
                .eq(Dict::getCode, resources.getCode()));
        if (ObjectUtil.isNotEmpty(dictList) && !resources.getLabel().equals(dict.getLabel())) {
            throw new BadRequestException("标签[" + resources.getLabel() + "]已存在");
        }
        resources.setUpdate_id(SecurityUtils.getCurrentUserId());
        resources.setUpdate_name(SecurityUtils.getCurrentNickName());
        resources.setUpdate_time(DateUtil.now());
        sysDictMapper.updateById(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDetail(String id) {
        sysDictMapper.deleteById(id);
    }

    @Override
    public List<Dict> queryAll() {
        return sysDictMapper.selectList(new QueryWrapper<Dict>()
                .select("MAX(dict_id) AS dictId, code, name")
                .lambda()
                .groupBy(Dict::getCode, Dict::getName));
    }

}
