
package com.tmerclub.cloud.common.security;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.tmerclub.cloud.api.auth.bo.UidInfoBO;

import com.tmerclub.cloud.common.cache.constant.OauthCacheNames;
import com.tmerclub.cloud.common.cache.util.RedisUtil;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.SysTypeEnum;

import java.util.Objects;

/**
 * @author tmerclub
 * @date 2020/7/16
 */
public class AuthUserContext {
    private static final ThreadLocal<UidInfoBO> UID_HOLDER = new TransmittableThreadLocal<>();

    /**
     * 获取用户登录信息
     *
     * 用户端（请求一次）：通过token获取uid，拆分得到 sysType、userId、accountUid（账号全局唯一id）
     * 其他端（请求一次）：通过token获取uid, 拆分得到 sysType、userId、accountUid（账号全局唯一id）、userName、tenantId、isAdmin、isPassShop
     *
     * 所以用户端的UidInfoBO中没有 bizUserId、 socialType 数据
     * 如果需要用到  bizUserId、 socialType这些数据, 请使用 TokenFeignClient.getLoginInfo() 方法
     * 设计思路：
     *     1.用户端除了支付的接口外,仅用到userId, userId可以在uid中拆解获得，没有必要再去redis中获取用户的数据
     *     2.由1可知，用户端每个接口能减少一次redis请求
     */
    public static UidInfoBO get() {
        return UID_HOLDER.get();
    }

    public static void set(String uid) {
        UID_HOLDER.set(getUidInfo(uid));
    }

    public static void clean() {
        if (UID_HOLDER.get() != null) {
            UID_HOLDER.remove();
        }
    }

    public static void set(UidInfoBO uidInfoBo) {
        UID_HOLDER.set(uidInfoBo);
    }

    /**
     * 获取系统类型
     * @return
     */
    public static Integer getSysType() {
        return get().getSysType();
    }

    /**
     * 获取系统内账号唯一id
     * @return
     */
    public static Long getAccountUid() {
        return get().getAccountUid();
    }

    /**
     * 获取userId(用户端)
     * @return
     */
    public static Long getUserId() {
        return get().getUserId();
    }

    /**
     * 获取商家端EmployeeId
     * @return
     */
    public static Long getEmployeeId() {
        return getUserId();
    }

    /**
     * 获取平台端系统用户id
     * @return
     */
    public static Long getSysUserId() {
        return getUserId();
    }

    /**
     * 获取店铺Id
     * @return
     */
    public static Long getShopId() {
        return get().getTenantId();
    }

    /**
     * 获取供应商id
     * @return
     */
    public static Long getSupplierId() {
        return get().getTenantId();
    }

    /**
     * 获取自提点Id
     * @return
     */
    public static Long getStationId() {
        return getUserId();
    }

    public static String getUid() {
        return getUid(get());
    }

    public static Integer getIsAdmin() {
        return get().getIsAdmin();
    }

    /**
     * 获取用户名称
     * @return
     */
    public static String getUserName() {
        String uid = getUid(get());
        UidInfoBO infoBO = JSONObject.parseObject(RedisUtil.get(OauthCacheNames.USER_INFO + uid), UidInfoBO.class);
        return infoBO.getUsername();
    }


    /**
     * 生成各系统唯一uid
     * @param uidInfoBo uid含有的信息
     * @return
     */
    public static String getUid(UidInfoBO uidInfoBo) {

        StringBuilder sb = new StringBuilder();
        // uidInfoArray[0]
        sb.append(uidInfoBo.getSysType())
                // uidInfoArray[1]
                .append(Constant.UNDERLINE).append(uidInfoBo.getAccountUid())
                     // uidInfoArray[2]
                    .append(Constant.UNDERLINE).append(uidInfoBo.getUserId());

        if (Objects.equals(uidInfoBo.getSysType(), SysTypeEnum.ORDINARY.value())) {
            return sb.toString();
        }
        // uidInfoArray[3]
        sb.append(Constant.UNDERLINE).append(uidInfoBo.getTenantId())
                // uidInfoArray[4]
                .append(Constant.UNDERLINE).append(uidInfoBo.getIsAdmin())
                // uidInfoArray[5]
                    .append(Constant.UNDERLINE).append(uidInfoBo.getIsPassShop());
        return sb.toString();
    }

    /**
     * 根据uid获取用户信息
     * @param uid
     * @return
     */
    public static UidInfoBO getUidInfo(String uid) {
        String[] uidInfoArray = uid.split(Constant.UNDERLINE);
        UidInfoBO uidInfoBO = new UidInfoBO(Integer.valueOf(uidInfoArray[0]), Long.parseLong(uidInfoArray[1]),Long.parseLong(uidInfoArray[2]));

        if (Objects.equals(uidInfoBO.getSysType(), SysTypeEnum.ORDINARY.value())) {
            return uidInfoBO;
        }
        Long tenantId = Long.valueOf(uidInfoArray[3]);
        // 未注册的商家端、供应商端从缓存获取最新数据
        if (tenantId == -1) {
            UidInfoBO infoBO = JSONObject.parseObject(RedisUtil.get(OauthCacheNames.USER_INFO + uid), UidInfoBO.class);
            return infoBO;
        }
        uidInfoBO.setTenantId(Long.valueOf(uidInfoArray[3]));
        uidInfoBO.setIsAdmin(Integer.valueOf(uidInfoArray[4]));
        uidInfoBO.setIsPassShop(Integer.valueOf(uidInfoArray[5]));
        return uidInfoBO;
    }

}
