package cn.wisenergy.chnmuseum.party.service.impl;

import cn.wisenergy.chnmuseum.party.common.util.CurrencyMathUtil;
import cn.wisenergy.chnmuseum.party.common.util.DateUtil;
import cn.wisenergy.chnmuseum.party.common.util.RedisUtil;
import cn.wisenergy.chnmuseum.party.core.annotations.RedisLock;
import cn.wisenergy.chnmuseum.party.model.*;
import cn.wisenergy.chnmuseum.party.mapper.TBoardStatisticMapper;
import cn.wisenergy.chnmuseum.party.service.TAreaService;
import cn.wisenergy.chnmuseum.party.service.TBoardStatisticService;
import cn.wisenergy.chnmuseum.party.service.TUserService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 展板统计信息表 服务实现类
 * </pre>
 *
 * @author Danny Lee
 * @since 2021-03-25
 */
@Slf4j
@Service
public class TBoardStatisticServiceImpl extends ServiceImpl<TBoardStatisticMapper, TBoardStatistic> implements TBoardStatisticService {

    @Autowired
    private TBoardStatisticMapper boardStatisticMapper;

    @Autowired
    private TUserService userService;

    @Autowired
    private TAreaService areaService;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RedisTemplate<String,? extends Object> redisTemplate;
    private static String STATISTIC_BOARD_INFO_KEY = "STATISTIC_BOARD_INFO_KEY"; // 展板统计信息key
    @Override
    @RedisLock(value = "boardLock",timeLock = 20 ,required = true,timeOut = 1100000)
    public Object boardStatisticInfo(TBoardStatistic tBoardStatistic, boolean autoUpdate) {
        // 根据用户id获取用户信息
        TUser user = userService.selectById(tBoardStatistic.getUserId());

        tBoardStatistic.setOrganId(user.getOrgId());    // 用户所属机构
        tBoardStatistic.setAreaId(Integer.parseInt(user.getAreaId()));// 用户所属地区
        if (StringUtils.isEmpty(tBoardStatistic.getPlayDate())){
            // 获取当前日期
            tBoardStatistic.setPlayDate(DateUtil.getCurrentDate("yyyyMMdd"));
        }
        List<TBoardStatistic> statisticList = new ArrayList<>();
        String redisKey = STATISTIC_BOARD_INFO_KEY;
        // 获取统计信息缓存数据
        String businessJsonArray = (String) redisUtil.get(redisKey);
        // 缓存数据不为空,转换数据
        if (StringUtils.isNotEmpty(businessJsonArray)){
            statisticList = JSONObject.parseArray(businessJsonArray, TBoardStatistic.class);
        }
        statisticList.add(tBoardStatistic);
        redisUtil.set(redisKey, JSON.toJSON(statisticList).toString());
        // 统计记录数等于100 时,或者需要自动更新时 汇总统计数据
        if (statisticList.size() >= 100 || autoUpdate){
            // 更新展板统计信息
            updateBoardStatisticInfo(statisticList,redisKey);
        }
        return true;
    }


    @Override
    public Page<TBoardPlayRank> getBoardRankPageList(Page<TBoardPlayRank> page,TBoardPlayRank rank) {
        page.setRecords(boardStatisticMapper.getBoardRankPageList(page,rank));
        return page;
    }

    @Override
    public Page<TBoardPlayTrend> getBoardTrendPageList(Page<TBoardPlayTrend> page, TBoardPlayTrend trend) {

        page.setRecords(boardStatisticMapper.getBoardTrendPageList(page,trend));
        return page;
    }


    @Override
    public Page<TDistrictBoardStatistic> getBoardDistrictPageList(Page<TDistrictBoardStatistic> page, TDistrictBoardStatistic district){
        List<TDistrictBoardStatistic> list = boardStatisticMapper.getBoardDistrictPageList(page, district);
        list.stream().forEach(l->l.setAreaName(l.getAreaName().replace("省","").replace("市","").
                replace("自治区","").replace("特别行政区","").replace("壮族","").replace("回族","").replace("维吾尔","")));
        page.setRecords(list);
        return page;
    }

    @Override
    public TBoardSurvey getBoardSurvey(TBoardSurvey survey){
        // 获取展板播放量
        survey.setPlayCnt(boardStatisticMapper.getBoardPlayTotal(survey));
        // 获取展板总数
        survey.setBoardCnt(boardStatisticMapper.getBoardTotal(survey));
        // 获取播放展板的机构总数
        survey.setOrgCnt(boardStatisticMapper.getOrganTotal(survey));
        // 获取互动总数
        survey.setInteractionCnt(boardStatisticMapper.getInteractionTotal(survey));
        return survey;
    }

    @Override
    public Page getInteractionFrequency(Page page,String frequencyDate){
        page.setRecords(boardStatisticMapper.getInteractionFrequency(page,frequencyDate));
        return page;
    }

    @Override
    public List getBoardProvincePlayTotalList(String organId){
        // 获取省份信息
        QueryWrapper qw = new QueryWrapper();
        qw.eq("type","P");
        List<TArea> provlist = areaService.list(qw);
        // 遍历省份,统计各省播放量
        TBoardSurvey survey = new TBoardSurvey();
        String dateStr = DateUtil.getCurrentDate("yyyyMM");
        survey.setStatisticDate(dateStr);
        survey.setOrganId(organId);
        List list = new ArrayList();
        // 根据省份查询播放量
        for(TArea prov : provlist){
            Map map = new HashMap();
            survey.setAreaId(prov.getId().toString().substring(0,2));
            Integer cnt = boardStatisticMapper.getBoardPlayTotal(survey);
            map.put("name",prov.getName());
            map.put("value",cnt == null ? 0 : cnt);
            list.add(map);
        }
        return list;
    }

    /**
     * 更新展板统计信息
     */
    @Override
    public void updateBoardStatisticInfo(List<TBoardStatistic> statisticList,String redisKey) {
        Map<String,TBoardStatistic> map = new HashMap<>();
        statisticList.stream().forEach(s->{
            String key = s.getBoardId()+"_"+s.getOrganId()+"_"+s.getPlayDate();
            // 如果有对应的展板记录,累计播放量
            if (map.containsKey(key)){
                TBoardStatistic boardStatistic = map.get(key);
                boardStatistic.setPlayNumber(Integer.parseInt(CurrencyMathUtil.add(boardStatistic.getPlayNumber(),s.getPlayNumber())));
                map.put(key,boardStatistic);
            }else {
                // 如果无对应的展板记录,插入到map中
                map.put(key,s);
            }
        });
        // 更新数据库展板统计信息
        for (String key : map.keySet()){
            TBoardStatistic bs = map.get(key);
            // 查询数据库是否有对应的记录
            QueryWrapper<TBoardStatistic> qw = new QueryWrapper<>();
            qw.eq("board_id",bs.getBoardId());
            qw.eq("organ_id",bs.getOrganId());
            qw.eq("play_date",bs.getPlayDate());
            TBoardStatistic tbDB = this.getOne(qw);
            // 如果数据库存在统计记录,则累计统计数量
            if (tbDB != null){
                tbDB.setPlayNumber(Integer.parseInt(CurrencyMathUtil.add(bs.getPlayNumber(),tbDB.getPlayNumber())));
                this.updateById(tbDB);
                map.put(key,tbDB);
            }else {
                // 如果数据库不存在统计记录,则增加统计数据
                this.save(bs);
            }
        }
        // 更新展板播放排行 t_board_play_rank

        // 插入

        // 看板播放趋势

        // 地区看板播放统计

        // 播放数据概览

        // 清空redis
        redisUtil.del(redisKey);
    }

}