package com.tofly.spire.service.impl;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haiqiu.tools.excel.utils.ExcelUtils;
import com.tofly.common.constant.CalendarHelper;
import com.tofly.common.constant.CoordinateTransformationUtils;
import com.tofly.common.core.util.StringUtil;
import com.tofly.scada.entity.Dmatable;
import com.tofly.scada.entity.Scada;
import com.tofly.scada.entity.ScadaMonitor;
import com.tofly.scada.mapper.DmatableMapper;
import com.tofly.scada.service.ScadaMonitorService;
import com.tofly.scada.service.ScadaService;
import com.tofly.spire.common.Constants;
import com.tofly.spire.entity.*;
import com.tofly.spire.entity.dto.SpireBigGridDto;
import com.tofly.spire.mapper.SpireBigGridMapper;
import com.tofly.spire.service.*;
import com.tofly.spire.utils.ResultScada;
import com.tofly.spire.utils.SpireMTLogin;
import com.tofly.spire.utils.SpireUtils;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 大表（管网）(SpireBigGrid)表服务实现类
 *
 * @author HaiQiu
 * @since 2022-11-11 09:16:07
 */
@Slf4j
@Service("spireBigGridService")
public class SpireBigGridServiceImpl extends ServiceImpl<SpireBigGridMapper, SpireBigGrid> implements SpireBigGridService {

    @Autowired
    private SpireUtils spireUtils;



    @Autowired
    private DeviceArchiveManageService deviceArchiveManageService;

    @Autowired
    private IndexAllocationService allocationService;

    @Autowired
    private DmatableMapper dmatableMapper;

    @Autowired
    private SpireBigConfigService spireBigConfigService;

    @Autowired
    private ScadaMonitorService scadaMonitorService;

    @Autowired
    private SpireBigBaseService spireBigBaseService;

    @Autowired
    private  ScadaService scadaService;

    @Autowired
    private SpireMTLogin spireMTLogin;



    /**
     * 多线程同步大表管网数据
     * @param date
     * @param snList
     */
    @Override
    @Async
    public  void  synBulkMeterThread(String date, String snList){


        Date readTime= CalendarHelper.ConvertStrToDate(date,"yyyy-MM-dd");
        List<String> listSn=null;
        if(StringUtil.isNotBlank(snList)){
            listSn=Arrays.asList(snList.split(","));
        }
        List<SpireBigBase> spireBigBaseList = spireBigBaseService.list(Wrappers.<SpireBigBase>lambdaQuery()
                .in(StringUtil.isNotBlank(snList),SpireBigBase::getSn,listSn));

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                6,
                12,
                480,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                (r) -> {
                    Thread t = new Thread(r);
                    t.setName("thread-" + ((int) (Math.random() * 1000)));
                    return t;
                },
                new ThreadPoolExecutor.CallerRunsPolicy());

