package com.njcn.energy.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.energy.mapper.EleEpdMapper;
import com.njcn.energy.mapper.EleLoadSetMapper;
import com.njcn.energy.mapper.PvPowerStrategyMapper;
import com.njcn.energy.pojo.constant.SmsConstant;
import com.njcn.energy.pojo.po.EleEpdPqd;
import com.njcn.energy.pojo.po.PvPowerStrategy;
import com.njcn.influx.utils.InfluxDbUtils;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: cdf
 * @CreateTime: 2025-05-12
 * @Description:
 */
@EnableScheduling
@Slf4j
@RequiredArgsConstructor
@RestController
@Api(tags = "光伏异常运行定时任务")
public class SunPowerScheduledController {

    private final DicDataFeignClient dicDataFeignClient;

    private final EleLoadSetMapper eleLoadSetMapper;

    private final EleEpdMapper eleEpdMapper;

    private final PvPowerStrategyMapper pvPowerStrategyMapper;

    private static final String PARK_POWER_NOTICE = "SMS_485465792";

    private final InfluxDbUtils influxDbUtils;

    @Scheduled(cron = "0 50 8 * * ?")
    @GetMapping("sunBadSendMessage")
    public void sunBadSendMessage() {
        try {
            DateTime yesterday = DateUtil.yesterday();
            String begin = DateUtil.format(DateUtil.beginOfDay(yesterday), DatePattern.NORM_DATETIME_PATTERN);
            String end = DateUtil.format(DateUtil.endOfDay(yesterday), DatePattern.NORM_DATETIME_PATTERN);
            EleEpdPqd eleEpdPqd = eleEpdMapper.selectById("64592326d968dd07ffc0437befcfa026");
            if(Objects.isNull(eleEpdPqd)){
                log.error("获取净有功电能配置失败,任务终止");
                return;
            }
            DictData dictData = dicDataFeignClient.getDicDataByCodeAndType("Photovoltaic", DicDataTypeEnum.ELE_LOAD_TYPE.getCode()).getData();
            if(Objects.isNull(dictData)){
                log.error("获取光伏字典失败,任务终止");
                return;
            }
            List<String> lineIdList = eleLoadSetMapper.getAllLineListRelation(dictData.getId());
            log.info("获取监测点信息{}",lineIdList);
            if (CollectionUtil.isNotEmpty(lineIdList)) {
                StringBuilder lineId = new StringBuilder();
                for (int i = 0; i < lineIdList.size(); i++) {
                    if (i == lineIdList.size() - 1) {
                        lineId.append("'").append(lineIdList.get(i)).append("'");
                    } else {
                        lineId.append("'").append(lineIdList.get(i)).append("'").append(" or LineId=");
                    }
                }
                StringBuilder sql = new StringBuilder("select ");
                sql.append("SUM(").append(eleEpdPqd.getName()).append(") as ").append(eleEpdPqd.getName()).append(" from ").append(eleEpdPqd.getClassId()).append(" where (LineId = ").append(lineId).append(") and Phase= '").append(eleEpdPqd.getPhase())
                        .append("' and time>='").append(begin).append("' and time<= '").append(end).append("' and ").append(eleEpdPqd.getName()).append(" !=-1000000").append(" group by time(15m)");
                log.info("执行sql-----------{}",sql);
                List<Map<String, Object>> mapList = influxDbUtils.getResult(sql.toString(), "");

                if (CollectionUtil.isNotEmpty(mapList)) {
                    List<Map<String, Object>> temList = mapList.stream().filter(it->Objects.nonNull(it.get("WattHr"))).collect(Collectors.toList());
                    log.info("返回结果-----------{}",+temList.size());
                    if(temList.size()<10){
                        //防止数据量太少导致的异常发送
                        log.error("power_data表统计日数据量太少，判定为异常,任务终止");
                        return;
                    }

                    double max = temList.stream().mapToDouble(it->Double.parseDouble(it.get("WattHr").toString())).max().orElse(3.14159);
                    double min = temList.stream().mapToDouble(it->Double.parseDouble(it.get("WattHr").toString())).min().orElse(3.14159);
                    if(max != 3.14159 && min != 3.14159){
                        PvPowerStrategy pvPowerStrategy = pvPowerStrategyMapper.selectOne(new LambdaQueryWrapper<>());
                        if(Objects.isNull(pvPowerStrategy)){
                            log.error("表pv_power_strategy_光伏发电配置查询为空,任务终止");
                            return;
                        }
                        double val = NumberUtil.round(max-min,3).doubleValue();
                        log.info("当天发电量:{} kwh",+val);
                        if(val < pvPowerStrategy.getAlarmVal()){
                            log.info("净电度差值 {} 低于阈值 {}, 准备发送报警短信", val, pvPowerStrategy.getAlarmVal());
                            String[] phoneArr = pvPowerStrategy.getSendPhone().split(StrUtil.COMMA);
                            for(String ph : phoneArr){
                                sendMobileMessage(DateUtil.format(yesterday,DatePattern.NORM_DATE_PATTERN),String.valueOf(val), ph);
                            }
                        }else {
                            log.info("净电度差值 {} 高于阈值 {}, 无需报警", val, pvPowerStrategy.getAlarmVal());
                        }
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 发送手机短信
     *
     * @return 推送的响应
     */
    private static SendSmsResponse sendMobileMessage(String date, String value, String phone) {
        SendSmsResponse sendSmsResponse = new SendSmsResponse();
        //开始执行短信发送
        try {
            //设置超时时间-可自行调整
            System.setProperty(SmsConstant.DEFAULT_CONNECT_TIME_OUT, "10000");
            System.setProperty(SmsConstant.DEFAULT_READ_TIME_OUT, "10000");
            IClientProfile profile = DefaultProfile.getProfile(SmsConstant.LOCATION, SmsConstant.ACCESS_KEY_ID, SmsConstant.ACCESS_KEY_SECRET);
            DefaultProfile.addEndpoint(SmsConstant.LOCATION, SmsConstant.LOCATION, SmsConstant.PRODUCT, SmsConstant.DOMAIN);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            SendSmsRequest request = new SendSmsRequest();
            request.setMethod(MethodType.POST);
            request.setPhoneNumbers(phone);
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(SmsConstant.SGIN);
            //必填:短信模板-可在短信控制台中找到，发送国际/港澳台消息时，请使用国际/港澳台短信模版
            request.setTemplateCode(PARK_POWER_NOTICE);
            String messgae = "{\"date\":\"" + date+ "\",\"value\":\"" + value + "\"}";
            request.setTemplateParam(messgae);
            //请求失败这里会抛ClientException异常
            sendSmsResponse = acsClient.getAcsResponse(request);
            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                //成功发送短信验证码后，保存进redis
                log.info("给用户发送光伏发电异常短信成功，手机号为：{}", phone);
            } else {
                log.info("给用户发送光伏发电异常短信失败，手机号为：{}，失败原因为：{}", phone, sendSmsResponse.getMessage());
            }
        } catch (Exception e) {
            log.error("用能光伏发电自动定时任务发送短信异常：" + e.getMessage());
        }
        return sendSmsResponse;
    }


    public static void main(String[] args) {
        try {
            sendMobileMessage("2025-05-11","8", "18815508963");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

