package com.liquidnet.service.adam.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redisson.util.RedisLockUtil;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.AdamMemberVo;
import com.liquidnet.service.adam.dto.vo.AdamUserMemberVo;
import com.liquidnet.service.adam.entity.AdamUserMember;
import com.liquidnet.service.adam.mapper.AdamUserMemberMapper;
import com.liquidnet.service.adam.service.IAdamRdmService;
import com.liquidnet.service.adam.service.IAdamUserMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.regex.Pattern;

@Slf4j
@Service
public class AdamUserMemberServiceImpl extends ServiceImpl<AdamUserMemberMapper, AdamUserMember> implements IAdamUserMemberService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    IAdamRdmService adamRdmService;

    private static final String LOCK_KEY_UMEMBER_NO = "adam:lk:member_no";

    @Override
    public String getNextMemberNo(String memberId) {
        long s = System.currentTimeMillis();
        int memberMaxNo = adamRdmService.getMaxMemberNo();
        if (-1 == memberMaxNo) {
            if (RedisLockUtil.tryLock(LOCK_KEY_UMEMBER_NO, 1, 3000)) {
                memberMaxNo = adamRdmService.getMaxMemberNo();
                if (-1 == memberMaxNo) {
                    Query query = Query.query(Criteria.where("memberId").is(memberId)).with(Sort.by(Sort.Direction.DESC, "memberNo")).limit(1);

                    AdamUserMemberVo latestMaxMemberNoVo = mongoTemplate.findOne(query, AdamUserMemberVo.class, AdamUserMemberVo.class.getSimpleName());

                    if (null == latestMaxMemberNoVo) {
                        AdamMemberVo memberVo = adamRdmService.getMemberVoByMemberId(memberId);

                        adamRdmService.setMaxMemberNo(memberVo.getStartNo());
                    } else {
                        adamRdmService.setMaxMemberNo(Integer.parseInt(latestMaxMemberNoVo.getMemberNo()));
                    }
                }
                RedisLockUtil.unlock(LOCK_KEY_UMEMBER_NO);
            } else {
                return null;
            }
        }
        String nextMemberNoStr = String.valueOf(adamRdmService.incrMemberNo());
        if (Pattern.matches("([\\d])\\1{" + (nextMemberNoStr.length() - 1) + "}", nextMemberNoStr)) {
            // 不能是完全相同的数字
            nextMemberNoStr = String.valueOf(adamRdmService.incrMemberNo());
        }
        log.debug("#MNO耗时:{}ms", System.currentTimeMillis() - s);
        return nextMemberNoStr;
    }

//    @Override
//    public boolean getOneFromRepertory(String memberId) {
//        AdamMemberVo adamMemberVo = (AdamMemberVo) redisUtil.get(AdamRedisConst.INFO_MEMBERS_INFO.concat(memberId));
//        if (null == adamMemberVo) {
//            adamMemberVo = mongoTemplate.findOne(Query.query(Criteria.where("memberId").is(memberId)), AdamMemberVo.class, AdamMemberVo.class.getSimpleName());
//        }
//        if (0 == adamMemberVo.getLimitation()) {
//            return true;
//        }
//        String repertoryKey = AdamRedisConst.INFO_MEMBERS_REPERTORY_INFO.concat(memberId);
//        Object repertory = redisUtil.get(repertoryKey);
//        // 判断，如果没有从redis中拿到库存数量，则把MongoDB中查出的库存插入redis
//        if (null == repertory) {
//            redisUtil.set(repertoryKey, adamMemberVo.getLimitation());
//            repertory = adamMemberVo.getLimitation();
//        }
//        Long limitation = Long.parseLong(repertory.toString());
//        limitation = redisUtil.decr(repertoryKey, limitation);
//        // 库存大于0 正常返回，否则回滚一位库存
//        if (limitation >= 0) {
//            return true;
//        } else {
//            redisUtil.incr(repertoryKey, 1);
//            return false;
//        }
//    }
}
