package com.quantgroup.asset.distribution.service.user.impl;

import cn.quantgroup.motan.bean.UserAssociationBean;
import cn.quantgroup.motan.bean.UserInfo;
import cn.quantgroup.motan.retbean.XUserExtInfo;
import cn.quantgroup.motan.vo.UserSysResult;
import cn.quantgroup.user.IUserSdkService;
import cn.quantgroup.user.UserSdkServiceFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.model.entity.user.SDKUserInfo;
import com.quantgroup.asset.distribution.service.httpclient.IHttpService;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import com.quantgroup.asset.distribution.service.user.IUserCenterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author : Hyuk
 * @description : UserCenterServiceImpl
 * @date : 2020/6/27 2:05 上午
 */
@Slf4j
@Service
public class UserCenterServiceImpl implements IUserCenterService {

    @Value("${user.sdk.url}")
    private String userSysUrl;
    private IUserSdkService userSdkService;
    @Autowired
    @Qualifier("httpClient")
    private CloseableHttpClient httpClient;
    @Autowired
    private IRedisService<UserInfo> redisService;
    @Autowired
    private IRedisService<SDKUserInfo> sdkUserInfoRedisService;
    @Autowired
    private IHttpService httpService;


    /**
     * UserInfo redisKey前缀
     */
    private static final String USER_INFO_PRE_FIX = "ASSET_DISTRIBUTION:GET_USER_INFO_BY_UUID:MMNACH99:";

    /**
     * SDKUserInfo redisKey前缀
     */
    private static final String SDK_USER_INFO_PREFIX = "ASSET_DISTRIBUTION:GET_SDK_USER_INFO_BY_PHONE_NO:AMMVYY16:";

    @PostConstruct
    private void init() {
        userSdkService = UserSdkServiceFactory.generateSDKService(userSysUrl, httpClient);
    }

    @Override
    public UserInfo getUserInfoByUuid(String uuid) {
        final String cacheKey = getUserInfoCacheKey(uuid);
        UserInfo userInfo = redisService.getEntity(cacheKey);

        if (userInfo == null) {
            UserSysResult<UserInfo> result = userSdkService.findUserInfoByUuid(uuid);
            if (result.isSuccess() && result.getData() != null) {
                userInfo = result.getData();
                redisService.setEntityEx(cacheKey, userInfo, 5, TimeUnit.MINUTES);
            } else {
                log.info("用户中心根据uuid查询userInfo失败， uuid : {}, result : {}", uuid, result);
            }
        }
        return userInfo;
    }

    @Override
    public SDKUserInfo getSDKUserExtInfo(String phoneNo, String uuid) {
        final String cacheKey = getSdkUserInfoCacheKey(phoneNo);
        SDKUserInfo sdkUserInfo = sdkUserInfoRedisService.getEntity(cacheKey);
        if (sdkUserInfo == null) {
            sdkUserInfo = getSDKUserInfoFromUserCenter(phoneNo, uuid);
            if (sdkUserInfo != null) {
                sdkUserInfoRedisService.setEntityEx(cacheKey, sdkUserInfo, 5, TimeUnit.MINUTES);
            }
        }
        return sdkUserInfo;
    }

    @Override
    public UserAssociationBean getUserAssociationBean(String uuid) {
        UserSysResult<UserInfo> result = userSdkService.findUserInfoByUuid(uuid);
        UserInfo userInfo = new UserInfo();
        if (result.isSuccess() && result.getData() != null && result.getData().getId() == null) {
            userInfo = result.getData();
        } else {
            log.error("调用用户中心接口findUserInfoByUuid异常 {}",JSON.toJSONString(userInfo));
            throw new RuntimeException("调用用户中心接口findUserInfoByUuid异常");
        }
        UserSysResult<UserAssociationBean> association = userSdkService.findUserAssociationByUid(userInfo.getId().toString());
        if (association == null || !association.isSuccess() || association.getData() == null
                || CollectionUtils.isEmpty(association.getData().getContractResults())){
            log.error("调用用户中心接口findUserAssociationByUid异常 {}",JSON.toJSONString(association));
            throw new RuntimeException("调用用户中心接口findUserAssociationByUid异常");
        }
        return association.getData();
    }

    /**
     * 从用户中心获取SDKUserInfo
     * @param uuid
     * @param phoneNo
     * @return
     */
    private SDKUserInfo getSDKUserInfoFromUserCenter(String phoneNo, String uuid) {
        String url = userSysUrl + "/innerapi/user-association/search/userId";
        Map<String, String> params = new HashMap<>();
        params.put("phoneNo", phoneNo);

        String result = httpService.post(url, params);
        JSONObject data = JSON.parseObject(result);
        Boolean success = data.getBoolean("success");
        if (!(success != null && success.booleanValue() && "0000".equals(data.getString("code"))
                && "0000".equals(data.getString("businessCode")))) {
            log.info("用户中心根据phoneNo查询用户全量信息失败， uuid : {}, phone : {}, result : {}", uuid, phoneNo, result);
            return null;
        }

        SDKUserInfo sdkUserInfo = JSON.parseObject(data.getString("data"), SDKUserInfo.class);
        return sdkUserInfo;
    }

    /**
     * 获取UserInfo缓存key前缀
     * @param uuid
     * @return
     */
    private static final String getUserInfoCacheKey(String uuid) {
        return USER_INFO_PRE_FIX + uuid;
    }

    /**
     * 获取SDKUserInfo缓存key前缀
     * @param phoneNo
     * @return
     */
    private static final String getSdkUserInfoCacheKey(String phoneNo) {
        return SDK_USER_INFO_PREFIX + phoneNo;
    }

}
