package com.ho.business.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.Device;
import com.ho.business.entity.Station;
import com.ho.business.service.DeviceService;
import com.ho.business.service.ReallyCockpitService;
import com.ho.business.service.StationService;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.InverterResp.ModelNewInverter;
import com.ho.business.vo.resp.cockpit.CapacityProportionResp;
import com.ho.business.vo.resp.cockpit.CumulativeRespVO;
import com.ho.business.vo.resp.cockpit.GroupDataRespVo;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 驾驶舱的真实数据实现
 * Author yule
 * Date 2023/4/12 14:39
 */
@Slf4j
@Service
public class ReallyCockpitServiceImpl implements ReallyCockpitService {

    @Autowired
    StationService stationService;

    @Autowired
    RedisService redisService;

    @Autowired
    DeviceService deviceService;

    //二氧化碳到煤的转换系数
    @Value("${energy.co2ToCole}")
    BigDecimal co2ToCole;
    //二氧化碳到树的转换系数
    @Value("${energy.co2ToTree}")
    BigDecimal co2ToTree;
    //二氧化碳到汽油的转换系数
    @Value("${energy.co2ToGasoline}")
    BigDecimal co2ToGasoline;
    //树到平方公里的转换系数
    @Value("${energy.treeToSquareKilometer}")
    BigDecimal treeToSquareKilometer;
    //碳排放因子
    @Value("${inverter.co2Factor}")
    BigDecimal co2Factor;

    @Override
    public GroupDataRespVo getGroupData(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        List<Device> devices = new ArrayList<>();
        for (Integer stationId : stationIds) {
            DeviceReqVO reqVO = new DeviceReqVO();
            reqVO.setStationId(stationId);
            reqVO.setDeviceTypePrefix(DeviceTypeConstant.INVERTER_PREFIX);
            List<DeviceRespVO> list = deviceService.getList(reqVO);
            devices.addAll(list);
        }
        //总装机容量
        BigDecimal pvCapacity = BigDecimal.ZERO;
        for (Station station : stations) {
            pvCapacity = pvCapacity.add(station.getCapacity());
        }
        //当前总功率 各个逆变器的有功功率之和
        BigDecimal pvCurrentPower = BigDecimal.ZERO;
        //累计发电量
        BigDecimal pvCumulativePowerGeneration = BigDecimal.ZERO;

        for (Device device : devices) {
            String inverterRedisKey = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
            ModelNewInverter modelInverter = new ModelNewInverter();
            if (redisService.hasKey(inverterRedisKey)) {
                Map<Object, Object> inverterMap = redisService.hgetall(inverterRedisKey);
                if (inverterMap != null) {
                    modelInverter = JSON.parseObject(JSON.toJSONString(inverterMap), ModelNewInverter.class);
                }
                BigDecimal acActivePower = BigDecimal.ZERO;
                if(modelInverter.getAcActivePower() != null && modelInverter.getAcActivePower().getValue()!=null){
                    acActivePower = modelInverter.getAcActivePower().getValue();
                }
                pvCurrentPower = pvCurrentPower.add(acActivePower);

                //累计发电量  cumulativePowerGeneration
                BigDecimal modelInverterCumulativePowerGeneration =BigDecimal.ZERO;
                if(modelInverter.getCumulativePowerGeneration()!=null && modelInverter.getCumulativePowerGeneration().getValue()!=null){
                    modelInverterCumulativePowerGeneration = modelInverter.getCumulativePowerGeneration().getValue();
                }
                pvCumulativePowerGeneration = pvCumulativePowerGeneration.add(modelInverterCumulativePowerGeneration);
            }
        }

        //todo 创建返回值对象(先只有光伏数据)
        GroupDataRespVo groupDataRespVo = new GroupDataRespVo();
        groupDataRespVo.setPvCapacity(pvCapacity);
        groupDataRespVo.setPvCurrentPower(pvCurrentPower);
        groupDataRespVo.setPvPowerGeneration(pvCumulativePowerGeneration);

        return groupDataRespVo;
    }

    @Override
    public CumulativeRespVO getCumulative(SimpleUser user) {

        //获取光伏累计放电量
        GroupDataRespVo groupData = getGroupData(user);
        BigDecimal powerGeneration = groupData.getPvPowerGeneration();

        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);

        CumulativeRespVO respVO = new CumulativeRespVO();
        if (stations == null || stations.isEmpty()) {
            return respVO;
        }
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        //找出最早的电站的创建时间
        Date createTime = null;
        for (Station station : stations) {
            Date stationCreateTime = station.getCreateTime();
            if (createTime == null) {
                createTime = stationCreateTime;
            } else {
                //比较两个时间大小(前 - 后)
                int compare = DateUtil.compare(createTime, stationCreateTime);
                if (compare > 0) {
                    createTime = stationCreateTime;
                }
            }
        }
        //安全运行天数(今天时间 - 创建时间)
        long safeOperationDays = 0;
        if (createTime == null) {
            safeOperationDays = 0;
        } else {
            safeOperationDays = DateUtil.between(createTime, new Date(), DateUnit.DAY);
        }
        //计算等值数据
        BigDecimal co2Reductions = powerGeneration.multiply(co2Factor);
        // co2/一棵树每年的吸收系数 = 减伐的树
        BigDecimal treeReductions = co2Reductions.divide(co2ToTree, 2, BigDecimal.ROUND_HALF_UP);
        // co2/每升汽油燃烧排放的二氧化碳 = 节约石油
        BigDecimal petroleumReductions = co2Reductions.divide(co2ToGasoline, 2, BigDecimal.ROUND_HALF_UP);


        respVO.setSafeOperationDays((int) safeOperationDays);
        respVO.setPvPowerGeneration(powerGeneration);
        respVO.setCo2Reductions(co2Reductions);
        respVO.setCoalReductions(powerGeneration.multiply(co2Factor).multiply(co2ToCole));
        respVO.setTreeReductions(treeReductions);
        respVO.setPetroleumReductions(petroleumReductions);
        respVO.setForestReductions(treeReductions.divide(treeToSquareKilometer, 2, BigDecimal.ROUND_HALF_UP));
        return respVO;
    }

    @Override
    public CapacityProportionResp capacityProportion(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());
        //总装机容量
        BigDecimal pvCapacity = BigDecimal.ZERO;
        for (Station station : stations) {
            pvCapacity = pvCapacity.add(station.getCapacity());
        }
        //todo 总装机容量(现只有光伏)
        BigDecimal totalCapacity = pvCapacity;

        //创建返回值
        CapacityProportionResp capacityProportionResp = new CapacityProportionResp();

        BigDecimal pvProportion =
                totalCapacity.equals(BigDecimal.ZERO)
                        ? BigDecimal.ZERO
                        : pvCapacity.divide(totalCapacity, 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(new BigDecimal("100"));

        capacityProportionResp.setPvProportion(pvProportion);
        return capacityProportionResp;
    }


    /**
     * 通过登录人查询到集团下所有电站
     *
     * @param user
     * @return 集团下所有电站
     */
    private List<Station> getStations(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        //根据分组id查询到该集团所有电站
        List<Station> stations = stationService.selectByGroupId(user.getGroupId());
        return stations;
    }
}