        Date finalReadTime = readTime;
        spireBigBaseList.forEach(spireBigBase->{
            String token = spireUtils.getToken(spireMTLogin.getAppId(), spireMTLogin.getSecret());
            String sn=spireBigBase.getSn();
            ResultScada bulkMeterData = spireUtils.getBulkMeterData(sn, date, token);
            List<SpireBigGrid> list = JSONObject.parseArray(bulkMeterData.getData().toString(), SpireBigGrid.class);
           if(list!=null && list.size()>0){
            threadPoolExecutor.execute(()->synSpireBigBaseComm(spireMTLogin.getAppId(),list,sn, finalReadTime));
           }
        });


    }

    /**
     * 同步管网数据，根据水表
     * @param appId
     * @param list
     * @param
     */
    @Async
    public  void  synSpireBigBaseComm(String appId,List<SpireBigGrid> list, String sn,Date readTime){
        //基础数据表获取所有的水表，或者根据水表获取水表数据
        List<SpireBigGrid> list_old = super.list(Wrappers.<SpireBigGrid>lambdaQuery()
                .eq(SpireBigGrid::getSn,sn)
                .ge(SpireBigGrid::getReadTime, readTime));

        if (list_old!=null && list_old.size() > 0) {
            //取不同的差集，用于新增数据
            List<SpireBigGrid> list_diff = list.stream().filter(x -> list_old.stream().noneMatch(e -> e.getSn().equals(x.getSn()) && e.getReadTime().equals(x.getReadTime()))).collect(Collectors.toList());
            if (list_diff.size() > 0) {
                //添加
                list_diff.forEach(a -> a.setAppid(appId));
                saveBatch(list_diff,list_diff.size());
            }

        } else {
            list.forEach(a -> a.setAppid(appId));
            saveBatch(list,list.size());
        }

    }


    /**
     * 同步大表管网数据，基础数据
     */
    @Override
    public  void  getBulkMeterBigBaseData(){
        List<SpireBigConfig> list= spireBigConfigService.list(Wrappers.<SpireBigConfig>lambdaQuery()
                .eq(SpireBigConfig::getStatus,1));
        try{
            list.forEach(spireBigConfig-> {
                String appId = spireBigConfig.getAppid();
                String secret = spireBigConfig.getSecret();
                String token = spireUtils.getToken(appId, secret);

                ResultScada bulkMeterBaseData = spireUtils.getBulkMeterData(null, null, token);
                List<SpireBigBase> dataBase = JSONObject.parseArray(bulkMeterBaseData.getData().toString(), SpireBigBase.class);

                List<SpireBigBase> SpireBigBase_Old = spireBigBaseService.list();
                if (dataBase.size() > 0) {
                    dataBase.forEach(base -> {

                        base.setBdLongitude(base.getLongitude());
                        base.setBdLatitude(base.getLatitude());
                        base.setAppid(appId);
                        base.setLatitude(null);
                        base.setLongitude(null);
                        if(StringUtil.isNotEmpty(base.getBdLatitude()) && StringUtil.isNotEmpty(base.getBdLongitude())){
                            double [] maps= CoordinateTransformationUtils.bd09towgs84(Double.parseDouble(base.getBdLongitude()), Double.parseDouble(base.getBdLatitude()));
                            DecimalFormat df = new DecimalFormat("#.000000");
                            base.setLongitude(df.format(maps[0]));
                            base.setLatitude(df.format(maps[1]));
                            deviceArchiveManageService.update(Wrappers.<TfDeviceArchiveManage>lambdaUpdate()
                                    .set(TfDeviceArchiveManage::getLatitude,new BigDecimal(base.getLatitude()))
                                    .set(TfDeviceArchiveManage::getLongitude,new BigDecimal(base.getLongitude()))
                                    .set(TfDeviceArchiveManage::getDeviceType,"3")
                                    .eq(TfDeviceArchiveManage::getCode,base.getSn()));

                        }

                        SpireBigBase spireBigBase = SpireBigBase_Old.stream().filter(a -> a.getSn().equals(base.getSn())).findFirst().orElse(null);
                        if (spireBigBase != null) {
                            base.setId(spireBigBase.getId());
                        }
                    });
                    spireBigBaseService.saveOrUpdateBatch(dataBase);
                }
            });
        } catch(Exception e){

        }
    }


    /**
     * 高德地图坐标转换，同步坐标到设备
     */
    public  void  getMapGdDataNew(){
        List<SpireBigBase> list = spireBigBaseService.list();
        if(list!=null && list.size()>0){

            list.forEach(spireBigBase -> {
                if(StringUtil.isNotEmpty(spireBigBase.getBdLatitude()) && StringUtil.isNotEmpty(spireBigBase.getBdLongitude())){
                    if(StringUtils.isEmpty(spireBigBase.getLatitude()) || StringUtils.isEmpty(spireBigBase.getLongitude())){
                        double [] maps= CoordinateTransformationUtils.bd09towgs84(Double.parseDouble(spireBigBase.getBdLongitude()), Double.parseDouble(spireBigBase.getBdLatitude()));
                        DecimalFormat df = new DecimalFormat("#.000000");
                        spireBigBase.setLongitude(df.format(maps[0]));
                        spireBigBase.setLatitude(df.format(maps[1]));

                        spireBigBaseService.updateById(spireBigBase);
                        deviceArchiveManageService.update(Wrappers.<TfDeviceArchiveManage>lambdaUpdate()
                                .set(TfDeviceArchiveManage::getLatitude,new BigDecimal(spireBigBase.getLatitude()))
                                .set(TfDeviceArchiveManage::getLongitude,new BigDecimal(spireBigBase.getLongitude()))
                                .eq(TfDeviceArchiveManage::getCode,spireBigBase.getSn()));
                    }

                }

            });
        }
    }

    /**
     * 同步设备数据
     */
    @Override
    public void synDeviceArchiveManage() {
        List<SpireBigBase> ListSpireBigBase=spireBigBaseService.list(Wrappers.<SpireBigBase>lambdaQuery()
                .isNotNull(SpireBigBase::getMeterName));
        ListSpireBigBase.forEach(spireBigGrid->{
            Long deviceId=null;
            String deviceType=null;
            //if 原方法判断不需要
            if(StringUtil.isNotEmpty(spireBigGrid.getMeterName())
                    && (
                    spireBigGrid.getMeterName().startsWith("总表-")
                            || spireBigGrid.getMeterName().startsWith("分区-")
                            || spireBigGrid.getMeterName().startsWith("沐浴水库-")
            ))
            {
                deviceType="3";
            }else{
                deviceType="12";

            }


            TfDeviceArchiveManage tfDeviceArchiveManage= deviceArchiveManageService.list(Wrappers.<TfDeviceArchiveManage>lambdaQuery()
                    .eq(TfDeviceArchiveManage::getCode, spireBigGrid.getSn())).stream().findFirst().orElse(null);
            if (tfDeviceArchiveManage ==null) {
               // log.info("正在添加设备添加");
                TfDeviceArchiveManage manage = new TfDeviceArchiveManage();
                manage.setName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()));
                manage.setStatus("1");
                manage.setType("2");
                manage.setDeviceType(deviceType);
                if(StringUtil.isNotEmpty(spireBigGrid.getLongitude())){
                    manage.setLongitude(new BigDecimal(spireBigGrid.getLongitude()));

                }
                if(StringUtil.isNotEmpty(spireBigGrid.getLatitude())){
                    manage.setLatitude(new BigDecimal(spireBigGrid.getLatitude()));

                }
                manage.setCode(spireBigGrid.getSn());
                manage.setCreateTime(new Date());
                deviceArchiveManageService.save(manage);
                deviceId=manage.getId();
                //新增指标
               // log.info("正在添加新增指标");
                saveAllocationsNew(spireBigGrid, manage);

            }else{
                deviceId=tfDeviceArchiveManage.getId();
                tfDeviceArchiveManage.setDeviceType(deviceType);
                deviceArchiveManageService.updateById(tfDeviceArchiveManage);
                saveAllocationsNew(spireBigGrid, tfDeviceArchiveManage);
            }
            if(StringUtil.isNotEmpty(deviceType) && deviceType.equals("3")){

                Integer count= dmatableMapper.selectCount(Wrappers.<Dmatable>lambdaQuery()
                        .eq(Dmatable::getDeviceId,deviceId));
                if(count==0){
                    Dmatable dmatable = new Dmatable(deviceId,0D);
                    dmatable.setDeviceId(deviceId);
                    dmatable.setMinFlow((double)0);
                    dmatable.setUsfl("1");
                    dmatableMapper.insert(dmatable);
                }
            }

        });
    }

    /**
     * 管网数据分发
     */
    @Override
    @Async
    public void synData(){
        Page page=new Page();
        page.setCurrent(1);
        page.setSize(500); //每次取1000条数据进行同步
        long total=0L;
        Page<SpireBigGrid> listPage=super.page(page,Wrappers.<SpireBigGrid>lambdaQuery()
                .eq(SpireBigGrid::getStatus,"0").orderByDesc(SpireBigGrid::getReadTime));
        if(listPage.getTotal()>0){
           // List<SpireBigBase> ListSpireBigBase=spireBigBaseService.list();
            List<SpireBigGrid> spireBigGrids=listPage.getRecords();
            total=spireBigGrids.stream().count();
            for (SpireBigGrid spireBigGrid : spireBigGrids) {
                //新增设备
               /* SpireBigBase spireBigBase=ListSpireBigBase.stream().filter(a->a.getSn().equals(spireBigGrid.getSn())).findFirst().orElse(null);
                if(spireBigBase!=null){
                    spireBigGrid.setMeterName(spireBigBase.getMeterName());
                    spireBigGrid.setLatitude(spireBigBase.getLatitude());
                    spireBigGrid.setLongitude(spireBigBase.getLongitude());
                    spireBigGrid.setMeterType(spireBigBase.getMeterType());
                    spireBigGrid.setMeterStatus(spireBigBase.getMeterStatus());

                }*/

                //新增历史表数据
               // log.info("正在添加新增历史表数据");
                boolean flag= covertGridToScada(spireBigGrid);
                spireBigGrid.setStatus(flag?"1":"2");
                this.updateById(spireBigGrid);

            }
        }

    }

   @Async
   @Override
    public long synDataByDate(Date start,Date end){
        Page page=new Page();
        page.setCurrent(1);
        page.setSize(500); //每次取1000条数据进行同步
        long total=0L;
        Page<SpireBigGrid> listPage=super.page(page,Wrappers.<SpireBigGrid>lambdaQuery()
                .eq(SpireBigGrid::getStatus,"0")
                 .between(SpireBigGrid::getReadTime,start,end)
                .orderByDesc(SpireBigGrid::getReadTime));
        if(listPage.getTotal()>0){
            // List<SpireBigBase> ListSpireBigBase=spireBigBaseService.list();
            List<SpireBigGrid> spireBigGrids=listPage.getRecords();
            total=spireBigGrids.stream().count();
            for (SpireBigGrid spireBigGrid : spireBigGrids) {
                //新增设备
               /* SpireBigBase spireBigBase=ListSpireBigBase.stream().filter(a->a.getSn().equals(spireBigGrid.getSn())).findFirst().orElse(null);
                if(spireBigBase!=null){
                    spireBigGrid.setMeterName(spireBigBase.getMeterName());
                    spireBigGrid.setLatitude(spireBigBase.getLatitude());
                    spireBigGrid.setLongitude(spireBigBase.getLongitude());
                    spireBigGrid.setMeterType(spireBigBase.getMeterType());
                    spireBigGrid.setMeterStatus(spireBigBase.getMeterStatus());

                }*/

                //新增历史表数据
                // log.info("正在添加新增历史表数据");
                boolean flag= covertGridToScada(spireBigGrid);
                spireBigGrid.setStatus(flag?"1":"2");
                this.updateById(spireBigGrid);

            }
        }
        return total;
    }

    /**
     * 管网数据转换成历史数据
     * @param spireBigGrid
     * @return
     */
    public boolean covertGridToScada(SpireBigGrid spireBigGrid) {
        try{
            //新增指标累计量(m³)
            if (StringUtils.hasText(spireBigGrid.getAccFlow())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.accFlow);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                scada.setValue(spireBigGrid.getAccFlow());
                saveScadaAndHistory(scada);

            }
            //新增指标反向累积量 (m³)
            if (StringUtils.hasText(spireBigGrid.getDecAccFlow())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.decAccFlow);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                scada.setValue(spireBigGrid.getDecAccFlow());
                saveScadaAndHistory(scada);
            }
            //新增指标瞬时量 (m³/h)
            if (StringUtils.hasText(spireBigGrid.getFlow())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.flow);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                scada.setValue(spireBigGrid.getFlow());
                saveScadaAndHistory(scada);
            }
            //新增指标进水温度 (℃)
            if (StringUtils.hasText(spireBigGrid.getInTemp())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.inTemp);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                scada.setValue(spireBigGrid.getInTemp());
                saveScadaAndHistory(scada);
            }
            //新增压力值 (kPa），转换成MPa
            if (StringUtils.hasText(spireBigGrid.getPressure())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.pressure);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                Float Pressure=Float.valueOf(spireBigGrid.getPressure())/1000F;
                scada.setValue(Pressure.toString());
                saveScadaAndHistory(scada);
            }
            //新增指标出水温度 (℃)
            if (StringUtils.hasText(spireBigGrid.getTemp())) {
                Scada scada = new Scada();
                scada.setCode(spireBigGrid.getSn() + "." + Constants.temp);
                scada.setScadaTime(spireBigGrid.getReadTime());
                scada.setUpdateTime(new Date());
                scada.setValue(spireBigGrid.getTemp());
                saveScadaAndHistory(scada);
            }
        }catch (Exception ex){
            log.error(ex.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 保存实时数据，历史数据
     * @param scada
     */
    @Async
    public void saveScadaAndHistory(Scada scada){
       String nowData=CalendarHelper.getFormatDate(new Date(),"yyyy-MM-dd");
        Date todayTime=CalendarHelper.ConvertStrToDate(nowData,"yyyy-MM-dd");
        if(scada.getScadaTime().after(todayTime)){
            ScadaMonitor scadaMonitor = new ScadaMonitor();
            BeanUtils.copyProperties(scada, scadaMonitor);
            ScadaMonitor scadaMonitorHistory=scadaMonitorService.list(Wrappers.<ScadaMonitor>lambdaQuery()
                    .eq(ScadaMonitor::getCode,scada.getCode())).stream().findFirst().orElse(null);
            if(scadaMonitorHistory!=null && scadaMonitorHistory.getId()>0){

                scadaMonitor.setId(scadaMonitorHistory.getId());
                //判断日期大小，只保存最新日期的数据
                if(scadaMonitorHistory.getScadaTime().before(scada.getScadaTime())){
                    scadaMonitorService.saveOrUpdate(scadaMonitor);
                }
            }else{
                scadaMonitorService.save(scadaMonitor);
            }
        }

        Scada scadaHistory=scadaService.list(Wrappers.<Scada>lambdaQuery()
                .eq(Scada::getCode,scada.getCode())
                .eq(Scada::getScadaTime,scada.getScadaTime())).stream().findFirst().orElse(null);
        if(scadaHistory==null){
            scadaService.saveOrUpdate(scada);
        }

        }



    /**
     * 保存指标数据
     * @param spireBigGrid
     * @param manage
     */
    private void saveAllocationsNew(SpireBigBase spireBigGrid, TfDeviceArchiveManage manage) {
        //新增指标累计量(m³)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.accFlow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#累计量#" + Constants.accFlow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.accFlow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.accFlow);
            allocation.setUnit("m³");
            allocationService.save(allocation);
        }
        //新增指标反向累积量 (m³)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.decAccFlow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#反向累积量#" + Constants.decAccFlow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.decAccFlow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.decAccFlow);
            allocation.setUnit("m³");
            allocationService.save(allocation);
        }
        //新增指标瞬时量 (m³/h)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.flow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#瞬时量#" + Constants.flow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.flow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.flow);
            allocation.setUnit("m³/h");
            allocationService.save(allocation);
        }
        //新增指标进水温度 (℃)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.inTemp)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#进水温度#" + Constants.inTemp);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.inTemp);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.inTemp);
            allocation.setUnit("℃");
            allocationService.save(allocation);
        }
        //新增压力值 (kPa
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.pressure)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#压力值#" + Constants.pressure);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.pressure);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.pressure);
            allocation.setUnit("kPa");
            allocationService.save(allocation);
        }
        //新增指标出水温度 (℃)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.temp)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#出水温度#" + Constants.temp);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.temp);
            allocation.setVariableCode(spireBigGrid.getSn()+ "." + Constants.temp);
            allocation.setUnit("℃");
            allocationService.save(allocation);
        }
       // log.info("正在添加新增指标-------------------->完成");
    }



    /**
     * 根据ID查询
     *
     * @param id id
     * @return 数据
     */
    @Override
    public SpireBigGrid get(Serializable id) {
        return getById(id);
    }

    /**
     * 新增
     *
     * @param spireBigGridDto 实体
     */
    @Override
    public void insert(SpireBigGridDto spireBigGridDto) {
        SpireBigGrid spireBigGrid = convert(spireBigGridDto);
        if (!save(spireBigGrid)) {
            throw new RuntimeException("新增失败");
        }
    }

    /**
     * 修改
     *
     * @param spireBigGridDto 实体
     */
    @Override
    public void edit(SpireBigGridDto spireBigGridDto) {
        SpireBigGrid spireBigGrid = convert(spireBigGridDto);
        if (!updateById(spireBigGrid)) {
            throw new RuntimeException("修改失败");
        }
    }

    /**
     * 实体转换
     *
     * @param spireBigGridDto dto实体
     */
    private SpireBigGrid convert(SpireBigGridDto spireBigGridDto) {
        SpireBigGrid spireBigGrid = new SpireBigGrid();
        BeanUtils.copyProperties(spireBigGridDto, spireBigGrid);
        return spireBigGrid;
    }

    /**
     * 批量删除
     *
     * @param idList 数据ID集合
     */
    @Override
    public void delete(List<Long> idList) {
        if (!removeByIds(idList)) {
            throw new RuntimeException("删除失败");
        }
    }

    /**
     * 生成模板下载
     */
    @Override
    public void template() {
        SpireBigGrid spireBigGrid = new SpireBigGrid();
        ExcelUtils.createTemplate("大表（管网）", "SpireBigGrid大表（管网）",
                "SpireBigGrid大表（管网）", SpireBigGrid.class, Collections.singletonList(spireBigGrid));
    }

    /**
     * 数据导入
     *
     * @param file 文件
     */
    @Override
    public void importData(MultipartFile file) {
        List<SpireBigGrid> datas = ExcelUtils.getExcelToList("大表（管网）", file, SpireBigGrid.class);
        if (!CollectionUtils.isEmpty(datas)) {
            saveBatch(datas);
        }
    }

    /**
     * 分页查询
     *
     * @param page         分页
     * @param spireBigGrid 查询wrapper
     * @return 数据集合
     */
    @Override
    public Page<SpireBigGrid> pageList(Page page, SpireBigGrid spireBigGrid) {
        return page(page, new QueryWrapper<>(spireBigGrid)).addOrder(page.getOrders());
    }

    /**
     * 数据导出
     *
     * @param page         分页
     * @param spireBigGrid 查询模型
     * @param isAll        是否导出全部数据，true是，false否
     */
    @Override
    public void export(Page page, SpireBigGrid spireBigGrid, Boolean isAll) {
        Page<SpireBigGrid> pageData = new Page<>();
        if (isAll == null || !isAll) {
            pageData = page(page, new QueryWrapper<>(spireBigGrid)).addOrder(page.getOrders());
        } else {
            pageData.setRecords(list(new QueryWrapper<>(spireBigGrid)));
        }
        //导出数据
        ExcelUtils.getListToExcel(SpireBigGrid.class, pageData.getRecords(), "大表（管网）");
    }

    /**
     * 查询所有数据
     *
     * @param spireBigGrid 查询条件
     * @return 查询所有数据
     */
    @Override
    public List<SpireBigGrid> allList(SpireBigGrid spireBigGrid) {
        return list(new QueryWrapper<>(spireBigGrid));
    }


    /**
     * 同步管网数据 最开始方法，不用了
     *
     * @param date  日期 yyyy-mm-dd
     * @param clean 是否清空原始旧数据
     * @param sn    设备sn
     * @return 同步成功条数
     */
  /*  @Override*/
    private long getBulkMeterData(String date, Boolean clean, String sn) {

        ResultScada bulkMeterData = spireUtils.getBulkMeterData(sn, date);
        List<SpireBigGrid> data_Old = JSONObject.parseArray(bulkMeterData.getData().toString(), SpireBigGrid.class);
       List<SpireBigGrid> data=new ArrayList<>();
        if(data_Old!=null && data_Old.size()>0){

            data=data_Old.stream().filter(a->
                    StringUtil.isNotEmpty(a.getMeterName())
                    && (a.getMeterName().startsWith("总表-")
            || a.getMeterName().startsWith("分区-"))
            || a.getMeterName().startsWith("沐浴水库-")).collect(Collectors.toList());
        }

       // log.info("获取到接口数据：{}条", data.size());

        Date getReadTime=null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            getReadTime = sdf.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        //查找库里面大于查询时间的所有数据
        List<SpireBigGrid>  list_old=super.list(Wrappers.<SpireBigGrid>lambdaQuery()
                .ge(SpireBigGrid::getReadTime,getReadTime));

        if(list_old.size()>0){
            //取不同的差集，用于新增数据
            List<SpireBigGrid> list_diff=data.stream().filter(x->list_old.stream().noneMatch(e->e.getSn().equals(x.getSn()) && e.getReadTime().equals(x.getReadTime()))).collect(Collectors.toList());
             if(list_diff.size()>0){
                 //添加
                 saveBatch(list_diff);
             }

        }else{
            saveBatch(data);
        }

        return data.size();
    }

  /* @Override*/
   private  void getBulkMeterDataNew(String date,String sn){
        List<SpireBigConfig> list= spireBigConfigService.list(Wrappers.<SpireBigConfig>lambdaQuery()
                .eq(SpireBigConfig::getStatus,1));

        list.forEach(spireBigConfig->{
            try{
            getBulkMeterDataComm(date,sn,spireBigConfig.getAppid(),spireBigConfig.getSecret());
            }catch (Exception e){

            }
        });

    }


    //高德api接口百度转高德
    private  void  getMapGdData(){
    List<SpireBigBase> list = spireBigBaseService.list(Wrappers.<SpireBigBase>lambdaQuery());
    if(list!=null && list.size()>0){

      list.forEach(spireBigBase -> {
        if(StringUtil.isNotEmpty(spireBigBase.getBdLatitude()) && StringUtil.isNotEmpty(spireBigBase.getBdLongitude())){
            String locations=spireBigBase.getBdLongitude()+","+spireBigBase.getBdLatitude();
            String result=spireUtils.getGdMap(locations,""); //调用高德api地图接口
            if(StringUtil.isNotEmpty(result)){
                DecimalFormat df = new DecimalFormat("#.000000");
                spireBigBase.setLongitude(df.format(Double.parseDouble(result.split(",")[0])));
                spireBigBase.setLatitude(df.format(Double.parseDouble(result.split(",")[1])));

                spireBigBaseService.updateById(spireBigBase);
                deviceArchiveManageService.update(Wrappers.<TfDeviceArchiveManage>lambdaUpdate()
                        .set(TfDeviceArchiveManage::getLatitude,new BigDecimal(spireBigBase.getLatitude()))
                        .set(TfDeviceArchiveManage::getLongitude,new BigDecimal(spireBigBase.getLongitude()))
                        .eq(TfDeviceArchiveManage::getCode,spireBigBase.getSn()));


            }

        }else{

            spireBigBaseService.updateById(spireBigBase);
        }

    });
    }
}



    private int getBulkMeterDataComm(String date, String sn,String appId,String secret) {
        int result=0;
    try {
      String token = spireUtils.getToken(appId, secret);
      ResultScada bulkMeterData = spireUtils.getBulkMeterData(sn, date, token);
      List<SpireBigGrid> data = JSONObject.parseArray(bulkMeterData.getData().toString(), SpireBigGrid.class);
        /*List<SpireBigGrid> data=new ArrayList<>();
        if(data_Old!=null && data_Old.size()>0){
             data=data_Old.stream().filter(a->
                    StringUtil.isNotEmpty(a.getMeterName())
                            && (a.getMeterName().startsWith("总表-")
                            || a.getMeterName().startsWith("分区-"))
                            || a.getMeterName().startsWith("沐浴水库-")).collect(Collectors.toList());
        }*/
     // log.info("获取到接口数据：{}条", data.size());
       result=data.size();
      Date getReadTime = null;
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      try {
          getReadTime = sdf.parse(date);
      } catch (ParseException e) {
          throw new RuntimeException(e);
      }

      //查找库里面大于查询时间的所有数据
      List<SpireBigGrid> list_old = super.list(Wrappers.<SpireBigGrid>lambdaQuery()
              .eq(SpireBigGrid::getAppid, appId)
              .ge(SpireBigGrid::getReadTime, getReadTime));

      if (list_old.size() > 0) {
          //取不同的差集，用于新增数据
          List<SpireBigGrid> list_diff = data.stream().filter(x -> list_old.stream().noneMatch(e -> e.getSn().equals(x.getSn()) && e.getReadTime().equals(x.getReadTime()))).collect(Collectors.toList());
          if (list_diff.size() > 0) {
              //添加
              list_diff.forEach(a -> a.setAppid(appId));
              saveBatch(list_diff);
          }

      } else {
          data.forEach(a -> a.setAppid(appId));
          saveBatch(data);

      }
  }catch (Exception e){

  }
       return result;
}


