package com.sy.coinage.sys.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sy.coinage.core.constants.CacheKey;
import com.sy.coinage.core.constants.Constants;
import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.core.redis.RedisService;
import com.sy.coinage.core.util.TreeUtil;
import com.sy.coinage.core.util.TreeUtil.TreeNode;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sy.coinage.sys.dao.DeptDao;
import com.sy.coinage.sys.model.*;
import com.sy.coinage.sys.req.DeptListReq;
import com.sy.coinage.sys.service.IDeptService;
import com.sy.coinage.sys.vo.DeptListVO;
import com.sy.coinage.core.vo.OptVO;


/**
 * 部门ServiceImpl
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptDao, Dept> implements IDeptService {

    @Autowired
    private RedisService redisService;

    @Override
    public IPage<DeptListVO> pageList(DeptListReq req, Integer tenantId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq((null != tenantId && tenantId > 0), Dept::getTenantId, tenantId);
        queryWrapper.eq((null != req.getStatus() && req.getStatus() > 0), Dept::getStatus, req.getStatus());
        queryWrapper.like(StringUtils.isNotBlank(req.getName()), Dept::getName, req.getName());
        queryWrapper.orderByAsc(Dept::getSorted);
        Page<DeptListVO> page = new Page<>(req.getPage(), req.getRows());
        IPage<DeptListVO> resp = this.baseMapper.queryPageList(page, queryWrapper);
        return resp;
    }

    @Override
    public List<DeptListVO> treeList(Integer orgId, Integer tenantId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getTenantId, tenantId);
        queryWrapper.eq((orgId != null && orgId > 0), Dept::getOrgId, orgId);
        queryWrapper.orderByDesc(Dept::getSorted);
        List<DeptListVO> list = this.baseMapper.queryList(queryWrapper);
        Collection<? extends TreeNode<Integer>> resp = TreeUtil.buildTree(list, 0);
        return (List<DeptListVO>) resp;
    }

    @Override
    public List<OptVO> opt(Integer orgId, Integer tenantId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getTenantId, tenantId);
        queryWrapper.eq(Dept::getStatus, Constants.STATUS_USABLE);
        queryWrapper.eq((orgId != null && orgId > 0), Dept::getOrgId, orgId);
        queryWrapper.orderByDesc(Dept::getSorted);
        List<OptVO> resp = this.baseMapper.queryOptList(queryWrapper);
        return resp;
    }

    @Override
    public List<OptVO> treeOpt(Integer orgId, Integer tenantId) {
        List<OptVO> list = this.opt(orgId, tenantId);
        Collection<? extends TreeNode<Integer>> resp = TreeUtil.buildTree(list, 0);
        return (List<OptVO>) resp;
    }

    @Override
    public void validName(Integer id, String name, Integer tenantId) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dept::getTenantId, tenantId);
        queryWrapper.eq(Dept::getName, name);
        if (null != id) {
            queryWrapper.ne(Dept::getId, id);
        }
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new RetException(name + "已存在");
        }
    }

    @Override
    public Dept getByCode(Integer id) {
        Dept resp = null;
        String key = "dept_" + id;
        if (redisService.hasKey(key)) {
            String json = redisService.get(key);
            resp = JSON.parseObject(json, Dept.class);
        } else {
            LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Dept::getRemark, String.valueOf(id));
            resp = this.getOne(queryWrapper);
            if (resp != null) {
                this.redisService.set(key, JSON.toJSONString(resp));
                this.redisService.expire(key, CacheKey.EXPIRED_WEEK);
            }
        }
        return resp;
    }

}
