package com.liquidnet.service.sweet.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.sweet.dto.SweetCityVoteStatDto;
import com.liquidnet.service.sweet.dto.vo.TempBannerVo;
import com.liquidnet.service.sweet.entity.SweetCityVote;
import com.liquidnet.service.sweet.mapper.SweetCityVoteMapper;
import com.liquidnet.service.sweet.mapper.SweetCityVoteStatMapper;
import com.liquidnet.service.sweet.param.SweetCityVoteParam;
import com.liquidnet.service.sweet.service.ISweetCityVoteService;
import com.liquidnet.service.sweet.utils.ObjectUtil;
import com.liquidnet.service.sweet.utils.QueueUtils;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import com.liquidnet.service.sweet.utils.WechatUsersRedisUtils;
import com.liquidnet.service.sweet.vo.SweetCItyVoteStatVo;
import com.liquidnet.service.sweet.vo.SweetWechatUsersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import static com.liquidnet.commons.lang.util.DateUtil.DTF_YMD_HMS;

/**
 * <p>
 * 答题表 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-08-12
 */
@Service
public class SweetCityVoteServiceImpl extends ServiceImpl<SweetCityVoteMapper, SweetCityVote> implements ISweetCityVoteService {

    @Autowired
    private RedisDataUtils redisDataUtils;
    @Autowired
    private WechatUsersRedisUtils usersRedisUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    private SweetCityVoteStatMapper sweetCityVoteStatMapper;

    @Override
    public ResponseDto getList(String phone, String unionId, Integer type) {
        List<SweetCItyVoteStatVo> sweetCityVoteStatList = redisDataUtils.getSweetCityVoteStatList(type);
        SweetCityVoteParam userVote = redisDataUtils.getUserVote(phone, unionId, type);
        if (!CollectionUtils.isEmpty(sweetCityVoteStatList)) {
            for (SweetCItyVoteStatVo info : sweetCityVoteStatList) {
                if (null == userVote) {
                    info.setIsVote(1);
                } else if (userVote.getCityCode().equals(info.getCityCode())) {
                    info.setIsVote(2);
                } else {
                    info.setIsVote(3);
                }
            }
        }

        HashMap<String, Object> stringObjectHashMap = CollectionUtil.mapStringObject();
        stringObjectHashMap.put("list", sweetCityVoteStatList);
        stringObjectHashMap.put("userVote", userVote);
        stringObjectHashMap.put("statUpdateTime", redisDataUtils.getSweetCityVoteStatUpdateTime(type));

        //获取活动状态
        HashMap<String, String> map = redisDataUtils.getStartEndTime(type);
        if (map.get("startTime") == null || map.get("endTime") == null) {
            stringObjectHashMap.put("activeStatus", 1);
        } else {
            LocalDateTime startTime = LocalDateTime.parse(map.get("startTime"), DTF_YMD_HMS);
            LocalDateTime endTime = LocalDateTime.parse(map.get("endTime"), DTF_YMD_HMS);
            LocalDateTime now = LocalDateTime.now();
            if (startTime.isAfter(now)) {
                stringObjectHashMap.put("activeStatus", 0);
            } else if (endTime.isBefore(now)) {
                stringObjectHashMap.put("activeStatus", 2);
            } else {
                stringObjectHashMap.put("activeStatus", 1);
            }
        }
        //获取banner
        List<TempBannerVo> bannerVoList = redisDataUtils.getTempBanner(type);
        stringObjectHashMap.put("bannerList", bannerVoList);

        return ResponseDto.success(stringObjectHashMap);
    }