public  String str(String str){
        if(StringUtils.isEmpty(str)){
            return "";
        }
        return str;
}


    /**
     * 自动新增指标
     *
     * @param spireBigGrid
     * @param manage
     */
    private void saveAllocations(SpireBigGrid spireBigGrid, TfDeviceArchiveManage manage) {
        //新增指标累计量(m³)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.accFlow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#累计量#" + Constants.accFlow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.accFlow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.accFlow);
            allocationService.save(allocation);
        }
        //新增指标反向累积量 (m³)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.decAccFlow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#反向累积量#" + Constants.decAccFlow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.decAccFlow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.decAccFlow);
            allocationService.save(allocation);
        }
        //新增指标瞬时量 (m³/h)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.flow)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#瞬时量#" + Constants.flow);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.flow);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.flow);
            allocationService.save(allocation);
        }
        //新增指标进水温度 (℃)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.inTemp)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#进水温度#" + Constants.inTemp);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.inTemp);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.inTemp);
            allocationService.save(allocation);
        }
        //新增压力值 (kPa
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.pressure)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#压力值#" + Constants.pressure);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.pressure);
            allocation.setVariableCode(spireBigGrid.getSn() + "." + Constants.pressure);
            allocationService.save(allocation);
        }
        //新增指标出水温度 (℃)
        if (allocationService.count(Wrappers.<IndexAllocation>lambdaQuery()
                .eq(IndexAllocation::getVariableCode, spireBigGrid.getSn() + "." + Constants.temp)) == 0) {
            IndexAllocation allocation = new IndexAllocation();
            allocation.setDeviceId(manage.getId());
            allocation.setCreateTime(new Date());
            allocation.setDisplayName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "#出水温度#" + Constants.temp);
            allocation.setVariableName(spireBigGrid.getSn() + str(spireBigGrid.getMeterName()) + "." + Constants.temp);
            allocation.setVariableCode(spireBigGrid.getSn()+ "." + Constants.temp);
            allocationService.save(allocation);
        }
       // log.info("正在添加新增指标-------------------->完成");
    }





}

