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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.core.vo.CacheUserVO;
import com.sy.coinage.sys.req.AdminCopyRoleReq;
import com.sy.coinage.sys.service.IRoleMenuService;
import com.sy.coinage.sys.service.IUserRoleService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

import com.sy.coinage.sys.dao.RoleDao;
import com.sy.coinage.sys.model.*;
import com.sy.coinage.sys.req.RoleMenuAddReq;
import com.sy.coinage.sys.service.IRoleService;
import com.sy.coinage.sys.vo.PermissionVO;
import com.google.common.base.Joiner;

import com.sy.coinage.core.constants.Constants;
import com.sy.coinage.core.vo.OptVO;

/**
 * 角色ServiceImpl
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleDao, Role> implements IRoleService {

    @Autowired
    private IRoleMenuService roleMenuService;

    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public List<OptVO> opt(Integer tenantId) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getTenantId, tenantId);
        queryWrapper.eq(Role::getStatus, Constants.STATUS_USABLE);
        queryWrapper.orderByAsc(Role::getSorted);
        List<OptVO> resp = this.baseMapper.queryOptList(queryWrapper);
        return resp;
    }

    @Override
    public List<Integer> menuIds(Integer id) {
        List<Integer> resp = null;
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId, id);
        List<RoleMenu> list = this.roleMenuService.list(queryWrapper);
        resp = new ArrayList<>();
        if (null != list && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                resp.add(list.get(i).getMenuId());
            }
        }
        return resp;
    }

    @Override
    @Transactional
    public void addMenu(RoleMenuAddReq req) {
        LambdaUpdateWrapper<RoleMenu> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId, req.getRoleId());
        this.roleMenuService.remove(queryWrapper);
        for (int i = 0; i < req.getMenuIds().size(); i++) {
            RoleMenu model = new RoleMenu();
            model.setRoleId(req.getRoleId());
            model.setMenuId(req.getMenuIds().get(i).getId());
            if (req.getMenuIds().get(i).getPermission() != null
                    && req.getMenuIds().get(i).getPermission().size() > 0) {
                String s = Joiner.on(",").join(req.getMenuIds().get(i).getPermission());
                model.setPermission(s);
            }
            this.roleMenuService.save(model);
        }
    }

    @Override
    public List<PermissionVO> permission(Integer roleId) {
        // 查询非父级权限
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId).isNotNull("sys_role_menu.permission");
        List<PermissionVO> list = this.roleMenuService.queryPermissionList(queryWrapper);
        if (null != list && list.size() > 0) {
            for (int i = list.size() - 1; i >= 0; i--) {
                if (StringUtils.isNoneBlank(list.get(i).getPermission())) {
                    String[] str = list.get(i).getPermission().split(",");
                    List<String> s = new ArrayList<>(Arrays.asList(str));
                    list.get(i).setList(s);
                } else {
                    list.remove(i);
                }
            }
        }
        return list;
    }

    @Override
    public void deleteUser(Integer userId, Integer roleId) {
        LambdaUpdateWrapper<UserRole> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userId).eq(UserRole::getRoleId, roleId);
        this.userRoleService.remove(queryWrapper);
    }

    @Override
    @Transactional
    public void copy(AdminCopyRoleReq req, CacheUserVO user) {
        Role model = new Role();
        BeanUtils.copyProperties(req, model);
        model.setCreateBy(user.getRealName());
        model.setStatus(Constants.STATUS_USABLE);
        this.save(model);
        // 复制角色的权限
        if (req.getCopyPermission().intValue() == 1) {
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getRoleId, req.getRoleId());
            List<RoleMenu> list = this.roleMenuService.list(queryWrapper);
            if (null != list && list.size() > 0) {
                List<RoleMenu> addList = new ArrayList<>();
                for (int i = 0; i < list.size(); i++) {
                    RoleMenu vo = list.get(i);
                    vo.setId(null);
                    vo.setRoleId(model.getId());
                    addList.add(vo);
                }
                this.roleMenuService.saveBatch(addList);
            }
        }

    }

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

}
