package ink.wgink.common.component;

import com.alibaba.fastjson.JSON;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.interfaces.manager.IAppManager;
import ink.wgink.pojo.app.AppToken;
import ink.wgink.pojo.app.AppTokenUser;
import ink.wgink.pojo.bos.LoginUser;
import ink.wgink.pojo.bos.RoleGrantedAuthorityBO;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.dtos.department.DepartmentSimpleDTO;
import ink.wgink.pojo.dtos.group.GroupSimpleDTO;
import ink.wgink.pojo.dtos.position.PositionSimpleDTO;
import ink.wgink.pojo.dtos.role.RoleSimpleDTO;
import ink.wgink.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @ClassName: SecurityCompontent
 * @Description: 权限工具
 * @Author: WangGeng
 * @Date: 2019/2/26 3:31 PM
 * @Version: 1.0
 **/
@Component
public class SecurityComponent {

    private static final Logger LOG = LoggerFactory.getLogger(SecurityComponent.class);

    /**
     * 获取当前用户
     *
     * @return
     */
    public UserInfoBO getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object user = authentication.getPrincipal();
        UserInfoBO userInfoBO = null;
        if (user instanceof LoginUser) {
            userInfoBO = new UserInfoBO();
            LoginUser loginUser = (LoginUser) user;
            userInfoBO.setUserId(loginUser.getUserId());
            userInfoBO.setUserUsername(loginUser.getUsername());
            userInfoBO.setUserName(loginUser.getUserName());
            userInfoBO.setUserPhone(loginUser.getUserPhone());
            userInfoBO.setUserAvatar(loginUser.getUserAvatar());
            userInfoBO.setUserEmail(loginUser.getUserEmail());
            userInfoBO.setDataRight(loginUser.getDataRight());
            userInfoBO.setDataUserIds(loginUser.getDataRightUserIds());
            userInfoBO.setRootDepartmentIds(loginUser.getBaseDepartmentIds());
            userInfoBO.setRoles(loginUser.getRoles());
            userInfoBO.setDepartments(loginUser.getDepartments());
            userInfoBO.setGroups(loginUser.getGroups());
            userInfoBO.setPositions(loginUser.getPositions());
            userInfoBO.setExpandData(loginUser.getExpandData());
        }
        if (user instanceof UserInfoBO) {
            userInfoBO = (UserInfoBO) user;
        }
        return userInfoBO;
    }

    /**
     * 角色ID列表
     *
     * @return
     */
    public List<String> listRoleIds() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Collection<? extends GrantedAuthority> grantedAuthorities = authentication.getAuthorities();
        List<String> roleIds = new ArrayList<>();
        for (GrantedAuthority grantedAuthority : grantedAuthorities) {
            RoleGrantedAuthorityBO roleGrantedAuthorityBO = (RoleGrantedAuthorityBO) grantedAuthority;
            roleIds.add(roleGrantedAuthorityBO.getRoleId());
        }
        return roleIds;
    }

    /**
     * 当前角色列表
     *
     * @return
     */
    public List<RoleSimpleDTO> listRole() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getRoles();
    }

    /**
     * 部门列表
     *
     * @return
     */
    public List<DepartmentSimpleDTO> listDepartment() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getDepartments();
    }

    /**
     * 组列表
     *
     * @return
     */
    public List<GroupSimpleDTO> listGroup() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getGroups();
    }

    /**
     * 职位列白
     *
     * @return
     */
    public List<PositionSimpleDTO> listPosition() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getPositions();
    }

    /**
     * 获取当前用户名
     *
     * @return
     */
    public String getCurrentUsername() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getUserUsername();
    }

    /**
     * 拓展数据
     *
     * @return
     */
    public Object getExpandData() {
        UserInfoBO userInfoBO = getCurrentUser();
        return userInfoBO.getExpandData();
    }

    /**
     * 拓展数据
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getExpandData(Class<T> clazz) {
        Object expandData = getExpandData();
        if (expandData == null) {
            return null;
        }
        return JSON.parseObject(JSON.toJSONString(expandData), clazz);
//        return (T) getExpandData();
    }

    /**
     * AppManager
     *
     * @return
     */
    public IAppManager getAppManager() throws ReflectUtil.ReflectException {
        return ReflectUtil.getSingleInstance("ink.wgink.app.AppTokenManager", IAppManager.class);
    }

    /**
     * AppToken 对象
     *
     * @param token
     * @return
     */
    public AppToken getAppToken(String token) throws ReflectUtil.ReflectException {
        IAppManager appManager = getAppManager();
        if (appManager == null) {
            return null;
        }
        return appManager.getToken(token);
    }

    /**
     * token 对应的 app 用户
     *
     * @param token
     * @return
     */
    public AppTokenUser getAppTokenUser(String token) throws ReflectUtil.ReflectException {
        AppToken appToken = getAppToken(token);
        if (appToken == null) {
            return null;
        }
        return appToken.getAppTokenUser();
    }

    /**
     * 是否是管理员
     *
     * @return
     */
    public boolean isAdmin() {
        return isAdmin(listRoleIds());
    }

    /**
     * 是否是管理员
     *
     * @param roleIds
     * @return
     */
    public boolean isAdmin(List<String> roleIds) {
        String username = getCurrentUsername();
        if (StringUtils.equals(username, ISystemConstant.ADMIN)) {
            return true;
        }
        if (roleIds == null || roleIds.isEmpty()) {
            return false;
        }
        for (String roleId : roleIds) {
            if (StringUtils.equals(roleId, ISystemConstant.ADMIN)) {
                return true;
            }
        }
        return false;
    }

}
