package com.flossom.miniProgram.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.flossom.common.core.domain.entity.*;
import com.flossom.common.core.domain.req.WxNursingLogReq;
import com.flossom.common.core.domain.ret.WxNursingStatisticsRet;
import com.flossom.common.core.enums.Status;
import com.flossom.common.core.exception.ServiceException;
import com.flossom.common.core.mapper.WxInstrumentMapper;
import com.flossom.common.core.mapper.WxModeMapper;
import com.flossom.common.core.mapper.WxNursingLogMapper;
import com.flossom.common.core.utils.DateUtils;
import com.flossom.common.core.utils.StringUtils;
import com.flossom.common.security.utils.DictUtils;
import com.flossom.common.security.utils.SecurityUtils;
import com.flossom.miniProgram.service.IWxNursingLogService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 用户护理日志Service业务层处理
 *
 * @author flossom
 * @date 2024-01-29
 */
@Service
public class WxNursingLogServiceImpl implements IWxNursingLogService {

    @Autowired
    private WxNursingLogMapper wxNursingLogMapper;

    @Autowired
    private WxInstrumentMapper wxInstrumentMapper;

    @Autowired
    private WxModeMapper wxModeMapper;

    @Override
    public WxNursingStatisticsRet statistics(Long instrumentId) {
        // 排序：最新的护理记录在最上方；图片由后台模式管理-模式封面图片进行配置；
        WxNursingLog queryNursingLog = new WxNursingLog();
        queryNursingLog.setInstrumentId(instrumentId);
        LocalDateTime now = LocalDateTime.now();
        queryNursingLog.getParams().put("beginTime", now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN));
        queryNursingLog.getParams().put("endTime", now.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX));
        List<WxNursingLog> wxNursingLogList = wxNursingLogMapper.selectWxNursingLogList(queryNursingLog);
        if (wxNursingLogList != null && wxNursingLogList.size() > 0) {
            WxNursingStatisticsRet wxNursingStatisticsRet = new WxNursingStatisticsRet();
            Map<LocalDate, Long> collect = wxNursingLogList.stream().collect(
                    Collectors.groupingBy(
                            log -> log.getCreateTime().toInstant()
                                    .atZone(ZoneId.systemDefault()).toLocalDate(), Collectors.counting()
                    )
            );
            wxNursingStatisticsRet.setNursingNum(collect.size());
            Integer totalNursingSecond = 0;
            for (WxNursingLog wxNursingLog : wxNursingLogList) {
                if (wxNursingLog.getNursingTime() != null) {
                    totalNursingSecond += wxNursingLog.getNursingTime().toSecondOfDay();
                }
            }
            wxNursingStatisticsRet.setNursingTime(LocalTime.ofSecondOfDay(totalNursingSecond));
            return wxNursingStatisticsRet;
        }
        return new WxNursingStatisticsRet(0, LocalTime.ofSecondOfDay(0));
    }

    /**
     * 查询用户护理日志列表
     */
    @Override
    public List<WxNursingLog> selectWxNursingLogList(Long instrumentId) {
        // 排序：最新的护理记录在最上方；图片由后台模式管理-模式封面图片进行配置；
        WxNursingLog wxNursingLog = new WxNursingLog();
        if (instrumentId != null) {
            wxNursingLog.setInstrumentId(instrumentId);
        }
        wxNursingLog.setUserId(SecurityUtils.getLoginUser().getWxUserMember().getId());
        List<WxNursingLog> wxNursingLogList = wxNursingLogMapper.selectWxNursingLogList(wxNursingLog);
        if (wxNursingLogList != null && wxNursingLogList.size() > 0) {
            for (WxNursingLog nursingLog : wxNursingLogList) {
                WxMode wxMode = wxModeMapper.selectWxModeById(nursingLog.getModeId());
                if (wxMode != null) {
                    nursingLog.setModeImage(wxMode.getModeBanner());
                }
                WxInstrument wxInstrument = wxInstrumentMapper.selectWxInstrumentById(nursingLog.getInstrumentId());
                if (wxInstrument != null) {
                    nursingLog.setInstrumentType(wxInstrument.getType());
                    nursingLog.setInstrumentName(wxInstrument.getName());
                }
            }
        }
        return wxNursingLogList;
    }

    /**
     * 新增用户护理日志
     */
    @Override
    public void insertWxNursingLog(WxNursingLogReq wxNursingLogReq) {
        /* 查询 同一仪器，同一模式 下，是否有相同的记录，如果有合并护理时间 */
        WxInstrument wxInstrument = wxInstrumentMapper.selectWxInstrumentById(wxNursingLogReq.getInstrumentId());
        if (wxInstrument == null) {
            throw new ServiceException("保存失败");
        }
        WxNursingLog queryNursingLog = new WxNursingLog();
        queryNursingLog.setUserId(SecurityUtils.getLoginUser().getWxUserMember().getId());
        queryNursingLog.setInstrumentId(wxNursingLogReq.getInstrumentId());
        LocalDateTime now = LocalDateTime.now();
        queryNursingLog.getParams().put("beginTime", LocalDateTime.of(now.toLocalDate(), LocalTime.MIN));
        queryNursingLog.getParams().put("endTime", LocalDateTime.of(now.toLocalDate(), LocalTime.MAX));
        List<WxNursingLog> wxNursingLogList = wxNursingLogMapper.selectWxNursingLogList(queryNursingLog);

        if (wxNursingLogList != null && wxNursingLogList.size() > 0) {
            // 存在，修改
            WxNursingLog updateNursingLog = new WxNursingLog();
            WxNursingLog wxNursingLog = wxNursingLogList.get(0);
            // 非IOT仪器没有护理时间
            if (wxNursingLog.getNursingTime() != null) {
                if (wxNursingLogReq.getNursingTime() != null) {
                    updateNursingLog.setNursingTime(wxNursingLog.getNursingTime().plusSeconds(wxNursingLogReq.getNursingTime().toSecondOfDay()));
                }
            } else {
                updateNursingLog.setNursingTime(wxNursingLogReq.getNursingTime());
            }
            LocalTime nursingTime = wxInstrument.getNursingTime();
            if (nursingTime != null) {
                Integer userNursingTime = updateNursingLog.getNursingTime().toSecondOfDay();
                Integer instrumentNursingTime = nursingTime.toSecondOfDay();
                if (userNursingTime != null && userNursingTime > instrumentNursingTime) {
                    updateNursingLog.setCompletionPercentage(1.0);
                } else {
                    if (instrumentNursingTime != null && instrumentNursingTime != 0) {
                        updateNursingLog.setCompletionPercentage(Double.valueOf(userNursingTime) / instrumentNursingTime);
                    }
                }
            }
            updateNursingLog.setId(wxNursingLog.getId());
            updateNursingLog.setUpdateBy(SecurityUtils.getLoginUser().getWxUserMember().getNickname());
            updateNursingLog.setUpdateTime(DateUtils.getNowDate());
            wxNursingLogMapper.updateWxNursingLog(updateNursingLog);
        } else {
            // 不存在，新增
            WxNursingLog wxNursingLog = new WxNursingLog();
            BeanUtils.copyProperties(wxNursingLogReq, wxNursingLog);
            wxNursingLog.setUserId(SecurityUtils.getLoginUser().getWxUserMember().getId());
            // 非IOT仪器没有护理时间
            LocalTime nursingTime = wxInstrument.getNursingTime();
            if (nursingTime != null) {
                Integer instrumentNursingTime = nursingTime.toSecondOfDay();
                Integer userNursingTime = wxNursingLog.getNursingTime().toSecondOfDay();
                if (instrumentNursingTime != null && instrumentNursingTime != 0) {
                    wxNursingLog.setCompletionPercentage(Double.valueOf(userNursingTime) / instrumentNursingTime);
                }
            }
            // 离线状态/在线状态
            Boolean online = true;
            List<SysDictData> nursingOfflineInstrumentModelDict = DictUtils.getDictCache("nursing_offline_instrument_model");
            if (nursingOfflineInstrumentModelDict != null && nursingOfflineInstrumentModelDict.size() > 0) {
                for (SysDictData sysDictData : nursingOfflineInstrumentModelDict) {
                    if (StringUtils.equals(sysDictData.getDictType(), wxInstrument.getModel())) {
                        List<SysDictData> nursingOfflineInstrumentModeDict = DictUtils.getDictCache("nursing_offline_instrument_mode");
                        if (nursingOfflineInstrumentModeDict != null && nursingOfflineInstrumentModeDict.size() > 0) {
                            for (SysDictData dictData : nursingOfflineInstrumentModeDict) {
                                if (StringUtils.equals(dictData.getDictType(), wxNursingLogReq.getModeName())) {
                                    // 离线
                                    online = false;
                                    wxNursingLog.setOnline(2L);
                                }
                            }
                        }
                    }
                }
            }
            if (online) {
                // 在线
                wxNursingLog.setOnline(1L);
            }
            wxNursingLog.setCreateBy(SecurityUtils.getLoginUser().getWxUserMember().getNickname());
            wxNursingLog.setCreateTime(DateUtils.getNowDate());
            wxNursingLog.setUpdateBy(SecurityUtils.getLoginUser().getWxUserMember().getNickname());
            wxNursingLog.setUpdateTime(DateUtils.getNowDate());
            wxNursingLog.setStatus(Status.OK.getCode().longValue());
            wxNursingLogMapper.insertWxNursingLog(wxNursingLog);
        }
    }

}
