package com.liquidnet.client.admin.zhengzai.adam.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamMemberCodeAdminService;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.AdamMemberCodeParam;
import com.liquidnet.service.adam.dto.vo.AdamMemberCodeVo;
import com.liquidnet.service.adam.entity.AdamMemberCode;
import com.liquidnet.service.adam.mapper.AdamMemberCodeMapper;
import com.liquidnet.service.adam.util.MemberUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.regex.Pattern;

@Slf4j
@Service
public class AdamMemberCodeAdminServiceImpl extends ServiceImpl<AdamMemberCodeMapper, AdamMemberCode> implements IAdamMemberCodeAdminService {
    @Autowired
    AdamMemberCodeMapper memberCodeMapper;
//    @Autowired
//    MongoTemplate mongoTemplate;
    @Autowired
    RedisUtil redisUtil;

    @Override
    public String createGiftCode(AdamMemberCodeParam param) {
        String mCode, memberNo;
        boolean exists;
        do {
            mCode = MemberUtil.freeCode();
//            exists = mongoTemplate.exists(
//                    Query.query(Criteria.where("code").is(mCode)), AdamMemberCodeVo.class.getSimpleName()
//            );
            exists = redisUtil.hasKey(mCode);
        } while (exists);

        // 需要主动生成会员编号
        memberNo = getNextMemberNo(param.getMemberId());

        if (StringUtils.isEmpty(memberNo)) return "";

        AdamMemberCode initMemberCode = new AdamMemberCode();
        initMemberCode.setCode(mCode);
        initMemberCode.setType(param.getType());
        initMemberCode.setMemberId(param.getMemberId());
        initMemberCode.setMemberPriceId(param.getMemberPriceId());
        initMemberCode.setMemberNo(memberNo);
        initMemberCode.setState(0);// 0-未使用,1-已使用,2-不可用
        initMemberCode.setCreatedAt(LocalDateTime.now());

        memberCodeMapper.insert(initMemberCode);

        AdamMemberCodeVo vo = AdamMemberCodeVo.getNew().copy(initMemberCode);
//        mongoTemplate.insert(vo, AdamMemberCodeVo.class.getSimpleName());

        setMemberCodeVoByCode(mCode, vo);

        return initMemberCode.getCode();
    }

    public String getNextMemberNo(String memberId) {
        long s = System.currentTimeMillis();
        int memberMaxNo = getMaxMemberNo();
        if (-1 == memberMaxNo) {
            // TODO: 2021/7/29 降级DB
            throw new LiquidnetServiceException();
//            if (RedisLockUtil.tryLock(LOCK_KEY_UMEMBER_NO, 1, 3)) {
//                memberMaxNo = 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 = getMemberVoByMemberId(memberId);
//
//                        setMaxMemberNo(memberVo.getStartNo());
//                    } else {
//                        setMaxMemberNo(Integer.parseInt(latestMaxMemberNoVo.getMemberNo()));
//                    }
//                }
//                RedisLockUtil.unlock(LOCK_KEY_UMEMBER_NO);
//            } else {
//                return null;
//            }
        }
        String nextMemberNoStr = String.valueOf(incrMemberNo());
        if (Pattern.matches("([\\d])\\1{" + (nextMemberNoStr.length() - 1) + "}", nextMemberNoStr)) {
            // 不能是完全相同的数字
            nextMemberNoStr = String.valueOf(incrMemberNo());
        }
        log.debug("#MNO耗时:{}ms", System.currentTimeMillis() - s);
        return nextMemberNoStr;
    }

    private int getMaxMemberNo() {
        Object o = redisUtil.get(AdamRedisConst.INCR_MEMBER_NO);
        return null == o ? -1 : (int) o;
    }

//    public AdamMemberVo getMemberVoByMemberId(String memberId) {
//        String key = AdamRedisConst.INFO_MEMBER_CATEGORY.concat(memberId);
//        long s = System.currentTimeMillis();
//        AdamMemberVo vo = (AdamMemberVo) redisUtil.get(key);
//        if (null == vo) {
//            s = System.currentTimeMillis();
//            vo = mongoTemplate.findOne(
//                    Query.query(Criteria.where("memberId").is(memberId).and("state").is(1)),
//                    AdamMemberVo.class, AdamMemberVo.class.getSimpleName()
//            );
//            log.debug("#MDB耗时:{}ms", System.currentTimeMillis() - s);
//            if (null != vo) redisUtil.set(key, vo);
//        }
//        log.debug("#RDM耗时:{}ms", System.currentTimeMillis() - s);
//        return vo;
//    }

    public boolean setMaxMemberNo(int val) {
        return redisUtil.set(AdamRedisConst.INCR_MEMBER_NO, val);
    }

    public int incrMemberNo() {
        return (int) redisUtil.incr(AdamRedisConst.INCR_MEMBER_NO, 1);
    }

    public boolean setMemberCodeVoByCode(String memberCode, AdamMemberCodeVo vo) {
        return redisUtil.set(AdamRedisConst.INFO_MEMBER_CODE.concat(memberCode), vo);
    }
}
