package com.tofly.water.service.impl;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.haiqiu.tools.excel.utils.ExcelUtils;
import com.tofly.common.core.util.DateUtil;
import com.tofly.scada.entity.Allocation;
import com.tofly.scada.entity.Scada;
import com.tofly.scada.mapper.ScadaMapper;
import com.tofly.scada.service.AllocationService;
import com.tofly.water.entity.dto.StatisticsRealDto;
import com.tofly.water.entity.vo.StatisticsPumpRunTimeVo;
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.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.CollectionUtils;
import org.springframework.beans.BeanUtils;
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 com.tofly.water.mapper.ScadaStatusDurationMapper;
import com.tofly.water.entity.ScadaStatusDuration;
import com.tofly.water.entity.dto.ScadaStatusDurationDto;
import com.tofly.water.service.ScadaStatusDurationService;
import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.io.Serializable;
import java.util.stream.Collectors;

/**
 * 记录设备运行时长状态(ScadaStatusDuration)表服务实现类
 *
 * @author HaiQiu
 * @since 2022-12-26 16:37:24
 */
@Service("scadaStatusDurationService")
@Slf4j
public class ScadaStatusDurationServiceImpl extends ServiceImpl<ScadaStatusDurationMapper, ScadaStatusDuration> implements ScadaStatusDurationService {


    @Autowired
    private ScadaMapper scadaMapper;

    @Autowired
    private AllocationService allocationService;

    @Value("${scada.runTimeType:13}")
    private String runTimeType;

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


    /**
     * 新增
     *
     * @param scadaStatusDurationDto 实体
     */
    @Override
    public void insert(ScadaStatusDurationDto scadaStatusDurationDto) {
        ScadaStatusDuration scadaStatusDuration = convert(scadaStatusDurationDto);
        if (!save(scadaStatusDuration)) {
            throw new RuntimeException("新增失败");
        }
    }

    /**
     * 修改
     *
     * @param scadaStatusDurationDto 实体
     */
    @Override
    public void edit(ScadaStatusDurationDto scadaStatusDurationDto) {
        ScadaStatusDuration scadaStatusDuration = convert(scadaStatusDurationDto);
        if (!updateById(scadaStatusDuration)) {
            throw new RuntimeException("修改失败");
        }
    }

    /**
     * 实体转换
     *
     * @param scadaStatusDurationDto dto实体
     */
    private ScadaStatusDuration convert(ScadaStatusDurationDto scadaStatusDurationDto) {
        ScadaStatusDuration scadaStatusDuration = new ScadaStatusDuration();
        BeanUtils.copyProperties(scadaStatusDurationDto, scadaStatusDuration);
        return scadaStatusDuration;
    }

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

    /**
     * 生成模板下载
     */
    @Override
    public void template() {
        ScadaStatusDuration scadaStatusDuration = new ScadaStatusDuration();
        ExcelUtils.createTemplate("记录设备运行时长状态", "记录设备运行时长状态",
                "记录设备运行时长状态", ScadaStatusDuration.class, Collections.singletonList(scadaStatusDuration));
    }

    /**
     * 数据导入
     *
     * @param file 文件
     */
    @Override
    public void importData(MultipartFile file) {
        List<ScadaStatusDuration> excelToList = ExcelUtils.getExcelToList("记录设备运行时长状态", file, ScadaStatusDuration.class);
        if (CollectionUtils.isEmpty(excelToList)) {
            throw new RuntimeException("数据解析为空");
        }
        saveBatch(excelToList);
    }

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

    /**
     * 数据导出
     *
     * @param page                分页
     * @param scadaStatusDuration 查询模型
     * @param isAll               是否导出全部数据，true是，false否（默认否）
     */
    @Override
    public void export(Page page, ScadaStatusDuration scadaStatusDuration, boolean isAll) {
        Page<ScadaStatusDuration> pageData = new Page<>();
        if (!isAll) {
            pageData = page(page, new QueryWrapper<>(scadaStatusDuration)).addOrder(page.getOrders());
        } else {
            pageData.setRecords(list(new QueryWrapper<>(scadaStatusDuration)));
        }
        //导出数据
        ExcelUtils.getListToExcel(ScadaStatusDuration.class, pageData.getRecords(), "记录设备运行时长状态");
    }

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

