package com.rongwei.bscommon.sys.service.impl;


import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.bscommon.sys.dao.EquGdyRecordDao;
import com.rongwei.bscommon.sys.service.EquGdyRecordService;
import com.rongwei.bsentity.domain.EquGdyMeterDo;
import com.rongwei.bsentity.domain.EquGdyRecordDo;
import com.rongwei.rwcommon.base.BaseDo;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.base.exception.CustomException;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.safecommon.utils.CXCommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 *
 */
@Service
public class EquGdyRecordServiceImpl extends ServiceImpl<EquGdyRecordDao, EquGdyRecordDo>
        implements EquGdyRecordService {
    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
    @Autowired
    private EquGdyMeterServiceImpl equGdyMeterService;

    @Override
    public R generateDailyRecords() {
        log.info("开始生产当天的高低压记录");
        List<EquGdyMeterDo> gdyMeterDoList = equGdyMeterService.list(new LambdaQueryWrapper<EquGdyMeterDo>()
                .eq(BaseDo::getDeleted, "0")
                .eq(EquGdyMeterDo::getStatus, "enable"));
        if (gdyMeterDoList.isEmpty()) {
            log.error("无法获取到用表记录信息");
            return R.error("无法获取到用表记录信息");
        }
        List<EquGdyRecordDo> equGdyRecordDos = new ArrayList<>();
        Calendar instance = Calendar.getInstance();
        Date now = instance.getTime();
        EquGdyRecordDo equGdyRecordDo;
        for (EquGdyMeterDo equGdyMeterDo : gdyMeterDoList) {
            equGdyRecordDo = new EquGdyRecordDo();
            equGdyRecordDo.setId(SecurityUtil.getUUID());
            equGdyRecordDo.setEnergytype(equGdyMeterDo.getEnergytype());
            equGdyRecordDo.setMeterid(equGdyMeterDo.getId());
            equGdyRecordDo.setMetername(equGdyMeterDo.getMetername());
            equGdyRecordDo.setMetercode(equGdyMeterDo.getMetercode());
            equGdyRecordDo.setCbdate(now);
            equGdyRecordDo.setUsedeptid(equGdyMeterDo.getUsedeptid());
            equGdyRecordDo.setCreatedate(now);
            equGdyRecordDo.setModifydate(now);
            equGdyRecordDo.setTenantid(equGdyMeterDo.getTenantid());
            equGdyRecordDo.setMeterlocation(equGdyMeterDo.getMeterlocation());
            equGdyRecordDo.setYear(instance.get(Calendar.YEAR));
            equGdyRecordDo.setMonth(instance.get(Calendar.MONTH) + 1);
            equGdyRecordDo.setDay(instance.get(Calendar.DAY_OF_MONTH));
            equGdyRecordDos.add(equGdyRecordDo);
        }
        this.saveBatch(equGdyRecordDos, 100);
        return R.ok();
    }

    @Override
    public R saveData(EquGdyRecordDo currentData) {
        if (StringUtils.isBlank(currentData.getId())) {
            return R.error("数据异常");
        }
        // 获取表具信息
        EquGdyMeterDo gdyMeterDo = this.equGdyMeterService.getById(currentData.getMeterid());

        //计算 夜班用量= 当前的夜班抄表-前一天的中班抄表
        if (currentData.getValuenight() != null) {
            // 获取上一天的数据
            EquGdyRecordDo previousData = dataFromTheDayBefore(currentData, -1);
            if (previousData != null && previousData.getValuemiddle() != null) {
                //当前数据-前一天的中班用量
                currentData.setValuenightuse((currentData.getValuenight().subtract(previousData.getValuemiddle())).multiply(gdyMeterDo.getDbbb()));
            }
        }
        // 计算 早班用量 =当前的早班抄表-当前的夜班抄表
        if (currentData.getValuemorning() != null && currentData.getValuenight() != null) {
            currentData.setValuemorninguse((currentData.getValuemorning().subtract(currentData.getValuenight())).multiply(gdyMeterDo.getDbbb()));
        }
        // 计算 中班用量 = 当前的中班抄表-当前的早班抄表
        if (currentData.getValuemiddle() != null) {
            // 中班用量 = 当前的中班抄表-当前的早班抄表
            if (currentData.getValuemorning() != null) {
                currentData.setValuemiddleuse((currentData.getValuemiddle().subtract(currentData.getValuemorning())).multiply(gdyMeterDo.getDbbb()));
            }
            // 更新下一天的夜班用量 = 下一天的夜班抄表-当前的中班抄表
            EquGdyRecordDo nextData = dataFromTheDayBefore(currentData, 1);
            if (nextData != null && nextData.getValuenight() != null) {
                nextData.setValuenightuse((nextData.getValuenight().subtract(currentData.getValuemiddle()).multiply(gdyMeterDo.getDbbb())));
                this.updateById(nextData);
            }
        }
        this.updateById(currentData);
        return R.ok(currentData);
    }

    @Override
    public R generateByDate(Date startDate, Date endDate) {
        String currentUserFactoryId = CXCommonUtils.getCurrentUserFactoryId(null);
        // 获取所有的表具信息
        List<EquGdyMeterDo> gdyMeterDoList = equGdyMeterService.list(new LambdaQueryWrapper<EquGdyMeterDo>()
                .eq(BaseDo::getDeleted, "0")
                .eq(EquGdyMeterDo::getStatus, "enable")
                .eq(EquGdyMeterDo::getTenantid, currentUserFactoryId));
        Calendar startInstance = Calendar.getInstance();
        startInstance.setTime(startDate);
        Calendar endInstance = Calendar.getInstance();
        endInstance.setTime(endDate);
        Date now = new Date();
        List<EquGdyRecordDo> saveData = new ArrayList<>();
        while (startInstance.compareTo(endInstance)<=0) {
            // 获取当天的数据
            List<String> meteridList = this.getBaseMapper().getMeteridByDate(startInstance.getTime(), currentUserFactoryId);
            // 获取没有生成数量的表具信息
            List<EquGdyRecordDo> collect = gdyMeterDoList.stream().filter(data -> !meteridList.contains(data.getId()))
                    .map(info -> {
                                EquGdyRecordDo equGdyRecordDo = new EquGdyRecordDo();
                                equGdyRecordDo.setId(SecurityUtil.getUUID());
                                equGdyRecordDo.setEnergytype(info.getEnergytype());
                                equGdyRecordDo.setMeterid(info.getId());
                                equGdyRecordDo.setMetername(info.getMetername());
                                equGdyRecordDo.setMetercode(info.getMetercode());
                                equGdyRecordDo.setCbdate(startInstance.getTime());
                                equGdyRecordDo.setUsedeptid(info.getUsedeptid());
                                equGdyRecordDo.setCreatedate(now);
                                equGdyRecordDo.setModifydate(now);
                                equGdyRecordDo.setTenantid(info.getTenantid());
                                equGdyRecordDo.setMeterlocation(info.getMeterlocation());
                                equGdyRecordDo.setYear(startInstance.get(Calendar.YEAR));
                                equGdyRecordDo.setMonth(startInstance.get(Calendar.MONTH) + 1);
                                equGdyRecordDo.setDay(startInstance.get(Calendar.DAY_OF_MONTH));
                                return equGdyRecordDo;
                            }
                    ).collect(Collectors.toList());
            saveData.addAll(collect);
            startInstance.add(Calendar.DATE, 1);
        }
        if (!saveData.isEmpty()) {
            this.saveBatch(saveData, 100);
        }
        return R.ok();
    }

    public EquGdyRecordDo dataFromTheDayBefore(EquGdyRecordDo equGdyRecordDo, int changeDay) {
        Date cbdate = equGdyRecordDo.getCbdate();
        if (cbdate == null) {
            log.error("当前抄表日期为空,无法计算夜班用量");
            throw new CustomException("当前抄表日期为空,无法计算夜班用量");
        }
        Calendar instance = Calendar.getInstance();
        instance.setTime(cbdate);
        instance.add(Calendar.DATE, changeDay);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        return this.getOne(new LambdaQueryWrapper<EquGdyRecordDo>()
                .eq(BaseDo::getDeleted, "0")
                .eq(EquGdyRecordDo::getCbdate, dateFormat.format(instance.getTime()))
                .eq(EquGdyRecordDo::getMeterid, equGdyRecordDo.getMeterid()), false);
    }
}




