package ink.wgink.service.role.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.UpdateException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.ZTreeDTO;
import ink.wgink.pojo.dtos.role.RoleDTO;
import ink.wgink.pojo.pos.RolePO;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.service.role.dao.IRoleDao;
import ink.wgink.service.role.pojo.vos.RoleVO;
import ink.wgink.service.role.service.IRoleService;
import ink.wgink.service.role.service.IRoleUserService;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.map.HashMapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: RoleServiceImpl
 * @Description: 角色
 * @Author: WangGeng
 * @Date: 2021/1/31 18:51
 * @Version: 1.0
 **/
@Service
public class RoleServiceImpl extends DefaultBaseService implements IRoleService {

    @Autowired
    private IRoleDao roleDao;
    @Autowired
    private IRoleUserService roleUserService;

    @Override
    public void save(RoleVO roleVO) throws SaveException, SearchException {
        Map<String, Object> params = HashMapUtil.beanToMap(roleVO);
        String parentCode = null;
        String roleParentId = roleVO.getRoleParentId();
        if (!StringUtils.equals(ISystemConstant.TREE_ROOT_ID, roleVO.getRoleParentId())) {
            params.put("roleId", roleParentId);
            RoleDTO roleDTO = roleDao.get(params);
            parentCode = roleDTO.getRoleCode();
        }
        String roleCode = getCode(parentCode, roleParentId);
        params.put("roleCode", roleCode);
        params.put("roleId", UUIDUtil.getUUID());
        setSaveInfo(params);
        roleDao.save(params);
    }

    @Override
    public void remove(List<String> ids) throws RemoveException {
        // 删除角色用户
        roleUserService.delete(ids);

        Map<String, Object> params = getHashMap(10);
        params.put("roleIds", ids);
        setUpdateInfo(params);
        roleDao.remove(params);
    }

    @Override
    public void update(String roleId, RoleVO roleVO) throws UpdateException {
        Map<String, Object> params = HashMapUtil.beanToMap(roleVO);
        params.put("roleId", roleId);
        setUpdateInfo(params);
        roleDao.update(params);
    }

    @Override
    public void updateRoleDataRight(String roleId, String roleDataRight) {
        Map<String, Object> params = getHashMap(4);
        params.put("roleId", roleId);
        params.put("roleDataRight", roleDataRight);
        setUpdateInfo(params);
        roleDao.update(params);
    }

    @Override
    public RoleDTO get(Map<String, Object> params) throws SearchException {
        return roleDao.get(params);
    }

    @Override
    public RoleDTO get(String roleId) {
        Map<String, Object> params = getHashMap(2);
        params.put("roleId", roleId);
        return get(params);
    }

    @Override
    public List<RoleDTO> list(Map<String, Object> params) {
        List<RoleDTO> srcRoleDTO = roleDao.list(params);
        List<RoleDTO> destRoleDTO = new ArrayList<>(Arrays.asList(new RoleDTO[srcRoleDTO.size()]));
        Collections.copy(destRoleDTO, srcRoleDTO);
        return destRoleDTO;
    }

    @Override
    public List<RoleDTO> listByRoleIds(List<String> roleIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("roleIds", roleIds);
        return list(params);
    }

    @Override
    public List<RolePO> listPO(Map<String, Object> params) {
        return roleDao.listPO(params);
    }

    @Override
    public List<RolePO> listPO(List<String> roleIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("roleIds", roleIds);
        return listPO(params);
    }

    @Override
    public List<RoleDTO> listAll(Map<String, Object> params) throws SearchException {
        List<RoleDTO> roleDTOs = roleDao.list(params);
        listSubRoles(roleDTOs, params);
        return roleDTOs;
    }

    @Override
    public List<ZTreeDTO> listZTree(Map<String, Object> params) throws SearchException {
        List<ZTreeDTO> zTreeDTOs = roleDao.listZTree(params);
        for (ZTreeDTO zTreeDTO : zTreeDTOs) {
            Integer subCount = roleDao.countByParentId(zTreeDTO.getId());
            setZTreeInfo(zTreeDTO, subCount);
        }
        return zTreeDTOs;
    }

    @Override
    public SuccessResultList<List<RoleDTO>> listPage(ListPage page) throws SearchException {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<RoleDTO> roleDTOs = list(page.getParams());
        PageInfo<RoleDTO> pageInfo = new PageInfo<>(roleDTOs);
        return new SuccessResultList<>(roleDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public Integer count(Map<String, Object> params) throws SearchException {
        Integer roleCount = roleDao.countRole(params);
        return roleCount == null ? 0 : roleCount;
    }

    /**
     * 递归查询子角色
     *
     * @param roleDTOs
     * @param params
     * @throws SearchException
     */
    private void listSubRoles(List<RoleDTO> roleDTOs, Map<String, Object> params) throws SearchException {
        for (RoleDTO roleDTO : roleDTOs) {
            params.put("roleParentId", roleDTO.getRoleId());
            List<RoleDTO> subRoleDTOs = roleDao.list(params);
            roleDTO.setSubRoles(subRoleDTOs);
            listSubRoles(subRoleDTOs, params);
        }
    }

    /**
     * 获取code
     *
     * @param parentCode
     * @param parentId
     * @return
     * @throws SearchException
     */
    private String getCode(String parentCode, String parentId) throws SearchException {
        RoleDTO roleDTO = roleDao.getLastByParentId(parentId);
        String code = roleDTO != null ? roleDTO.getRoleCode() : "0000";
        return super.getNewCode(code, parentCode);
    }

}
