package com.ruoyi.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.demo.constant.RedisContant;
import com.ruoyi.demo.entity.AttentionPool;
import com.ruoyi.demo.entity.WdInfo;
import com.ruoyi.demo.entity.bo.*;
import com.ruoyi.demo.entity.vo.ChannelMapAceeptVo;
import com.ruoyi.demo.mapper.AttentionPoolDao;
import com.ruoyi.demo.service.ChannelMapService;
import com.ruoyi.demo.valida.ChannelAreaGroup;
import com.ruoyi.demo.valida.ChannelListGroup;
import com.ruoyi.demo.valida.ChannelPointGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 渠道地图模块：渠道地图
 */
@RestController
@RequestMapping("/channelMap")

public class ChannelMapController {
    @Autowired
    private ChannelMapService channelMapService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    AttentionPoolDao attentionPoolDao;

    /**
     * 地图模式：查看省级别的网点数量
     * @param channel
     * @return
     */
    @RequestMapping("/getAreaProvince")
    public R areaProvince(ChannelMapAceeptVo channel) {
        //1.查看redis中是否存在有缓存
        channel.setRankType("province");
        String md5 = channel.getHash();
        WdCount wdCount = (WdCount) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).get(md5);
        if (wdCount != null) {
            return R.ok(wdCount);
        }

