package com.njcn.prepare.harmonic.service.mysql.Impl.line;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.harmonic.pojo.po.RMpEventDetailDPO;
import com.njcn.harmonic.pojo.po.RMpEventDetailMPO;
import com.njcn.prepare.harmonic.mapper.mysql.line.RMpEventDetailMapper;
import com.njcn.prepare.harmonic.pojo.mysql.RMpEventDetailPO;
import com.njcn.prepare.harmonic.pojo.param.LineParam;
import com.njcn.prepare.harmonic.service.mysql.line.RMpEventDetailDService;
import com.njcn.prepare.harmonic.service.mysql.line.RMpEventDetailMService;
import com.njcn.prepare.harmonic.service.mysql.line.RMpEventDetailService;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 
 * Description:
 * 接口文档访问地址：http://serverIP:port/swagger-ui.html
 * Date: 2023/4/23  13:50【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class RMpEventDetailServiceImpl extends ServiceImpl<RMpEventDetailMapper, RMpEventDetailPO> implements RMpEventDetailService{

    private final RMpEventDetailDService rMpEventDetailDService;

    private final RMpEventDetailMService rMpEventDetailMService;

    private final DicDataFeignClient dicDataFeignClient;

    private final RedisUtil redisUtil;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    @Async("asyncExecutor")
    public void eventdetailHandler(LineParam lineParam) {
        this.hanlderData(lineParam);
    }

    @Override
    public Integer queryByCondition(String measurementPointId, String dataDate, String eventType) {
        QueryWrapper<RMpEventDetailPO> queryWrapper = new QueryWrapper ( );
        queryWrapper.select ("1").
                eq ("measurement_point_id", measurementPointId).
                eq ("event_type",eventType).
                eq("DATE_FORMAT( start_time ,'%Y-%m-%d')",dataDate);

        Integer integer = this.getBaseMapper ().selectCount (queryWrapper);

        return integer;
    }

    /**
     * @Description: hanlderOracleData
     * @Param: [lineParam]
     * @return: void
     * @Author: clam
     * @Date: 2022/12/28
     */
    private void hanlderData(LineParam lineParam) {
        Integer type = lineParam.getType ( );
        switch (type) {
//            case 1:
//                this.hanlderYear (lineParam);
//                break;
//            case 2:
//                this.hanlderQtr (lineParam);
//                break;
            case 3:
                this.hanlderMonth (lineParam);
                break;
            case 5:
                this.hanlderDay (lineParam);
                break;
            default:
                break;
        }
    }
    @SneakyThrows
    private void hanlderMonth(LineParam lineParam) {


        List<String> lineIds = lineParam.getLineIds ( );
        String dataDate = lineParam.getDataDate ( );
        final Date tempDate = new SimpleDateFormat ("yyyy-MM-dd").parse (dataDate);
        List<RMpEventDetailMPO> rMpEventDetailMPOList = new ArrayList<> ( );

        lineIds.forEach (measurementPointId -> {
            /*查询day表数据生成月表数据*/
            List<RMpEventDetailDPO> rMpEventDetailDPOList = rMpEventDetailDService.queryOneMothData(measurementPointId,dataDate);
            int sagCount = rMpEventDetailDPOList.stream ( ).mapToInt (RMpEventDetailDPO::getSagTimes).sum ( );
            int riseCount = rMpEventDetailDPOList.stream ( ).mapToInt (RMpEventDetailDPO::getSwellTimes).sum ( );
            int interruptCount = rMpEventDetailDPOList.stream ( ).mapToInt (RMpEventDetailDPO::getInterruptTimes).sum ( );

            RMpEventDetailMPO rMpEventDetailMPO = new RMpEventDetailMPO();
            rMpEventDetailMPO.setMeasurementPointId (measurementPointId);
            rMpEventDetailMPO.setDataDate (tempDate);
            rMpEventDetailMPO.setSagTimes (sagCount);
            rMpEventDetailMPO.setSwellTimes (riseCount);
            rMpEventDetailMPO.setInterruptTimes (interruptCount);
            rMpEventDetailMPOList.add (rMpEventDetailMPO);

        });

        rMpEventDetailMService.saveOrUpdateBatchByMultiId (rMpEventDetailMPOList,500);
    }


    @SneakyThrows
    private void hanlderDay(LineParam lineParam) {

        List<String> lineIds = lineParam.getLineIds ( );
        String dataDate = lineParam.getDataDate ( );
        final Date tempDate = new SimpleDateFormat ("yyyy-MM-dd").parse (dataDate);
        List<RMpEventDetailDPO> rMpEventDetailDPOList = new ArrayList<> ( );


        lineIds.forEach (measurementPointId -> {
            Integer sagCount = this.queryByCondition (measurementPointId,dataDate, getEventTypeId(DicDataEnum.VOLTAGE_DIP.getCode ( )));
            Integer riseCount = this.queryByCondition (measurementPointId,dataDate,getEventTypeId(DicDataEnum.VOLTAGE_RISE.getCode ( )));
            Integer interruptCount = this.queryByCondition (measurementPointId,dataDate,getEventTypeId(DicDataEnum.SHORT_INTERRUPTIONS.getCode ( )));
            RMpEventDetailDPO rMpEventDetailDPO = new RMpEventDetailDPO();
            rMpEventDetailDPO.setMeasurementPointId (measurementPointId);
            rMpEventDetailDPO.setDataDate (tempDate);
            rMpEventDetailDPO.setSagTimes (sagCount);
            rMpEventDetailDPO.setSwellTimes (riseCount);
            rMpEventDetailDPO.setInterruptTimes (interruptCount);

            rMpEventDetailDPOList.add (rMpEventDetailDPO);
        });

        rMpEventDetailDService.saveOrUpdateBatchByMultiId (rMpEventDetailDPOList,500);
    }

    public String getEventTypeId(String code){

        String eventType =redisUtil.getStringByKey (code);
        eventType = Optional.ofNullable (eventType).orElseGet (() ->{
            DictData data = dicDataFeignClient.getDicDataByCode (code).getData ( );
            redisUtil.saveByKey (data.getCode (),data.getId ());
            return data.getId ();
        });

        return eventType;

    }

}