    @Override
    public void timingInsertData(Date start, Date end) {
        // 获取指标code
        List<Allocation> allocations = allocationService.list(Wrappers.<Allocation>lambdaQuery()
                .eq(Allocation::getType, runTimeType));
        if (CollectionUtils.isEmpty(allocations)) {
            return;
        }
        List<String> codes = allocations.stream().map(Allocation::getVariableCode).collect(Collectors.toList());
        List<Scada> scadas = scadaMapper.selectList(new QueryWrapper<Scada>().lambda()
                .between(Scada::getUpdateTime, start, end)
                .in(Scada::getCode, codes));
        log.info("时间{}-----{}----->查询每5分钟定时任务运行时长实时数据{}", start, end, scadas);
        if (CollectionUtils.isEmpty(scadas)) {
            return;
        }
        List<ScadaStatusDuration> scadaStatusDurations = new ArrayList<>();
        for (Scada scada : scadas) {
            Page<ScadaStatusDuration> page = page(new Page<>(1, 1), Wrappers.<ScadaStatusDuration>lambdaQuery()
                    .eq(ScadaStatusDuration::getCode, scada.getCode())
                    .orderByDesc(ScadaStatusDuration::getScadaTime));
            List<ScadaStatusDuration> records = page.getRecords();
//            if (CollectionUtils.isEmpty(records) && (scada.getValue().equals("1") || scada.getValue().equals("0"))) {
            if (CollectionUtils.isEmpty(records)) {
                ScadaStatusDuration duration = new ScadaStatusDuration();
                duration.setTotal("0");
                duration.setRunTime("0");
                BeanUtils.copyProperties(scada, duration);
                save(duration);
            } else if (!CollectionUtils.isEmpty(records)) {
                ScadaStatusDuration statusDuration = records.get(0);
                long runTime = Long.parseLong(statusDuration.getRunTime());
                long total = Long.parseLong(statusDuration.getTotal());
//                if (statusDuration.getValue().equals("1") && scada.getValue().equals(statusDuration.getValue())) {
                if (scada.getValue().equals(statusDuration.getValue())) {
                    long s = statusDuration.getScadaTime().getTime();
                    long e = scada.getScadaTime().getTime();
                    long d = (e - s) / 1000;
                    long sum = d + runTime;
                    long t = d + total;
                    statusDuration.setRunTime(String.valueOf(sum));
                    statusDuration.setTotal(String.valueOf(t));
                    scadaStatusDurations.add(statusDuration);
//                } else if (scada.getValue().equals("0") && !scada.getValue().equals(statusDuration.getValue())) {
                } else if (!scada.getValue().equals(statusDuration.getValue())) {
                    long s = statusDuration.getScadaTime().getTime();
                    long e = scada.getScadaTime().getTime();
                    long d = (e - s) / 1000;
                    long sum = d + runTime;
                    long t = d + total;
                    statusDuration.setRunTime(String.valueOf(sum));
                    statusDuration.setTotal(String.valueOf(t));
                    scadaStatusDurations.add(statusDuration);
//                } else if (statusDuration.getValue().equals("0") && !scada.getValue().equals(statusDuration.getValue())) {
                } else if (!scada.getValue().equals(statusDuration.getValue())) {
                    ScadaStatusDuration duration = new ScadaStatusDuration();
                    duration.setTotal("0");
                    duration.setRunTime("0");
                    BeanUtils.copyProperties(scada, duration);
                    scadaStatusDurations.add(duration);
                }
            }
        }
        saveOrUpdateBatch(scadaStatusDurations);
    }

    /**
     * 定时任务，每分钟1执行一次
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void timingInsertData() {
//    @XxlJob("getScadaRuntime")
//    public ReturnT getScadaRuntime(String params) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        Date end = calendar.getTime();
        calendar.add(Calendar.MINUTE, -5);
        Date start = calendar.getTime();
        timingInsertData(start, end);
//        return ReturnT.SUCCESS;
    }


    @Override
    public Object statisticsReal(Page page, StatisticsRealDto dto) {
        //如果查询的是泵站
        List<StatisticsPumpRunTimeVo> timeVos = baseMapper.statisticsPumpReal(dto);
        if (CollectionUtils.isEmpty(timeVos)){
            return null;
        }
        Map<String, List<StatisticsPumpRunTimeVo>> collect = timeVos.stream()
                .filter(statisticsPumpRunTimeVo -> statisticsPumpRunTimeVo.getScadaTime()!=null)
                .collect(Collectors.groupingBy(o-> DateUtil.getDateFormat(o.getScadaTime(),"yyyy-MM-dd HH:mm:ss")));

        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Map.Entry<String, List<StatisticsPumpRunTimeVo>> entry : collect.entrySet()) {
            Map<String, Object> resultMap = new HashMap<>();
            List<StatisticsPumpRunTimeVo> value = entry.getValue();
            if (!CollectionUtils.isEmpty(value)){
                long sum = 0;
                for (StatisticsPumpRunTimeVo vo : value) {
                    sum = sum + Long.parseLong(vo.getRunTime());
                }
                resultMap.put("runTime",sum);
            }
            resultMap.put("details",value);
            mapList.add(resultMap);
        }
     return mapList;
    }
}