        //2.查询结果
        WdCount area = channelMapService.areaProvince(channel);
        if(area == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).put(md5,area);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_AREA,RedisContant.CHANNEL_MAP_AREA_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(area);
    }

    /**
     * 地图模式：查看市级别的网点数量
     * @param channel
     * @return
     */
    @RequestMapping("/getAreaCity")
    public R areaCity( ChannelMapAceeptVo channel) {
        //1.查看redis中是否存在有缓存
        channel.setRankType("city");
        String md5 = channel.getHash();
        WdCount wdCount = (WdCount) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).get(md5);
        if (wdCount != null) {
            return R.ok(wdCount);
        }

        //2.查询结果
        WdCount area = channelMapService.areaCity(channel);
        if(area == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).put(md5,area);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_AREA,RedisContant.CHANNEL_MAP_AREA_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(area);
    }

    /**
     * 地图模式：查看区级别的网点数量
     * @param channel
     * @return
     */
    @RequestMapping("/getAreaZone")
    public R areaZone( ChannelMapAceeptVo channel) {
        //1.查看redis中是否存在有缓存
        channel.setRankType("zone");
        String md5 = channel.getHash();
        WdCount wdCount = (WdCount) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).get(md5);
        if (wdCount != null) {
            return R.ok(wdCount);
        }

        //2.查询结果
        WdCount area = channelMapService.areaZone(channel);
        if(area == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).put(md5,area);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_AREA,RedisContant.CHANNEL_MAP_AREA_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(area);
    }


    /**
     * 地图模式：查看所有地区的网点数量
     * @param channel
     * @return
     */
    @RequestMapping("/getArea")
    public R area(@Validated(value={ChannelAreaGroup.class}) ChannelMapAceeptVo channel) {
        //1.查看redis中是否存在有缓存
        String md5 = channel.getHash();
        WdCount wdCount = (WdCount) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).get(md5);
        if (wdCount != null) {
            return R.ok(wdCount);
        }

        //2.查询结果
        WdCount area = channelMapService.area(channel);
        if(area == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_AREA).put(md5,area);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_AREA,RedisContant.CHANNEL_MAP_AREA_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(area);
    }


    /**
     * 获取网点列表
     * @param channel
     * @return
     */
    @RequestMapping("/list")
    public R list(@Validated(value={ChannelListGroup.class}) ChannelMapAceeptVo channel){
        //1.查看redis中是否存在缓存
        String md5 = channel.getHash();
        HashMap pageInfo = (HashMap) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_LIST).get(md5);
        if(pageInfo != null){
            List<WdTopologicalInfoBo> data = (List<WdTopologicalInfoBo>) pageInfo.get("data");
            attention(data); //是否添加关注
            pageInfo.put("data",data);
            return R.ok(pageInfo);
        }

        //2.查询结果
        HashMap hashMap = channelMapService.list(channel);
        if(hashMap == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        List<WdTopologicalInfoBo> data = (List<WdTopologicalInfoBo>) hashMap.get("data");
        attention(data);
        hashMap.put("data",data);
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_LIST).put(md5,hashMap);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_LIST,RedisContant.CHANNEL_MAP_LIST_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(hashMap);
    }


    /**
     * 获取区下的具体网点信息
     * @param channel
     * @return
     */
    @RequestMapping("/point")
    public R point(@Validated(value={ChannelPointGroup.class}) ChannelMapAceeptVo channel){
        //1.查看redis中是否存在缓存
        String md5 = channel.getHash();
        Page<WdInfo> pageInfo = (Page<WdInfo>) redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_POINT).get(md5);
        if(pageInfo != null){
            return R.ok(pageInfo);
        }

        //2.查询结果
        Page<WdInfo> point = channelMapService.point(channel);
        if(point == null)
            return R.fail("请求参数错误");

        //3.保存到redis中
        redisTemplate.boundHashOps(RedisContant.CHANNEL_MAP_POINT).put(md5,point);
        redisTemplate.expire(RedisContant.CHANNEL_MAP_POINT,RedisContant.CHANNEL_MAP_POINT_TIME, TimeUnit.MINUTES); //30分钟
        return R.ok(point);
    }

    /**
     * 标记网点关注列表
     * @param wdTopologicalInfoBos
     */
    public void attention(List<WdTopologicalInfoBo> wdTopologicalInfoBos){
        //需要标志关注的网点Id
        List<String> collect = wdTopologicalInfoBos.stream().map(wdTopologicalInfoBo -> {
            return wdTopologicalInfoBo.getWdId();
        }).collect(Collectors.toList());

        //查询登录用户是否关注
        QueryWrapper<AttentionPool> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.select("wd_id");
        queryWrapper1.eq("user_id", LoginHelper.getUserId());
        queryWrapper1.and(attentionPoolQueryWrapper -> {
            attentionPoolQueryWrapper.in("wd_id",collect);
        });

        if(collect.size() > 0){
            List<AttentionPool> attentionPools = attentionPoolDao.selectList(queryWrapper1);
            List<String> collect1 = attentionPools.stream().map(attentionPool -> {
                return attentionPool.getWdId();
            }).collect(Collectors.toList());

            //标记
            for (WdTopologicalInfoBo wdTopologicalInfoBo : wdTopologicalInfoBos) {
                boolean contains = collect1.contains(wdTopologicalInfoBo.getWdId());
                if (contains)
                    wdTopologicalInfoBo.setAttention(1);
                else
                    wdTopologicalInfoBo.setAttention(0);
            }
        }
    }

    /**
     * 获取网点详细信息
     * @param wdId
     * @return
     */
    @GetMapping("/getWdInfo")
    public R getWdInfo(String wdId){
        WdInfo wdInfo = channelMapService.getWdInfo(wdId);
        if(wdInfo == null)
            return R.ok(null);
        if("1".equals(wdInfo.getWdTypeCode())){
            return R.ok((StoreWdInfoBo)wdInfo);
        }else if("2".equals(wdInfo.getWdTypeCode())){
            return R.ok((HouseWdInfoBo)wdInfo);
        }else if("3".equals(wdInfo.getWdTypeCode())){
            return R.ok((BuildWdInfoBo)wdInfo);
        }else if("4".equals(wdInfo.getWdTypeCode())){
            return R.ok((TrafficWdInfoBo)wdInfo);
        }else if("5".equals(wdInfo.getWdTypeCode())){
            return R.ok((EnterpriseWdInfoBo)wdInfo);
        }
        return R.ok(wdInfo);
    }

}
