package com.liquidnet.service.order.utils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.IdentityUtils;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.AdamUserInfoVo;
import com.liquidnet.service.adam.dto.vo.AdamUserMemberVo;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.feign.adam.api.FeignAdamBaseClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Slf4j
@Component
public class AdamRedisUtils {
    @Autowired
    public RedisUtil redisUtil;
    @Autowired
    @Lazy
    private FeignAdamBaseClient feignAdamBaseClient;

    public AdamUserInfoVo getUserInfoVoByUid(String uid) {
        String rk = AdamRedisConst.INFO_USER.concat(uid);
        long s = System.currentTimeMillis();
        AdamUserInfoVo vo = (AdamUserInfoVo) redisUtil.get(rk);
        if (null == vo) {
            log.info("not find value in redis cache, key: {}", rk);
            try {
                ResponseDto<AdamUserInfoVo> responseDto = feignAdamBaseClient.getAdamUserInfoByUid(uid);
                log.info("feign client response: {}", JSON.toJSONString(responseDto));
                if (null != responseDto && responseDto.isSuccess() && null != responseDto.getData()) {
                    log.info("feign client response success");
                    vo = responseDto.getData();
                }
            }catch (Exception e) {
                log.error("error", e);
            }
        }
        log.debug("#RDM耗时:{}ms", System.currentTimeMillis() - s);
        return vo;
    }

    public AdamUserMemberVo getUserMemberVoByUid(String uid) {
        String rk = AdamRedisConst.INFO_USER_MEMBER.concat(uid);
        long s = System.currentTimeMillis();
        AdamUserMemberVo vo = (AdamUserMemberVo) redisUtil.get(rk);
        if (null != vo) {
            vo.setState(vo.getState() == 1 ? (vo.getExpiryAt().isAfter(LocalDateTime.now()) ? 1 : 2) : vo.getState());
        }
        log.debug("#RDM耗时:{}ms", System.currentTimeMillis() - s);
        return vo;
    }


    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 认证失败的<ID_TYPE+ID_NO, ID_NAME> */

    private boolean setCertificationJunk(int idType, String idNo, String idName) {
        return redisUtil.set(AdamRedisConst.INFO_CERTIFICATION_JUNK + idType + idNo, idName, 604800);
    }

    private boolean isCertificationJunk(int idType, String idNo, String idName) {
        String o = (String) redisUtil.get(AdamRedisConst.INFO_CERTIFICATION_JUNK + idType + idNo);
        return !StringUtils.isEmpty(o) && o.equals(idName);
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 认证成功的<ID_TYPE+ID_NO, ID_NAME> */

    /**
     * 目前只针对身份证类型三方服务认证成功的标记
     *
     * @param idType
     * @param idNo
     * @param idName
     * @return
     */
    private boolean setCertification(int idType, String idNo, String idName) {
        return redisUtil.set(AdamRedisConst.INFO_CERTIFICATION + idType + idNo, idName);
    }

    /**
     * 目前只针对身份证类型三方服务认证成功的标记
     *
     * @param idType
     * @param idNo
     * @param idName
     * @return
     */
    private int isCertification(int idType, String idNo, String idName) {
        String o = (String) redisUtil.get(AdamRedisConst.INFO_CERTIFICATION + idType + idNo);
        if (StringUtils.isEmpty(o)) {
            return -1;
        }
        return o.equals(idName) ? 1 : 0;
//        return !StringUtils.isEmpty(o) && o.equals(idName);
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 认证处理 */

    /**
     * 身份证实名处理
     *
     * @param uid
     * @param name
     * @param idCard
     */
    public void identityHandler1(String uid, String name, String idCard) {
        int rst = this.isCertification(1, idCard, name);
        switch (rst) {
            case -1:// 本地不存在
                if (this.isCertificationJunk(1, idCard, name)) {
                    throw new LiquidnetServiceException("-1", "身份证号与姓名不符");
                }

                String respStr = IdentityUtils.aliThird(name, idCard), respErrorCode = null;
                JsonNode respJNode = JsonUtils.fromJson(respStr, JsonNode.class);
                if (null == respJNode || !"0".equals(respErrorCode = String.valueOf(respJNode.get("error_code")))) {
                    log.info("###实名认证失败[{}]", respStr);

//                    this.setCertificationJunk(1, idCard, name);
                    if (!StringUtils.isEmpty(respErrorCode) && org.apache.commons.lang3.StringUtils.indexOf("3000290033", respErrorCode) < 0) {
                        // 认证服务商'30002'、'90033'为运营商导致的失败，这里不做缓存标记
                        this.setCertificationJunk(1, idCard, name);
                    }

                    throw new LiquidnetServiceException("-1", "身份证号与姓名不符");
                }

                this.setCertification(1, idCard, name);
                break;
            case 0:// 本地存在，验证不通过
                throw new LiquidnetServiceException("-1", "身份证号与姓名不符");
            case 1:// 本地存在，验证通过
                break;
        }
    }
}
