package com.liquidnet.service.platform.controller.A_fskfsfs;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
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.AdamEntersParam;
import com.liquidnet.service.adam.dto.vo.AdamEntersVo;
import com.liquidnet.service.adam.entity.AdamEnters;
import com.liquidnet.service.adam.entity.AdamUser;
import com.liquidnet.service.adam.mapper.AdamEntersMapper;
import com.liquidnet.service.adam.mapper.AdamUserMapper;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.platform.utils.QueueUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * 临时数据处理
 *
 * @author jiangxiulong
 */
@Api(tags = "临时数据处理")
@RestController
@RequestMapping("fskfsfs")
@Slf4j
public class JxlDataAdamController {

    @Value("${liquidnet.reviewer.limit.enters:10}")
    private int reviewLimitEnters;

    @Autowired
    private AdamUserMapper adamUserMapper;
    @Autowired
    private AdamEntersMapper adamEntersMapper;

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisDataSourceUtil redisDataSourceUtil;
    @Autowired
    QueueUtils queueUtils;

    @GetMapping("A001")
    @ApiOperation("用户改名 修改入场人信息")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", dataType = "String", name = "oldName", value = "旧名字", required = true),
            @ApiImplicitParam(type = "query", dataType = "String", name = "newName", value = "新名字", required = true),
            @ApiImplicitParam(type = "query", dataType = "String", name = "phone", value = "手机号", required = true)
    })
    public ResponseDto A001(
            @RequestParam("oldName") String oldName,
            @RequestParam("newName") String newName,
            @RequestParam("phone") String phone
    ) {
        AdamUser adamUser = adamUserMapper.selectOne(
                Wrappers.lambdaQuery(AdamUser.class).
                        eq(AdamUser::getMobile, phone)
        );
        String currentUid = adamUser.getUid();
        System.out.println(currentUid);
        LocalDateTime now = LocalDateTime.now();

        AdamEnters adamEnters = adamEntersMapper.selectOne(
                Wrappers.lambdaQuery(AdamEnters.class)
                        .eq(AdamEnters::getName, oldName)
                        .eq(AdamEnters::getUid, currentUid)
        );

        AdamEntersParam parameter = new AdamEntersParam();
        parameter.setType(adamEnters.getType());
        parameter.setIdCard(adamEnters.getIdCard());
        parameter.setEntersId(adamEnters.getEntersId());
        parameter.setMobile(adamEnters.getMobile());
        parameter.setName(newName);
        if (1 == parameter.getType()) {
            this.identityHandler1(currentUid, parameter.getName(), parameter.getIdCard());
        }

        List<AdamEntersVo> vos = this.getEntersVoByUid(currentUid);
        AdamEntersVo updateVo = this.getEntersVoByUidEntersId(vos, parameter.getEntersId());
        updateVo.setType(parameter.getType());
        updateVo.setName(parameter.getName());
        updateVo.setMobile(parameter.getMobile());
        updateVo.setIdCard(parameter.getIdCard());
        updateVo.setUpdatedAt(now);
        long s = System.currentTimeMillis();
        this.setEntersVoByUid(currentUid, this.collectionProcess(vos, parameter.getEntersId(), updateVo));
        if (1 == parameter.getType()) {
            this.setCertification(1, parameter.getIdCard(), parameter.getName());
        }
        log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);

        s = System.currentTimeMillis();
        queueUtils.sendMsgByRedis(
                MQConst.AdamQueue.SQL_UCENTER.getKey(),
                SqlMapping.get("adam_enters.edit",
                        updateVo.getType(), updateVo.getName(), updateVo.getMobile(), updateVo.getIdCard(), updateVo.getIsDefault(), now, updateVo.getEntersId()
                )
        );
        log.debug("#MQ耗时:{}ms", System.currentTimeMillis() - s);

        return ResponseDto.success();
    }

    /**
     * 身份证实名处理
     *
     * @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)) {
                    ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("10102");
                    throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                }

                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);
                    }

                    ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("10102");
                    throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
                }

                this.setCertification(1, idCard, name);
                break;
            case 0:// 本地存在，验证不通过
                ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("10102");
                throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
            case 1:// 本地存在，验证通过
                break;
        }
    }

    /**
     * 目前只针对身份证类型三方服务认证成功的标记
     *
     * @param idType
     * @param idNo
     * @param idName
     * @return
     */
    public int isCertification(int idType, String idNo, String idName) {
        redisDataSourceUtil.getRedisAdamUtil().del(AdamRedisConst.INFO_CERTIFICATION + idType + idNo);
        String o = (String) redisDataSourceUtil.getRedisAdamUtil().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 idType
     * @param idNo
     * @param idName
     * @return
     */
    public boolean setCertification(int idType, String idNo, String idName) {
        return redisDataSourceUtil.getRedisAdamUtil().set(AdamRedisConst.INFO_CERTIFICATION + idType + idNo, idName);
    }

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

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

    public List<AdamEntersVo> getEntersVoByUid(String uid) {
        String rk = AdamRedisConst.INFO_ENTERS.concat(uid);
        long s = System.currentTimeMillis();
        AbstractRedisUtil redisAdamUtil = redisDataSourceUtil.getRedisAdamUtil();
        ArrayList<AdamEntersVo> vos = (ArrayList<AdamEntersVo>) redisAdamUtil.get(rk);
        log.debug("#RDM耗时:{}ms", System.currentTimeMillis() - s);
        return vos;
    }

    public AdamEntersVo getEntersVoByUidEntersId(List<AdamEntersVo> vos, String entersId) {
        return CollectionUtils.isEmpty(vos) ? null : vos.stream().filter(r -> r.getEntersId().equals(entersId)).findAny().orElse(null);
    }

    public boolean setEntersVoByUid(String uid, List<AdamEntersVo> list) {
        return redisDataSourceUtil.getRedisAdamUtil().set(AdamRedisConst.INFO_ENTERS.concat(uid), list);
    }

    private List<AdamEntersVo> collectionProcess(List<AdamEntersVo> vos, String replaceId, AdamEntersVo updateVo) {
        long s = System.currentTimeMillis();
        int idx = IntStream.range(0, vos.size())
                .filter(i -> vos.get(i).getEntersId().equals(replaceId))
                .findFirst().orElse(-1);
        if (idx == -1) {
            ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("10017");
            throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
        }
        vos.set(idx, updateVo);
        log.debug("#collect.process耗时:{}ms", System.currentTimeMillis() - s);
        return vos;
    }

}
