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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.common.cache.redis.util.AbstractRedisUtil;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.AdamUserInfoDto;
import com.liquidnet.service.adam.dto.vo.AdamProPerformMarkVo;
import com.liquidnet.service.adam.dto.vo.AdamProScanitVo;
import com.liquidnet.service.adam.dto.vo.AdamUserInfoVo;
import com.liquidnet.service.adam.dto.vo.AdamUserMemberVo;
import com.liquidnet.service.adam.entity.AdamUserInfo;
import com.liquidnet.service.adam.mapper.AdamUserInfoMapper;
import com.liquidnet.service.adam.mapper.AdamUserMapper;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.platform.utils.ObjectUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class PlatformAdamUserProService extends ServiceImpl<AdamUserInfoMapper, AdamUserInfo> {
    @Autowired
    private RedisDataSourceUtil redisDataSourceUtil;
    @Autowired
    private AdamUserMapper adamUserMapper;

    public AdamProScanitVo scanitProcess(String pid, String pna, String cod) {
        LambdaQueryWrapper<AdamUserInfo> userInfoLambdaQueryWrapper = Wrappers.lambdaQuery(AdamUserInfo.class);
        userInfoLambdaQueryWrapper.eq(AdamUserInfo::getQrCode, cod);
        userInfoLambdaQueryWrapper.select(AdamUserInfo::getUid);
        AdamUserInfo userInfo = this.getOne(userInfoLambdaQueryWrapper);

        AdamProScanitVo scanitVo = AdamProScanitVo.getNew();
        if (null != userInfo) {
            String uid = userInfo.getUid();
            AbstractRedisUtil redisAdamUtil = redisDataSourceUtil.getRedisAdamUtil();
            AdamUserInfoVo userInfoVo = (AdamUserInfoVo) redisAdamUtil.get(AdamRedisConst.INFO_USER.concat(uid));
            if (null != userInfoVo) {
                scanitVo.setNickname(userInfoVo.getNickname());
                scanitVo.setMobile(userInfoVo.getMobile());
            } else {
                AdamUserInfoDto adamUserInfoDto = adamUserMapper.selectByUid(userInfo.getUid());
                if (null != adamUserInfoDto) {
                    scanitVo.setNickname(adamUserInfoDto.getNickname());
                    scanitVo.setMobile(adamUserInfoDto.getMobile());
                }
            }
            AdamUserMemberVo userMemberVo = (AdamUserMemberVo) redisAdamUtil.get(AdamRedisConst.INFO_USER_MEMBER.concat(uid));
            if (null == userMemberVo) {
                scanitVo.setStageMarker(0);
            } else {
                if (userMemberVo.isActive()) {
                    scanitVo.setStageMarker(userMemberVo.isOldMember() ? 10 : 11);
                } else {
                    scanitVo.setStageMarker(2);
                }
            }
            this.performanceMarkProcessing(scanitVo, uid, pid, pna);

        }
        return scanitVo;
    }

    private void performanceMarkProcessing(AdamProScanitVo scanitVo, String uid, String pid, String pname) {
        AbstractRedisUtil redisAdamUtil = redisDataSourceUtil.getRedisAdamUtil();

        LocalDateTime now = LocalDateTime.now();
        String rk = AdamRedisConst.CACHE_USER_PERFORMANCE_MARK.concat(uid);
        String rkv = (String) redisAdamUtil.get(rk);

        List<AdamProPerformMarkVo> performMarkVos = JsonUtils.fromJson(rkv, new TypeReference<List<AdamProPerformMarkVo>>() {
        });
        if (!CollectionUtils.isEmpty(performMarkVos)) {
            Optional<AdamProPerformMarkVo> optional = performMarkVos.stream().filter(vo -> vo.getPid().equals(pid)).findAny();
            if (optional.isPresent()) {
                AdamProPerformMarkVo proPerformMarkVo = optional.get();
                performMarkVos.remove(proPerformMarkVo);

                proPerformMarkVo.setTime(DateUtil.Formatter.yyyyMMddHHmmss.format(now));
                proPerformMarkVo.setCount(proPerformMarkVo.getCount() + 1);

                performMarkVos.add(proPerformMarkVo);
            } else {
                AdamProPerformMarkVo proPerformMarkVo = AdamProPerformMarkVo.getNew();
                proPerformMarkVo.setPid(pid);
                proPerformMarkVo.setPname(pname);
                proPerformMarkVo.setTime(DateUtil.Formatter.yyyyMMddHHmmss.format(now));
                proPerformMarkVo.setCount(1);

                performMarkVos.add(proPerformMarkVo);
            }

            performMarkVos.sort(Comparator.comparing(AdamProPerformMarkVo::getTime).reversed());

            Iterator<AdamProPerformMarkVo> iterator = performMarkVos.iterator();
            while (iterator.hasNext()) {
                AdamProPerformMarkVo next = iterator.next();
                LocalDateTime time = DateUtil.Formatter.yyyyMMddHHmmss.parse(next.getTime());
                if (null == time || time.plusDays(7).isBefore(now)) {
                    iterator.remove();
                }
            }
        } else {
            performMarkVos = ObjectUtil.getAdamProPerformMarkVoArrayList();

            AdamProPerformMarkVo performMarkVo = AdamProPerformMarkVo.getNew();
            performMarkVo.setPid(pid);
            performMarkVo.setPname(pname);
            performMarkVo.setTime(DateUtil.Formatter.yyyyMMddHHmmss.format(now));
            performMarkVo.setCount(1);

            performMarkVos.add(performMarkVo);
        }

        redisAdamUtil.set(rk, JsonUtils.toJson(performMarkVos), 864000);// 缓存时效10天
        scanitVo.setPerformMarkVos(performMarkVos);
    }
}