    @Override
    public ResponseDto createVote(SweetCityVoteParam param) {
        SweetCityVoteParam userVote = redisDataUtils.getUserVote(param.getPhone(), param.getUnionId(), param.getType());
        if (null != userVote) {
            return ResponseDto.failure("已经投过票啦～");
        }
        SweetCityVote aNew = SweetCityVote.getNew();
        aNew.setVoteId(IDGenerator.nextSnowId());
        aNew.setPhone(param.getPhone());
        SweetWechatUsersVo sweetWechatUsers = usersRedisUtils.getSweetWechatUsersOfUnionId(param.getUnionId(), 2);
        String sweetWechatOpenId = "";
        if (null != sweetWechatUsers) {
            sweetWechatOpenId = sweetWechatUsers.getOpenId();
            aNew.setOpenId(sweetWechatOpenId);
        }
        aNew.setUnionId(param.getUnionId());
        aNew.setCityCode(param.getCityCode());
        aNew.setCityName(param.getCityName());
        aNew.setType(param.getType());


        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("sweet_city_vote.insert"));
        sqlsDataA.add(new Object[]{
                aNew.getVoteId(), aNew.getPhone(), sweetWechatOpenId, aNew.getUnionId(), aNew.getType(), aNew.getCityCode(), aNew.getCityName(), DateUtil.format(LocalDateTime.now(), DateUtil.Formatter.yyyyMMdd)
        });
        Integer cityVoteNum = redisDataUtils.getSweetCityVote(aNew.getCityCode(), aNew.getType());
        if (cityVoteNum > 0) { // 已有 incr
            sqls.add(SqlMapping.get("sweet_city_vote_stat.update"));
            sqlsDataB.add(new Object[]{
                    LocalDateTime.now(), aNew.getCityCode(), aNew.getType()
            });
        } else { // insert
            sqls.add(SqlMapping.get("sweet_city_vote_stat.insert"));
            sqlsDataB.add(new Object[]{
                    IDGenerator.nextSnowId(), aNew.getCityCode(), aNew.getCityName(), 1, aNew.getType()
            });
        }
        queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_CITY_VOTE.getKey(),
                SqlMapping.gets(sqls, sqlsDataA, sqlsDataB));

        redisDataUtils.incrSweetCityVote(aNew.getCityCode(), aNew.getType());

        redisDataUtils.setUserVote(param.getPhone(), param.getUnionId(), param);

        return ResponseDto.success();
    }

    public ResponseDto setStatList(Integer type) {
        List<SweetCityVoteStatDto> list = sweetCityVoteStatMapper.getStatList(type);
        List<SweetCItyVoteStatVo> sweetCityVoteStatList = redisDataUtils.getSweetCityVoteStatList(type);
        ArrayList<SweetCItyVoteStatVo> newList = ObjectUtil.getSweetCItyVoteStatVoList();
        if (!CollectionUtils.isEmpty(list)) {
            Integer ranking = 0;
            Integer rankingUpOrDown = 1;
            for (SweetCityVoteStatDto cityVote : list) {
                SweetCItyVoteStatVo voteStatVo = SweetCItyVoteStatVo.getNew().copy(cityVote);
                voteStatVo.setRanking(ranking);
                // 1.找到了老数据就进行对比 2.未找到说明是新增的 默认为排名不变 3.第一次没有统计过默认不变
                for (SweetCItyVoteStatVo statVoOld : sweetCityVoteStatList) {
                    if (statVoOld.getCityCode().equals(cityVote.getCityCode())) {
                        Integer oldRanking = statVoOld.getRanking();
                        if (null != oldRanking) { // 老数据没有这个字段默认为上升
                            if (oldRanking > ranking) {
                                rankingUpOrDown = 2;
                            } else if (oldRanking < ranking) {
                                rankingUpOrDown = 3;
                            } else {
                                rankingUpOrDown = 1;
                            }
                        }
                    }
                }
                voteStatVo.setRankingUpOrDown(rankingUpOrDown);
                newList.add(voteStatVo);
                ranking++;
            }
            // list.forEach(r -> newList.add(SweetCItyVoteStatVo.getNew().copy(r)));
            redisDataUtils.setSweetCityVoteStatList(newList, type);
        } else {
            redisDataUtils.setSweetCityVoteStatList(newList, type);
        }
        redisDataUtils.setSweetCityVoteStatUpdateTime(type);
        return ResponseDto.success();
    }
}
