/*
 * 文 件 名:  GrowattTemplate
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/12/16
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.ruoyi.ems.core;

import com.alibaba.fastjson.support.retrofit.Retrofit2ConverterFactory;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.huashe.common.exception.Assert;
import com.ruoyi.ems.model.growatt.DataLogger;
import com.ruoyi.ems.model.growatt.DeviceInfo;
import com.ruoyi.ems.retrofit.GrowattApi;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.StringUtils;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;

import java.util.ArrayList;
import java.util.List;

/**
 * Growatt - 古瑞瓦特 操作模板
 * <功能详细描述>
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/16]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Slf4j
public class GrowattTemplate extends BaseApiTemplate {
    /**
     * 访问地址
     */
    protected String url;

    /**
     * 调用令牌
     */
    protected String token;

    /**
     * 调用代理
     */
    protected final GrowattApi api;

    public GrowattTemplate(String restUrl, String token) {
        this.url = restUrl;
        this.token = token;

        OkHttpClient httpClient = getClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl(restUrl)
            .addConverterFactory(Retrofit2ConverterFactory.create()).client(httpClient).build();
        this.api = retrofit.create(GrowattApi.class);
    }

    /**
     * 构造调用模板
     *
     * @param restUrl        服务地址 (http://ip:port)
     * @param connectTimeout 连接超时
     * @param readTimeout    读取超时
     * @param writeTimeout   写超时
     */
    public GrowattTemplate(String restUrl, String token, int connectTimeout, int readTimeout, int writeTimeout) {
        super.connectTimeout = connectTimeout;
        super.readTimeout = readTimeout;
        super.writeTimeout = writeTimeout;
        this.url = restUrl;
        this.token = token;

        OkHttpClient httpClient = getClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl(restUrl)
            .addConverterFactory(Retrofit2ConverterFactory.create()).client(httpClient).build();
        api = retrofit.create(GrowattApi.class);
    }

    /**
     * 获取采集器列表
     *
     * @param plantId 电站ID
     * @return 采集器列表
     */
    public List<DataLogger> getDatalogList(String plantId) {
        List<DataLogger> list = new ArrayList<>();

        try {
            int pageNo = 1;
            int pageSize = 100;
            boolean isLastPage = true;

            do {
                // 执行调用
                Call<String> call = api.getDatalogList(token, plantId, pageNo, pageSize);
                Response<String> response = call.execute();
                log.debug("getDatalogList response:{}", response);

                Assert.isTrue(response.isSuccessful(), response.code(), response.message());
                JSONObject resJson = JSONObject.parseObject(response.body());
                Assert.isTrue(resJson.getIntValue("error_code") == 0, resJson.getIntValue("error_code"),
                    resJson.getString("error_msg"));

                JSONObject data = resJson.getJSONObject("data");

                if (null != data) {
                    String dataStr = data.getString("dataloggers");
                    list.addAll(JSON.parseArray(dataStr, DataLogger.class));

                    int count = data.getIntValue("count");
                    isLastPage = list.size() >= count;

                    if (!isLastPage) {
                        pageNo++;
                    }
                }
            }
            while (!isLastPage);
        }
        catch (Exception e) {
            log.error("getDatalogList fail!", e);
        }

        return list;
    }

    /**
     * 获取设备列表
     *
     * @param plantId 电站ID
     * @return 设备列表
     */
    public List<DeviceInfo> getDeviceList(String plantId) {
        List<DeviceInfo> list = new ArrayList<>();

        try {
            int pageNo = 1;
            int pageSize = 100;
            boolean isLastPage = true;

            do {
                // 执行调用
                Call<String> call = api.getDeviceList(token, plantId, pageNo, pageSize);
                Response<String> response = call.execute();
                log.debug("getDeviceList response:{}", response);

                Assert.isTrue(response.isSuccessful(), response.code(), response.message());
                JSONObject resJson = JSONObject.parseObject(response.body());
                Assert.isTrue(resJson.getIntValue("error_code") == 0, resJson.getIntValue("error_code"),
                    resJson.getString("error_msg"));

                JSONObject data = resJson.getJSONObject("data");

                if (null != data) {
                    String dataStr = data.getString("devices");
                    list.addAll(JSON.parseArray(dataStr, DeviceInfo.class));

                    int count = data.getIntValue("count");
                    isLastPage = list.size() >= count;

                    if (!isLastPage) {
                        pageNo++;
                    }
                }
            }
            while (!isLastPage);
        }
        catch (Exception e) {
            log.error("getDeviceList fail!", e);
        }

        return list;
    }

    /**
     * 获取设备列表
     *
     * @param type 类型 16：inverter， 17：SPH， 18：MAX， 19：SPA， 22：MIN
     * @param snList 设备SN集合
     * @return 设备列表
     */
    public JSONObject getDeviceData(int type, List<String> snList) {
        JSONObject retJson = null;

        try {
            // 执行调用
            String devSnStr = StringUtils.join(snList, ",");
            Call<String> call = api.getDeviceData(token, type, devSnStr);
            Response<String> response = call.execute();
            log.debug("getDeviceData response:{}", response);

            Assert.isTrue(response.isSuccessful(), response.code(), response.message());
            JSONObject resJson = JSONObject.parseObject(response.body());
            Assert.isTrue(resJson.getIntValue("error_code") == 0, resJson.getIntValue("error_code"),
                resJson.getString("error_msg"));

            retJson = resJson.getJSONObject("data");
        }
        catch (Exception e) {
            log.error("getDeviceData fail!", e);
        }

        return retJson;
    }
}