package org.springblade.modules.nh.factory.aiswei;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import org.springblade.modules.nh.factory.aiswei.config.AisweiApiRestTemplate;
import org.springblade.modules.nh.factory.aiswei.constant.Constants;
import org.springblade.modules.nh.factory.aiswei.constant.HttpHeader;
import org.springblade.modules.nh.factory.aiswei.constant.HttpSchema;
import org.springblade.modules.nh.factory.aiswei.dto.getdevicelistpro.GetDeviceListProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getdevicelistpro.GetDeviceListProResp;
import org.springblade.modules.nh.factory.aiswei.dto.getinvertercurrenterrorpro.GetInverterCurrentErrorProR;
import org.springblade.modules.nh.factory.aiswei.dto.getinvertercurrenterrorpro.GetInverterCurrentErrorProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterdatapagepro.GetInverterDataPageProData;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterdatapagepro.GetInverterDataPageProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getinverteretodaypro.GetInverterETodayProData;
import org.springblade.modules.nh.factory.aiswei.dto.getinverteretodaypro.GetInverterETodayProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterhiserrorpagepro.GetInverterHisErrorPageProR;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterhiserrorpagepro.GetInverterHisErrorPageProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getinverteroverviewpro.GetInverterOverviewProData;
import org.springblade.modules.nh.factory.aiswei.dto.getinverteroverviewpro.GetInverterOverviewProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterrecoverstatuspro.GetInverterRecoverStatusProR;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterrecoverstatuspro.GetInverterRecoverStatusProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getlasttsdatapro.GetLastTsDataProR;
import org.springblade.modules.nh.factory.aiswei.dto.getlasttsdatapro.GetLastTsDataProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getplanlistpro.GetPlanListProR;
import org.springblade.modules.nh.factory.aiswei.dto.getplanlistpro.GetPlanListProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getplantoutputpro.GetPlantOutputProReq;
import org.springblade.modules.nh.factory.aiswei.dto.getplantoutputpro.GetPlantOutputProResp;
import org.springblade.modules.nh.factory.aiswei.dto.getplantoverviewpro.GetPlantOverviewProR;
import org.springblade.modules.nh.factory.aiswei.dto.getplantoverviewpro.GetPlantOverviewProReq;
import org.springblade.modules.nh.factory.aiswei.enums.Method;
import org.springblade.modules.nh.factory.aiswei.util.AisweiObjectMapper;
import org.springblade.modules.nh.factory.aiswei.util.AisweiRequest;
import org.springblade.modules.nh.factory.aiswei.util.AisweiResponse;
import org.springblade.modules.nh.factory.aiswei.util.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.modules.nh.factory.common.TokenBucket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class AisweiApi {

    @Autowired
    AisweiApiRestTemplate aisweiApiRestTemplate;
    private static final String HOST = "api.general.aisweicloud.com";
//    private static final String HOST = "localhost:8021";

//    @Value("${aiswei.key}")
    String key = "204096593";
//    @Value("${aiswei.secret}")
    String secret ="SmOBrWWqKt7alK4sV2qEuWWqR75L52I0";
//    @Value("${aiswei.token}")
    String token ="dE41Z0RhR1IzakFTTmJvMjZyNDF0QT09";
    private final TokenBucket tokenBucket;

    public AisweiApi() {
        tokenBucket = new TokenBucket();
    }

    private static final Logger logger = LoggerFactory.getLogger(AisweiApi.class);

    private static final AisweiObjectMapper objectMapper = new AisweiObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    public AisweiResponse aisGetRequest(String path, Map<String, String> params) {
        tokenBucket.get();
        Map<String, String> headers = new HashMap<>();
        //（必填）根据期望的Response内容类型设置
        headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json");
        AisweiRequest request = new AisweiRequest(Method.GET, HttpSchema.HTTP + HOST, path, key, secret, Constants.DEFAULT_TIMEOUT * 10);
        request.setHeaders(headers);
        params.put("token", token);
        request.setSignHeaderPrefixList(null);
        request.setQuerys(params);
        AisweiResponse resp = Client.execute(request);
        logger.debug("ais response: {}", resp.getBody());
        return resp;
    }

    /**
     * 分页获取用户所有电站信息
     */
    public AisweiRet<AisweiPage<GetPlanListProR>> getPlanListPro(GetPlanListProReq req) {
        String path = wrapPath("/pro/getPlanListPro");
        //请求的query
        Map<String, String> querys = new HashMap<>();
        querys.put("token", token);
        querys.put("order", String.valueOf(req.getOrder()));
        querys.put("pageNum", String.valueOf(req.getPageNum()));
        querys.put("pageSize", String.valueOf(req.getPageSize()));
        //调用服务端
        AisweiResponse response = aisGetRequest(path, querys);
        String body = response.getBody();
        TypeReference<AisweiRet<AisweiPage<GetPlanListProR>>> typeRef = new TypeReference<AisweiRet<AisweiPage<GetPlanListProR>>>() {
        };
        return objectMapper.readValue(body, typeRef);
    }

    private String wrapPath(String path) {
        return Objects.equals(HOST, "api.general.aisweicloud.com") ? path : "/as/mock" + path;
    }

    /**
     * 获取电站发电量及效益减排数据
     */
    public AisweiRet<GetPlantOverviewProR> getPlantOverviewPro(GetPlantOverviewProReq req) {
        Map<String, String> params = new HashMap<>();
        params.put("apikey", req.getApikey());
        params.put("token", req.getToken());
        AisweiResponse response = aisGetRequest("/pro/getPlantOverviewPro", params);
        String body = response.getBody();
        TypeReference<AisweiRet<GetPlantOverviewProR>> typeRef = new TypeReference<AisweiRet<GetPlantOverviewProR>>() {
        };
        return objectMapper.readValue(body, typeRef);
    }

    /**
     * 按照查询类型获取电站下所有逆变器，其实这个电站维度的统计
     * (某天、月、年)数据
     */
    public AisweiRet<GetPlantOutputProResp> getPlantOutputPro(GetPlantOutputProReq req) {
        String url = wrapPath("/pro/getPlantOutputPro");
        Map<String, String> params = new HashMap<>();
        params.put("apikey", req.getApikey());
        params.put("period", req.getPeriod());
        params.put("date", req.getDate());
        params.put("token", req.getToken());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<GetPlantOutputProResp>> typeRef = new TypeReference<AisweiRet<GetPlantOutputProResp>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 获取电站下全部设备的列表
     */
    public AisweiRet<List<GetDeviceListProResp>> getDeviceListPro(GetDeviceListProReq req) {
        String url = wrapPath("/pro/getDeviceListPro");
        Map<String, String> params = new HashMap<>();
        params.put("apikey", req.getApiKey());
        params.put("token", req.getToken());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<List<GetDeviceListProResp>>> typeRef = new TypeReference<AisweiRet<List<GetDeviceListProResp>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 分页获取电站下所有逆变器在某时段内数据，时间段不能超过一天
     * 时间间隔：gt 10 mins and less than 24 hours
     * pageSize less than 500
     */
    public AisweiRet<AisweiPage<GetInverterDataPageProData>> getInverterDataPagePro(GetInverterDataPageProReq req) {
        String url = wrapPath("/pro/getInverterDataPagePro");
        Map<String, String> params = new HashMap<>();
        params.put("apikey", req.getApiKey());
        params.put("token", req.getToken());
        params.put("isno", req.getIsnos());
        params.put("startDate", req.getStartDate());
        params.put("endDate", req.getEndDate());
        params.put("pageNum", String.valueOf(req.getPageNum()));
        params.put("pageSize", String.valueOf(req.getPageSize()));

        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<AisweiPage<GetInverterDataPageProData>>> typeRef = new TypeReference<AisweiRet<AisweiPage<GetInverterDataPageProData>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 获取多个逆变器的最新信息，包括总满发小时候、总发电量、频率等
     */
    public AisweiRet<List<GetLastTsDataProR>> getLastTsDataPro(GetLastTsDataProReq req) {
        String url = wrapPath("/pro/getLastTsDataPro");
        Map<String, String> params = new HashMap<>();
        params.put("isnos", req.getIsnos());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<List<GetLastTsDataProR>>> typeRef = new TypeReference<AisweiRet<List<GetLastTsDataProR>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 获取逆变器某天的发电量
     */
    public AisweiRet<GetInverterETodayProData> getInverterETodayPro(GetInverterETodayProReq req) {
        String url = wrapPath("/pro/getInverterETodayPro");
        Map<String, String> params = new HashMap<>();
        params.put("isnos", req.getIsnos());
        params.put("apikey", req.getApikey());
        params.put("date", req.getDate());
        params.put("token", req.getToken());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<GetInverterETodayProData>> typeRef = new TypeReference<AisweiRet<GetInverterETodayProData>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 分页获取逆变器历史故障信息，最大时间间隔7天
     */
    public AisweiRet<AisweiPage<GetInverterHisErrorPageProR>> getInverterHisErrorPagePro(GetInverterHisErrorPageProReq req) {
        String url = wrapPath("/pro/getInverterHisErrorPagePro");
        Map<String, String> params = new HashMap<>();
        params.put("isno", req.getIsno());
        params.put("apikey", req.getApikey());
        params.put("startDate", req.getStartDate());
        params.put("endDate", req.getEndDate());
        params.put("pageNum", String.valueOf(req.getPageNum()));
        params.put("pageSize", String.valueOf(req.getPageSize()));
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<AisweiPage<GetInverterHisErrorPageProR>>> typeRef = new TypeReference<AisweiRet<AisweiPage<GetInverterHisErrorPageProR>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 取电站下逆变器当前故障信息
     */
    public AisweiRet<List<GetInverterCurrentErrorProR>> getInverterCurrentErrorPro(GetInverterCurrentErrorProReq req) {
        String url = wrapPath("/pro/getInverterCurrentErrorPro");
        Map<String, String> params = new HashMap<>();
        params.put("isno", req.getIsno());
        params.put("apikey", req.getApikey());
        params.put("token", null);
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<List<GetInverterCurrentErrorProR>>> typeRef = new TypeReference<AisweiRet<List<GetInverterCurrentErrorProR>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 获取逆变器发电量及效益减排数据
     * 貌似是逆变器某个月的发电量和节能减排数据。
     */
    public AisweiRet<List<GetInverterOverviewProData>> getInverterOverviewPro(GetInverterOverviewProReq req) {
        String url = wrapPath("/pro/getInverterOverviewPro");
        Map<String, String> params = new HashMap<>();
        params.put("apikey", req.getApikey());
        params.put("date", req.getDate());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<List<GetInverterOverviewProData>>> typeRef = new TypeReference<AisweiRet<List<GetInverterOverviewProData>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

    /**
     * 根据故障唯一标识获取逆变器恢复状态信息
     */
    public AisweiRet<List<GetInverterRecoverStatusProR>> getInverterRecoverStatusPro(GetInverterRecoverStatusProReq req) {
        String url = wrapPath("/pro/getInverterRecoverStatusPro");
        Map<String, String> params = new HashMap<>();
        params.put("faultCodes", req.getFaultCodes());
        AisweiResponse response = aisGetRequest(url, params);
        TypeReference<AisweiRet<List<GetInverterRecoverStatusProR>>> typeRef = new TypeReference<AisweiRet<List<GetInverterRecoverStatusProR>>>() {
        };
        return objectMapper.readValue(response.getBody(), typeRef);
    }

}
