package com.ruoyi.ss.meterReadingRecord.service;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.iot.domain.IotDeviceInfo;
import com.ruoyi.iot.service.IotService;
import com.ruoyi.ss.device.domain.DeviceQuery;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.mapper.DeviceMapper;
import com.ruoyi.ss.meterReadingRecord.domain.SmMeterReadingRecord;
import com.ruoyi.ss.meterReadingRecord.domain.SmMeterReadingRecordQuery;
import com.ruoyi.ss.meterReadingRecord.domain.SmMeterReadingRecordVo;
import com.ruoyi.ss.meterReadingRecord.domain.meterReadingRecord.MeterReadingRecordGroupBy;
import com.ruoyi.ss.meterReadingRecord.mapper.SmMeterReadingRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.utils.collection.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 抄记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-03-28
 */
@Service
@Slf4j
public class SmMeterReadingRecordServiceImpl implements ISmMeterReadingRecordService
{
    @Autowired
    private SmMeterReadingRecordMapper smMeterReadingRecordMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private IotService iotService;

    /**
     * 查询抄记录
     *
     * @param recordId 抄记录主键
     * @return 抄记录
     */
    @Override
    public SmMeterReadingRecordVo selectSmMeterReadingRecordByRecordId(Long recordId)
    {
        return smMeterReadingRecordMapper.selectSmMeterReadingRecordByRecordId(recordId);
    }

    /**
     * 查询抄记录列表
     *
     * @param smMeterReadingRecord 抄记录
     * @return 抄记录
     */
    @Override
    public List<SmMeterReadingRecordVo> selectSmMeterReadingRecordList(SmMeterReadingRecordQuery smMeterReadingRecord)
    {
        return smMeterReadingRecordMapper.selectSmMeterReadingRecordList(smMeterReadingRecord);
    }

    /**
     * 新增抄记录
     *
     * @param smMeterReadingRecord 抄记录
     * @return 结果
     */
    @Override
    public int insertSmMeterReadingRecord(SmMeterReadingRecord smMeterReadingRecord)
    {
        smMeterReadingRecord.setCreateTime(DateUtils.getNowDate());
        return smMeterReadingRecordMapper.insertSmMeterReadingRecord(smMeterReadingRecord);
    }

    /**
     * 修改抄记录
     *
     * @param smMeterReadingRecord 抄记录
     * @return 结果
     */
    @Override
    public int updateSmMeterReadingRecord(SmMeterReadingRecord smMeterReadingRecord)
    {
        return smMeterReadingRecordMapper.updateSmMeterReadingRecord(smMeterReadingRecord);
    }

    /**
     * 批量删除抄记录
     *
     * @param recordIds 需要删除的抄记录主键
     * @return 结果
     */
    @Override
    public int deleteSmMeterReadingRecordByRecordIds(Long[] recordIds)
    {
        return smMeterReadingRecordMapper.deleteSmMeterReadingRecordByRecordIds(recordIds);
    }

    /**
     * 删除抄记录信息
     *
     * @param recordId 抄记录主键
     * @return 结果
     */
    @Override
    public int deleteSmMeterReadingRecordByRecordId(Long recordId)
    {
        return smMeterReadingRecordMapper.deleteSmMeterReadingRecordByRecordId(recordId);
    }

    @Override
    public List<SmMeterReadingRecordVo> selectLatest(SmMeterReadingRecordQuery dto) {
        return smMeterReadingRecordMapper.selectLatest(dto);
    }

    @Override
    @Transactional
    public boolean record(List<Long> deviceIds) {
        Date now = new Date();

        // 查询设备列表
        DeviceQuery dto = new DeviceQuery();
        dto.setDeviceIds(deviceIds);
        List<DeviceVO> list = deviceMapper.selectSmDeviceList(dto);
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }

        // 历史最后一次设备抄表记录
        SmMeterReadingRecordQuery recordDto = new SmMeterReadingRecordQuery();
        recordDto.setDeviceIds(deviceIds);
        List<SmMeterReadingRecordVo> recordHistory = this.selectLatest(recordDto);

        List<SmMeterReadingRecord> recordList = new ArrayList<>();  // 抄表记录列表

        // 更新数据
        for (DeviceVO device : list) {
            try {
                if (device == null) {
                    continue;
                }
                IotDeviceInfo deviceInfo = iotService.getDeviceInfo(device);
                SmMeterReadingRecordVo history = recordHistory.stream().filter(item -> Objects.equals(device.getDeviceId(), item.getDeviceId())).findFirst().orElse(null);

                // 抄表记录
                SmMeterReadingRecord record = new SmMeterReadingRecord();
                record.setDeviceId(device.getDeviceId());
                record.setUserId(device.getUserId());
                record.setTotalElectriQuantity(deviceInfo == null ? device.getTotalElectriQuantity() : deviceInfo.getW());
                record.setCreateTime(now);
                if (history == null || history.getTotalElectriQuantity() == null) {
                    record.setUsedElectriQuantity(deviceInfo == null ? device.getTotalElectriQuantity() : deviceInfo.getW());
                } else {
                    record.setUsedElectriQuantity(deviceInfo == null ? device.getTotalElectriQuantity().subtract(history.getTotalElectriQuantity()) : deviceInfo.getW().subtract(history.getTotalElectriQuantity()));
                }
                recordList.add(record);
            } catch (Exception e) {
                log.error("抄表失败，deviceId:{}", device.getDeviceId(), e);
            }
        }

        // 保存到抄表记录
        smMeterReadingRecordMapper.batchInsert(recordList);
        return true;
    }

    @Override
    public List<SmMeterReadingRecordVo> selectCount(SmMeterReadingRecordQuery dto) {
        List<SmMeterReadingRecordVo> list = smMeterReadingRecordMapper.selectCount(dto);

        // 补全中间的日期
        if (dto.getYear() != null && dto.getMonth() != null && MeterReadingRecordGroupBy.create_date.name().equals(dto.getGroupBy())) {
            try {
                list = CollectionUtils.fillElement(list,
                        DateUtils.getMonthFirstDate(dto.getYear(), dto.getMonth()),
                        DateUtils.getMonthLastDate(dto.getYear(), dto.getMonth()),
                        SmMeterReadingRecordVo.class)
                        .stream().map(item -> (SmMeterReadingRecordVo)item).collect(Collectors.toList());
            } catch (Exception e) {
                throw new ServiceException(e.getMessage());
            }
        }

        return list;
    }
}
