package com.sunwin.robot2ips.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sunwin.robot2ips.beans.dto.CheckDataDTO;
import com.sunwin.robot2ips.beans.dto.IPSPointDTO;
import com.sunwin.robot2ips.beans.dto.RobotDTO;
import com.sunwin.robot2ips.beans.vo.IPSResp;
import com.sunwin.robot2ips.beans.vo.RecordData;
import com.sunwin.robot2ips.beans.vo.RecordTaskPoint;
import com.sunwin.robot2ips.common.RedisKey;
import com.sunwin.robot2ips.dao.UploadMapper;
import com.sunwin.robot2ips.service.CheckDataService;
import com.sunwin.robot2ips.util.DateUtil;
import com.sunwin.robot2ips.util.ExcelUtil;
import com.sunwin.robot2ips.util.HttpUtils;
import com.sunwin.robot2ips.util.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class CheckDataServiceImpl implements CheckDataService {
    private static final Logger logger = LoggerFactory.getLogger(CheckDataServiceImpl.class);

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    UploadMapper uploadMapper;

    @Value("${ips.connect.url}")
    private String url;

    @Value("${ips.point.fileName}")
    private String fileName;
    @Value("${ips.query.count}")
    private Integer count;

    /**
     * 查询巡检数据并上传至IPS系统
     *
     * @param
     * @return void
     * @author machao
     * @date 2022/6/6 17:06
     **/
    @Override
    public void uploadCheckData() {
        //获取机器人信息
        List<RobotDTO> robots = uploadMapper.selectRobots();
        if (CollectionUtils.isEmpty(robots)) {
            logger.info("threadName={} robot list is null skip this sync", Thread.currentThread().getName());
            return;
        }
        Map<Integer, List<RobotDTO>> robotMap = robots.stream().collect(Collectors.groupingBy(RobotDTO::getId));
        //从redis中获取最新一次上传id (若为首次上传 查询当前最近的30条记录上传)
        Long lastDataId = (Long) redisUtils.get(RedisKey.UPLOAD_IPS_LAST_ID);
        logger.info(" last data id ={} ", lastDataId);

        //根据lastDataId查询基于上次上传后的30条巡检数据
        List<RecordTaskPoint> checkDataList = uploadMapper.queryDataAfterId(lastDataId,count);
        if (CollectionUtils.isEmpty(checkDataList)) {
            logger.info("no new data ");
            return;
        }
        //获取当前时间并更新redis最近上传的最新id(若上传失败则回滚!)
        redisUtils.set(RedisKey.UPLOAD_IPS_LAST_ID, Long.valueOf(checkDataList.get(0).getResultId()));
        //将巡检数据按照robotId分组
        Map<Integer, List<RecordTaskPoint>> robotCheckData = checkDataList.stream().collect(Collectors.groupingBy(RecordTaskPoint::getRobotId));
        //初始化上传集合
        List<RecordData> uploadResult = new ArrayList<>();
        //根据机器人拆分巡检数据
        for (Integer key : robotCheckData.keySet()) {
            List<RobotDTO> robot = robotMap.get(key);
            if (CollectionUtils.isEmpty(robot)) {
                continue;
            }
            RobotDTO robotDTO = robot.get(0);
            RecordData recordData = new RecordData();
            recordData.setRobotCode(robotDTO.getId().toString());
            recordData.setRobotName(robotDTO.getRobotName());
            //获取机器人对应的巡检数据进行组装
            List<RecordTaskPoint> checkDataArray = robotCheckData.get(key);
            //初始化集合
            List<RecordTaskPoint> recordTaskPoints = new ArrayList<>();
            //遍历设置时间
            for (RecordTaskPoint recordTaskPoint : checkDataArray) {
                //取巡检数据的巡检时间的年月日作为任务日期
                String yyyyMMdd = DateUtil.parseToString(recordTaskPoint.getUpdateTime(), DateUtil.DateFormat_yyyy_MM_dd);
                Date start = DateUtil.strToDate(yyyyMMdd + " 00:00:00");
                Date end = DateUtil.strToDate(yyyyMMdd + " 23:59:59");
                //任务时间写死识别日期的00：00-23：59
                recordTaskPoint.setRecordPlanStartDate(start);
                recordTaskPoint.setRecordCompleteDate(end);
                recordTaskPoint.setRecordPlanCompleteDate(end);
                recordTaskPoint.setRecordStartDate(start);
                recordTaskPoints.add(recordTaskPoint);
            }
            recordData.setRecordTaskPoints(recordTaskPoints);
            uploadResult.add(recordData);
        }
        //初始化失败的最小id 集合
        ArrayList<Long> minIds = new ArrayList<>();
        //根据机器人拆分组装后遍历上传
        for (RecordData recordData : uploadResult) {
            //HttpPost
            String resp = HttpUtils.HttpPostWithJson(url, JSONObject.toJSONString(recordData));
            //上传成功
            if (!StringUtils.isEmpty(resp)) {
                IPSResp ipsResp = JSONObject.parseObject(resp, IPSResp.class);
                if (ipsResp.getIsSuccessed().equals("1")) {
                    continue;
                }
            }
            //失败即全部重新上传
            redisUtils.set(RedisKey.UPLOAD_IPS_LAST_ID, lastDataId);
        }

    }


    /**
     * 绑定IPS与机器人巡检点关系
     *
     * @param
     * @return void
     * @author machao
     * @date 2022/6/8 9:13
     **/
    @Override
    public void bindIPSAndRobotPoint() {
        String absolutePath = new File("").getAbsolutePath() + "\\" + fileName;
        File file = new File(absolutePath);
        InputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            List<IPSPointDTO> importList = (List<IPSPointDTO>) ExcelUtil.read(fileInputStream, IPSPointDTO.class, file.getName());
            if (CollectionUtils.isEmpty(importList)) {
                return;
            }
            Iterator<IPSPointDTO> iterator = importList.iterator();
            while (iterator.hasNext()) {
                IPSPointDTO next = iterator.next();
                if (next.getPointId() == null) {
                    iterator.remove();
                }
            }
            //入库
            uploadMapper.insertBindLink(importList);
        } catch (Exception e) {
            logger.error("bind link error msg={}", e.getMessage());
        }
    }

}
