package com.huatek.busi.service.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.dubbo.config.annotation.Service;
import com.google.common.collect.Maps;
import com.huatek.busi.common.util.DateUtil;
import com.huatek.busi.common.util.DecimalUtil;
import com.huatek.busi.dao.FailureRateDao;
import com.huatek.busi.entity.FailureRate;
import com.huatek.busi.mapper.FailureRateMapper;
import com.huatek.busi.service.FailureRateService;
import com.huatek.busi.util.CalcUtil;
import com.huatek.busi.vo.BusiSensorVo;

/**
 * 数据缺失率 ServiceImpl
 *
 * @author anker_cheng
 * @date Jul 15, 2019 3:43:34 PM
 */
@Component
@Service(interfaceClass = FailureRateService.class)
@Transactional(rollbackFor = Exception.class)
public class FailureRateServiceImpl implements FailureRateService {

    @Autowired
    private FailureRateMapper failureRateMapper;
    @Autowired
    private FailureRateDao failureRateDao;

    @Override
    public synchronized void saveSensorFailureRate(BusiSensorVo sensor, LocalDate date, BigDecimal uploadCycle, Integer dataCount) {
        FailureRate failureRate =
            failureRateMapper.getFailureRate(sensor.getSiteId(), sensor.getMainTreeId(), sensor.getSensorCode(), date);
        if (failureRate == null) {
            failureRate = new FailureRate();
            failureRate.setSiteId(sensor.getSiteId());
            failureRate.setMainTreeId(sensor.getMainTreeId());
            failureRate.setSubTreeId(sensor.getSubTreeId());
            failureRate.setSensorId(sensor.getSensorCode());
            failureRate.setCreatedTime(LocalDateTime.now());
            failureRate.setDTime(date);
        }
        // 实际次数
        failureRate.setRealCount(DecimalUtil.getVal(dataCount));
        // 应该次数
        failureRate.setMustCount(BigDecimal.ZERO);
        if(BigDecimal.ZERO.compareTo(uploadCycle) != 0) {
            failureRate.setMustCount(DecimalUtil.getVal(CalcUtil.calcMustCount(uploadCycle)));  
        }
        // 缺失率
        failureRate.setRate(BigDecimal.ONE);
        if (BigDecimal.ZERO.compareTo(failureRate.getMustCount()) != 0) {
            failureRate.setRate(CalcUtil.calcRate(failureRate.getMustCount().subtract(failureRate.getRealCount()),
                failureRate.getMustCount()));
        }
        failureRate.setModifiedTime(LocalDateTime.now());
        failureRateDao.saveOrUpdate(failureRate);
    }

    @Override
    public String getSensorLossRate(String sensorCode, Date startTime, Date endTime) {
        return getSensorLossRate(sensorCode, DateUtil.toLocalDateTime(startTime), DateUtil.toLocalDateTime(endTime));
    }

    @Override
    public String getSensorLossRate(String sensorCode, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> param = Maps.newLinkedHashMapWithExpectedSize(3);
        param.put("sensorCode", sensorCode);
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        return getLossRateCount(param);
    }

    private String getLossRateCount(Map<String, Object> param) {
        Map<String, Object> lossRateCountMap = failureRateMapper.getLossRateCount(param);
        if (CollectionUtils.isEmpty(lossRateCountMap)) {
            return null;
        }
        Object totalMustCountObj = lossRateCountMap.get("totalMustCount");
        BigDecimal totalMustCount = DecimalUtil.getVal(String.valueOf(totalMustCountObj));
        Object totalRealCountObj = lossRateCountMap.get("totalRealCount");
        BigDecimal totalRealCount = DecimalUtil.getVal(String.valueOf(totalRealCountObj));
        // 计算
        BigDecimal rate = CalcUtil.calcRate(totalMustCount.subtract(totalRealCount), totalMustCount);
        if (rate.compareTo(BigDecimal.ZERO) == -1) {
        	rate = new BigDecimal(0);
        }
        // 转换成百分比
        DecimalFormat df = new DecimalFormat("0.00##");
        return df.format(rate);
    }
}