package com.ruoyi.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.demo.entity.BuildWd;
import com.ruoyi.demo.entity.TopologicalBuildingWd;
import com.ruoyi.demo.entity.WdInfo;
import com.ruoyi.demo.entity.bo.BuildWdCategoryCount;
import com.ruoyi.demo.entity.bo.Histogram;
import com.ruoyi.demo.entity.vo.TopologicalWdAceeptVo;
import com.ruoyi.demo.mapper.BuildWdDao;
import com.ruoyi.demo.mapper.WdInfoDao;
import com.ruoyi.demo.service.TopologicalBuildWdSerevice;
import com.ruoyi.demo.utils.InitMapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Transactional
public class TopologicalBuildWdSereviceImpl implements TopologicalBuildWdSerevice {

    @Autowired
    WdInfoDao wdInfoDao;

    @Autowired
    InitMapUtil initMapUtil;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    BuildWdDao buildWdDao;

    /**
     * 周边楼宇物业类别统计
     * @param topologicalWdAceeptVo
     * @return
     */
    @Override
    public List<BuildWdCategoryCount> buildingLevel(TopologicalWdAceeptVo topologicalWdAceeptVo) {
        List<String> aroundWdId = new ArrayList<>();

        //1.根据经纬度 找到 周边网点Id 及 距离
        getAroundWdIdList(topologicalWdAceeptVo,aroundWdId,null);
        if (aroundWdId.isEmpty())
            return new ArrayList<>();

        //2.分页查找网点信息
        QueryWrapper<BuildWd> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("property_type","count(*) as people_count");
        queryWrapper.in("wd_id",aroundWdId);
        queryWrapper.groupBy("property_type");
        List<BuildWd> buildWds = buildWdDao.selectList(queryWrapper);

        //3.封装结果集
        List<BuildWdCategoryCount> list = new ArrayList<>();
        for (BuildWd buildWd : buildWds) {
            if (buildWd.getPropertyType().equals(""))
                continue;
            BuildWdCategoryCount buildWdCategoryCount = new BuildWdCategoryCount();
            buildWdCategoryCount.setName(buildWd.getPropertyType());
            buildWdCategoryCount.setCount(buildWd.getPeopleCount());
            list.add(buildWdCategoryCount);
        }

        return list;
    }

    /**
     * 获取周边楼宇列表
     * @param topologicalWdAceeptVo
     * @return
     */
    @Override
    public Page<TopologicalBuildingWd>  list(TopologicalWdAceeptVo topologicalWdAceeptVo) {
        List<String> aroundWdId = new ArrayList<>();
        HashMap<String,Double> wdDistMap = new HashMap<>();

        //1.根据经纬度 找到 周边网点Id 及 距离
        getAroundWdIdList(topologicalWdAceeptVo,aroundWdId,wdDistMap);
        if (aroundWdId.isEmpty()){
            //没有周边网点
            Page<TopologicalBuildingWd> page = new Page<>(topologicalWdAceeptVo.getPageNum(),topologicalWdAceeptVo.getPageSize());
            return page;
        }

        //2.分页查找网点信息
        QueryWrapper<WdInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wd_type_code","3");
        queryWrapper.and(wdInfoQueryWrapper -> {
            wdInfoQueryWrapper.in("ddt_wd_info.wd_id", aroundWdId);
        });

        Page<WdInfo> page = new Page<>(topologicalWdAceeptVo.getPageNum(),topologicalWdAceeptVo.getPageSize());
        Page<TopologicalBuildingWd> page1 = wdInfoDao.selectTopologicalBuildWdList(page, queryWrapper);


        //3.组装结果集
        for (TopologicalBuildingWd topologicalBuildingWd : page1.getRecords()) {
            //topologicalBuildingWd.setAddrCodeInfo(initMapUtil.getInitAddrCodeMap(topologicalBuildingWd.getAddrCode()));
            BigDecimal bigDecimal = new BigDecimal(wdDistMap.get(topologicalBuildingWd.getAroundWdId()));
            topologicalBuildingWd.setDistance(bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        }

        //5.返回结果
        return page1;
    }

    /**
     * 获取楼宇分类统计
     * @param topologicalWdAceeptVo
     * @return
     */
    @Override
    public List<Histogram> buildingHistogram(TopologicalWdAceeptVo topologicalWdAceeptVo) {
        List<String> aroundWdId = new ArrayList<>();

        //1.根据经纬度 找到 周边网点Id 及 距离
        getAroundWdIdList(topologicalWdAceeptVo,aroundWdId,null);
        if (aroundWdId.isEmpty())
            return new ArrayList<>();

        //2.获取符合条件的楼宇网点
        QueryWrapper<WdInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("type_code_by","count(*) as audit");
        queryWrapper.and(queryWrapper2 -> {
            queryWrapper2.eq("wd_type_code","3");
        });
        queryWrapper.and(queryWrapper2 -> {
            queryWrapper2.in("wd_id",aroundWdId);
        });
        queryWrapper.and(queryWrapper2 -> {
            queryWrapper2.isNotNull("type_code_by");
        });
        queryWrapper.groupBy("type_code_by");
        List<WdInfo> wdInfos = wdInfoDao.selectList(queryWrapper);

        //3.统计楼宇分类
        int total = 0;
        HashMap<String,Integer> hashMap = new HashMap<>();
        for (WdInfo wdInfo : wdInfos) {
            if(wdInfo.getTypeCodeBy() == null)
                continue;
            String typeCodeBy = wdInfo.getTypeCodeBy().substring(0,2);
            Integer integer = hashMap.get(typeCodeBy);
            if (integer == null){
                hashMap.put(typeCodeBy,wdInfo.getAudit());
            }else {
                hashMap.put(typeCodeBy,hashMap.get(typeCodeBy)+wdInfo.getAudit());
            }
            total+=wdInfo.getAudit();
        }

        //4.封装结果集
        ArrayList<Histogram> list = new ArrayList<>();
        for (String s : hashMap.keySet()) {
            Integer integer = hashMap.get(s);
            String initTypeByMap = initMapUtil.getInitTypeByMap(s + "0000").replace(":","");
            Histogram histogram = new Histogram();
            histogram.setName(initTypeByMap);
            histogram.setCount(integer);
            list.add(histogram);
        }

        return list;
    }

    /**
     * 根据坐标获取周边网点Id
     * @param topologicalWdAceeptVo
     * @param aroundWdIdList
     * @param wdDistMap 存储 周边网点与中心网点直接的距离
     */
    public void getAroundWdIdList(TopologicalWdAceeptVo topologicalWdAceeptVo,List<String> aroundWdIdList,HashMap<String,Double> wdDistMap){
        //1.根据经纬度 找到 周边网点Id
        // 以经纬度为中心，获取半径不超过最大距离的所有元素
        Point point = new Point(topologicalWdAceeptVo.getLng(),topologicalWdAceeptVo.getLat());

        //半径范围
        Distance distance = new Distance(topologicalWdAceeptVo.getRadius(), RedisGeoCommands.DistanceUnit.METERS);

        //圆
        Circle circle = new Circle(point, distance);
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        geoRadiusCommandArgs.includeDistance(); //添加参数：返回距离
        GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.boundGeoOps(topologicalWdAceeptVo.getAddrCode().substring(0, 4)).radius(circle,geoRadiusCommandArgs);

        //解析周边网点Id
        radius.getContent().stream().forEach(item -> {
            //记录网点坐标及距离
            aroundWdIdList.add((String) item.getContent().getName());
            if (wdDistMap != null)
                wdDistMap.put((String) item.getContent().getName(), item.getDistance().getValue());
        });
    }

}
