package com.zcxk.rmcp.web.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.zcxk.core.common.exception.BusinessException;
import com.zcxk.core.utils.export.EasyExcelUtil;
import com.zcxk.rmcp.api.dto.device.DeviceDataDto;
import com.zcxk.rmcp.api.enums.RmcpErrorEnum;
import com.zcxk.rmcp.api.vo.DeviceDataVo;
import com.zcxk.rmcp.api.vo.MeasuringPointVo;
import com.zcxk.rmcp.api.vo.ProductMeasuringDictVo;
import com.zcxk.rmcp.core.dao.DeviceMapper;
import com.zcxk.rmcp.core.dao.mongo.DeviceDataDao;
import com.zcxk.rmcp.core.entity.Device;
import com.zcxk.rmcp.core.mongo.DeviceData;
import com.zcxk.rmcp.core.mongo.DeviceDataItem;
import com.zcxk.rmcp.web.service.DeviceDataService;
import com.zcxk.rmcp.web.service.ProductMeasuringPointService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 
 * @author Andy
 * @date 2021-07-19 9:44
 */
@Slf4j
@Service
public class DeviceDataServiceImpl implements DeviceDataService {

    @Resource
    private DeviceDataDao deviceDataDao;
    @Resource
    private DeviceMapper deviceMapper;
    @Autowired
    private ProductMeasuringPointService productMeasuringPointService;

    @Override
    public List<DeviceDataVo> getData(DeviceDataDto deviceDataDto) {
        List<DeviceData> list = deviceDataDao.queryDeviceData(deviceDataDto.getDeviceId(),deviceDataDto.getStartDate(),
                deviceDataDto.getEndDate());
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        List<DeviceDataVo> deviceDataDTOList = new ArrayList();
        /*for (DeviceData deviceData : list) {
            if (deviceData.getDatas() == null) {
                continue;
            }
            for (DeviceDataItem data : deviceData.getDatas()) {
                if(!StringUtils.equals(deviceDataDto.getMeasuringCode(),data.getMeasuringCode())){
                    continue;
                }
                DeviceDataVo deviceDataDTO = new DeviceDataVo();
                deviceDataDTO.setValue(data.getMeasuringData());
                deviceDataDTO.setDateTime(deviceData.getReceiveTime());
                deviceDataDTOList.add(deviceDataDTO);
                break;
            }
        }*/

        return deviceDataDTOList;
    }

    public List<DeviceDataItem> getDataItem(DeviceDataDto deviceDataDto){
        return deviceDataDao.queryDeviceDataItem(deviceDataDto.getDeviceId(),deviceDataDto.getStartDate(),
                deviceDataDto.getEndDate());
    }

    /*
     * @description 导出Excel
     * @param deviceDataDto
     * @param httpServletResponse
     * @return
     * @author linqingwei
     **/
    @Override
    public void getDataExcel(DeviceDataDto deviceDataDto, HttpServletResponse httpServletResponse) {
        List<DeviceDataItem> list = deviceDataDao.queryDeviceDataItem(deviceDataDto.getDeviceId(),deviceDataDto.getStartDate(),
                deviceDataDto.getEndDate());

        Device device = deviceMapper.findById(deviceDataDto.getDeviceId());
        List<MeasuringPointVo> measuringList = productMeasuringPointService.getMeasuringPoint(device.getProductId());


        try {

            List<String> head = getHeadList(measuringList);

            List<List<Object>> dataList = new ArrayList<>();
            for (DeviceDataItem deviceDataItem : list) {
                List<Object> item = new ArrayList<>();
                item.add(DateUtil.format(new Date(deviceDataItem.getReceiveTime()), DatePattern.NORM_DATETIME_PATTERN));
                for (MeasuringPointVo vo : measuringList) {
                    item.add(getMeasuringValue(vo,deviceDataItem.getMeasureData()));
                }
                dataList.add(item);
            }


            EasyExcelUtil.excelDynamicWrite(httpServletResponse,"历史数据",head,dataList);
        } catch (Exception e) {
            throw BusinessException.builder(RmcpErrorEnum.RMCP_DOWNLOAD_ERROR);
        }

    }

    /*
     * @description 获取测点值
     * @param vo
     * @param measureData
     * @return
     * @author linqingwei
     **/
    private Object getMeasuringValue(MeasuringPointVo vo, Map<String, Object> measureData) {

        String value = MapUtil.getStr(measureData,vo.getMeasuringCode());
        if (value != null) {
            Optional<ProductMeasuringDictVo> measuringOptional = vo.getDictList().stream().filter(dto -> StringUtils.equals(value,dto.getDataValue())).findFirst();
            if (measuringOptional.isPresent() && StringUtils.equals("1",vo.getMeasuringDataType())) {
                return  measuringOptional.get().getDataName();
            }
        }
        return  value;

    }

    /*
     * @description 获取表头
     * @param measuringList
     * @return
     * @author linqingwei
     **/
    private List<String> getHeadList(List<MeasuringPointVo> measuringList){
        List<String> head = new ArrayList<>();
        head.add("上报时间");
        measuringList.forEach(m -> head.add(m.getMeasuringName()));
        return head;
    }


}
