package com.fs.watch.service.impl;

import com.fs.common.utils.DateUtils;
import com.fs.common.utils.StringUtils;
import com.fs.watch.domain.WatchContinuousSpo2Data;
import com.fs.watch.domain.WatchSpo2Data;
import com.fs.watch.domain.vo.WatchContinuousSpo2DataQueryVo;
import com.fs.watch.domain.vo.WatchContinuousSpo2DataVo;
import com.fs.watch.domain.vo.WatchSpo2DataQueryVo;
import com.fs.watch.domain.vo.WatchSpo2DataVo;
import com.fs.watch.mapper.WatchSpo2DataMapper;
import com.fs.watch.service.WatchContinuousSpo2DataService;
import com.fs.watch.service.WatchSpo2DataService;
import com.fs.watch.utils.ListConverterUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
* @author Administrator
* @description 针对表【watch_spo2_data(设备血氧数据)】的数据库操作Service实现
* @createDate 2024-10-15 11:06:51
*/
@Service
@Slf4j
public class WatchSpo2DataServiceImpl implements WatchSpo2DataService {
    @Autowired
    private WatchSpo2DataMapper mapper;
    @Autowired
    private WatchContinuousSpo2DataService continuousSpo2DataService;


    @Override
    public Boolean insert(WatchSpo2Data watchSpo2Data) {
        //判断创建时间是否唯一
        Integer num = mapper.queryByCreateTime(watchSpo2Data.getCreateTime());
        if (num != null && num > 0) {
            return false;
        }
        try {
            mapper.insert(watchSpo2Data);
        } catch (Exception e) {
            log.error("===============watchSpo2Data:insert=========================={}", e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public List<WatchSpo2DataVo> queryByDateAndDeviceIdAndState(String date, String deviceId) {
//        return mapper.queryByDateAndDeviceIdAndState(date,deviceId);
        List<WatchContinuousSpo2Data> list = continuousSpo2DataService.queryByDateAndDeviceIdAndState(date, deviceId);
        return getWatchSpo2DataVos(deviceId,list);
    }

    @Override
    public WatchSpo2DataQueryVo querySpByDate(Date startTime, Date endTime, String deviceId) {
        if (StringUtils.isNotBlank(deviceId)) {
//            List<WatchSpo2DataVo> data = mapper.querySpByDate(DateUtils.parseDateToStr(
//                    DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
//                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
//                    deviceId);
            List<WatchContinuousSpo2Data> datas = continuousSpo2DataService.querySpByDate(DateUtils.parseDateToStr(
                    DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
                    deviceId);
            //数据处理
            ArrayList<WatchSpo2DataVo> spo2DataVos = getWatchSpo2DataVos(deviceId, datas);
            WatchSpo2DataQueryVo watchSpo2DataQueryVo = new WatchSpo2DataQueryVo();
            watchSpo2DataQueryVo.setList(spo2DataVos);
            Integer max = 0;
            Integer min = 0;
            double avg = 0.;

            if (spo2DataVos.size()>0){
                max = spo2DataVos.stream().map(WatchSpo2DataVo::getMaxBoxy).max(Integer::compareTo).get();
                min = spo2DataVos.stream().map(WatchSpo2DataVo::getMinBoxy).min(Integer::compareTo).get();
                OptionalDouble  averageValue = spo2DataVos.stream().filter(temp->temp.getAvgBoxy()!=null).mapToDouble(WatchSpo2DataVo::getAvgBoxy)
                        .average();
                // 如果平均值存在，将其转换为 int 类型并输出
                if (averageValue.isPresent()) {
//                    avg = (int) averageValue.getAsDouble();  // 将 double 转换为 int
                    avg = averageValue.getAsDouble();  // 将 double 转换为 int
                    avg = Math.round(avg * 100.0) / 100.0;
                }
            }

            watchSpo2DataQueryVo.setMax(max);
            watchSpo2DataQueryVo.setMin(min);
            watchSpo2DataQueryVo.setAvg(avg);
            return watchSpo2DataQueryVo;
        }
        return null;
    }

    private @NotNull ArrayList<WatchSpo2DataVo> getWatchSpo2DataVos(String deviceId, List<WatchContinuousSpo2Data> datas) {
        ArrayList<WatchSpo2DataVo> spo2DataVos = new ArrayList<>();
        for (WatchContinuousSpo2Data data : datas) {
            WatchSpo2DataVo spo2DataVo = new WatchSpo2DataVo();
            //转list
//            List<Integer> spo2s = ListConverterUtils.convertStringToIntegerList(data.getJsonDataSpo2());
//            List<Integer> touch = ListConverterUtils.convertStringToIntegerList(data.getJsonDataTouch());
            List<Integer> spo2s = data.getSpo2();
            List<Integer> touch = data.getTouch();
            if (spo2s.size() == touch.size() && !spo2s.isEmpty()) {
                Integer max = spo2s.get(0);
                Integer min = spo2s.get(0);
                int count = 0;
                int sum = 0;
                for (int i = 0; i < touch.size(); i++) {
                    if (touch.get(i) != 0) {
                        Integer spo2 = spo2s.get(i);
                        count++;
                        sum += spo2;
                        if (max<spo2){
                            max = spo2;
                        }
                        if (min>spo2){
                            min = spo2;
                        }
                    }
                }
//                spo2DataVo.setId(UUID.fromString(data.getId()));
                if (min == 0 && max == 0){
                    continue;
                }
                spo2DataVo.setId(data.getId());
                spo2DataVo.setDeviceId(deviceId);
                spo2DataVo.setMaxBoxy(max);
                spo2DataVo.setMinBoxy(min);
                // 保留两位小数的平均值
                double avgBoxy = (double) sum / count;
                avgBoxy = Math.round(avgBoxy * 100.0) / 100.0;
                spo2DataVo.setAvgBoxy(avgBoxy);
                spo2DataVo.setStatus(getStatus(max,min));
//                spo2DataVo.setCreateTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
                spo2DataVo.setCreateTime(data.getCreateTime());
                spo2DataVos.add(spo2DataVo);
            }
        }
        return spo2DataVos;
    }

    @Override
    public Integer getStatus(int maxOxy, int minOxy) {
        if (maxOxy < 95) {
            return 1; //过低
        }
        if (minOxy > 100) {
            return 2; //过高
        }
        return 0; //正常
    }

    @Override
    public List<Map<String, Integer>> countSpByDate(Date startTime, Date endTime, String deviceId) {
        if (StringUtils.isBlank(deviceId)) {
            return null;
        }
//        res = mapper.countSpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
//                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
        List<WatchContinuousSpo2Data> list = continuousSpo2DataService.querySpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
        if (list != null && list.size() > 0) {
            return getStatusCount(list);
        }
        return null;
    }

    private List<Map<String, Integer>> getStatusCount(List<WatchContinuousSpo2Data> list) {

        List<Map<String, Integer>> res = new ArrayList<>();
        Integer count0 = 0;
        Integer count1 = 0;
        Integer count2 = 0;

        for (WatchContinuousSpo2Data data : list) {
            //转list
//            List<Integer> spo2s = ListConverterUtils.convertStringToIntegerList(data.getJsonDataSpo2());
//            List<Integer> touch = ListConverterUtils.convertStringToIntegerList(data.getJsonDataTouch());
            List<Integer> spo2s = data.getSpo2();
            List<Integer> touch = data.getTouch();
            if (spo2s.size() == touch.size() && !spo2s.isEmpty()) {
                Integer max = spo2s.get(0);
                Integer min = spo2s.get(0);
                for (int i = 0; i < touch.size(); i++) {
                    if (touch.get(i) != 0) {
                        Integer spo2 = spo2s.get(i);
                        if (max<spo2){
                            max = spo2;
                        }
                        if (min>spo2){
                            min = spo2;
                        }
                    }
                }
                Integer status = getStatus(max, min);
                switch (status) {
                    case 0:
                        count0++;
                        break;
                    case 1:
                        count1++;
                        break;
                    case 2:
                        count2++;
                        break;
                    default:
                        break;
                }
            }
        }
        if (count0>0){
            HashMap<String,Integer> map = new HashMap<>();
            map.put("status",0);
            map.put("count",count0);
            res.add(map);
        }
        if (count1>0){
            HashMap<String,Integer> map = new HashMap<>();
            map.put("status",1);
            map.put("count",count1);
            res.add(map);
        }
        if (count2>0){
            HashMap<String,Integer> map = new HashMap<>();
            map.put("status",2);
            map.put("count",count2);
            res.add(map);
        }
        return res;
    }

    @Override
    public WatchContinuousSpo2Data getLatest(String deviceId) {
//        return mapper.getLatest(deviceId);
        return continuousSpo2DataService.getLatest(deviceId);

    }

    @Override
    public int countSpPageByDate(Date startTime, Date endTime, String deviceId) {
//        return mapper.countSpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
//                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
//                deviceId);
        return continuousSpo2DataService.countSpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
                deviceId);
    }

    @Override
    public List<WatchSpo2DataVo> querySpPageByDate(Date startTime, Date endTime, String deviceId, Integer num, Integer size) {
        if (StringUtils.isNotBlank(deviceId)) {
//            return mapper.querySpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
//                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
//                    deviceId,num,size);
            List<WatchContinuousSpo2Data> continuousSpo2DataVos = continuousSpo2DataService.querySpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
                    deviceId, num, size);
            //数据处理
            ArrayList<WatchSpo2DataVo> spo2DataVos = getWatchSpo2DataVos(deviceId, continuousSpo2DataVos);
            return spo2DataVos;
        } else {
            return null;
        }
    }
}
