package com.fjhx.iot.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.fjhx.iot.entity.tda.po.TdaConfig;
import com.fjhx.iot.service.tda.TdaConfigService;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.region.Region;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.auth.IoTDACredentials;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.ruoyi.common.exception.ServiceException;
import lombok.Data;

import java.util.Collections;

public class IoTDAUtil {

    // REGION_ID：如果是上海一，请填写"cn-east-3"；如果是北京四，请填写"cn-north-4";如果是华南广州，请填写"cn-south-4"
    private static final String REGION_ID = "ap-southeast-1";
    // ENDPOINT：请在控制台的"总览"界面的"平台接入地址"中查看“应用侧”的https接入地址。
    private static final String ENDPOINT = "a0ba517e07.st1.iotda-app.ap-southeast-1.myhuaweicloud.com";

    private static final TdaConfigService tdaConfigService = SpringUtil.getBean(TdaConfigService.class);

    /**
     * 创建资源空间
     *
     * @param appName 资源空间名称
     * @return 资源空间id
     */
    public static String addApplication(Long configId, String appName) {
        AddApplicationRequest addApplicationRequest = new AddApplicationRequest();
        AddApplication addApplication = new AddApplication();
        addApplication.setAppName(appName);
        addApplicationRequest.setBody(addApplication);
        AddApplicationResponse addApplicationResponse = getIoTDAClient(configId).addApplication(addApplicationRequest);
        return addApplicationResponse.getAppId();
    }

    /**
     * 删除资源空间
     *
     * @param appId 资源空间Id
     */
    public static void deleteApplication(Long configId, String appId) {
        try {
            DeleteApplicationRequest deleteApplicationRequest = new DeleteApplicationRequest();
            deleteApplicationRequest.setAppId(appId);
            getIoTDAClient(configId).deleteApplication(deleteApplicationRequest);
        } catch (Exception e) {
            throw new ServiceException("资源空间删除失败");
        }
    }

    /**
     * 创建产品
     *
     * @param appId            资源空间Id
     * @param name             产品名称
     * @param deviceType       设备类型
     * @param manufacturerName 厂商名称
     * @param protocolType     设备使用的协议类型
     * @return 产品id
     */
    public static String createProduct(Long configId, String appId, String name, String deviceType, String manufacturerName, String protocolType) {

        // 添加命名空间
        ServiceProperty serviceProperty = new ServiceProperty();
        serviceProperty.setPropertyName("DeviceData");
        serviceProperty.setDataType("string");
        serviceProperty.setRequired(false);
        serviceProperty.setMaxLength(2000000);
        serviceProperty.setStep(0.0D);
        serviceProperty.setMethod("RW");

        // 添加产品属性
        ServiceCapability serviceCapability = new ServiceCapability();
        serviceCapability.setServiceId("data");
        serviceCapability.setServiceType("data");
        serviceCapability.setProperties(Collections.singletonList(serviceProperty));

        CreateProductRequest createProductRequest = new CreateProductRequest();
        AddProduct addProduct = new AddProduct();
        // 资源空间
        addProduct.setAppId(appId);
        // 产品名称
        addProduct.setName(name);
        addProduct.setDeviceType(deviceType);
        addProduct.setManufacturerName(manufacturerName);
        addProduct.setProtocolType(ObjectUtil.defaultIfBlank(protocolType, "MQTT"));
        addProduct.setDataFormat("json");
        addProduct.setServiceCapabilities(Collections.singletonList(serviceCapability));
        createProductRequest.setBody(addProduct);

        CreateProductResponse product = getIoTDAClient(configId).createProduct(createProductRequest);

        return product.getProductId();
    }

    /**
     * 修改产品
     *
     * @param productId        产品id
     * @param appId            资源空间Id
     * @param name             产品名称
     * @param deviceType       设备类型
     * @param manufacturerName 厂商名称
     */
    public static void updateProduct(Long configId, String productId, String appId, String name, String deviceType, String manufacturerName) {
        UpdateProductRequest updateProductRequest = new UpdateProductRequest();
        updateProductRequest.setProductId(productId);
        UpdateProduct updateProduct = new UpdateProduct();
        updateProduct.setAppId(appId);
        updateProduct.setName(name);
        updateProduct.setDeviceType(deviceType);
        updateProduct.setManufacturerName(manufacturerName);
        updateProductRequest.setBody(updateProduct);
        getIoTDAClient(configId).updateProduct(updateProductRequest);
    }

    /**
     * 删除产品
     *
     * @param appId     资源空间Id
     * @param productId 产品id
     */
    public static void deleteProduct(Long configId, String appId, String productId) {
        try {
            DeleteProductRequest deleteProductRequest = new DeleteProductRequest();
            deleteProductRequest.setAppId(appId);
            deleteProductRequest.setProductId(productId);
            getIoTDAClient(configId).deleteProduct(deleteProductRequest);
        } catch (Exception e) {
            throw new ServiceException("产品删除失败");
        }
    }

    /**
     * 添加设备
     *
     * @param nodeId     设备标识
     * @param deviceName 设备名称
     * @param appId      资源空间Id
     * @param productId  产品id
     * @return 设备secret
     */
    public static DeviceKey addDevice(Long configId, String nodeId, String deviceName,
                                      String appId, String productId, String secret) {

        AuthInfo authInfo = new AuthInfo();
        authInfo.setSecret(secret);

        AddDeviceRequest addDeviceRequest = new AddDeviceRequest();
        AddDevice addDevice = new AddDevice();
        addDevice.setNodeId(nodeId);
        addDevice.setDeviceName(deviceName);
        addDevice.setAppId(appId);
        addDevice.setProductId(productId);
        addDevice.setAuthInfo(authInfo);
        addDevice.setDeviceId(nodeId);

        addDeviceRequest.setBody(addDevice);
        AddDeviceResponse addDeviceResponse = getIoTDAClient(configId).addDevice(addDeviceRequest);

        DeviceKey deviceKey = new DeviceKey();
        deviceKey.setDeviceId(addDeviceResponse.getDeviceId());
        deviceKey.setSecret(addDeviceResponse.getAuthInfo().getSecret());

        return deviceKey;
    }

    /**
     * 删除设备
     *
     * @param deviceId 设备Id
     */
    public static void deleteDevice(Long configId, String deviceId) {
        try {
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceId(deviceId);
            getIoTDAClient(configId).deleteDevice(deleteDeviceRequest);
        } catch (Exception e) {
            throw new ServiceException("产品删除失败");
        }
    }

    @Data
    public static class DeviceKey {
        // 设备id
        private String deviceId;
        // 设备密匙
        private String secret;
    }

    public static IoTDAClient getIoTDAClient(Long configId) {

        TdaConfig tdaConfig = tdaConfigService.getById(configId);

        if (tdaConfig == null) {
            throw new ServiceException("没有找到iot配置");
        }

        // 创建认证
        ICredential auth = new IoTDACredentials()
                .withAk(tdaConfig.getAccessKeyId())
                .withSk(tdaConfig.getSecretAccessKey())
                .withProjectId(tdaConfig.getProductId());

        // 创建IoTDAClient实例并初始化
        return IoTDAClient.newBuilder()
                .withCredential(auth)
                // 基础版：请选择IoTDARegion中的Region对象
                // .withRegion(IoTDARegion.CN_NORTH_4)
                // 标准版/企业版：需自行创建Region对象
                .withRegion(new Region(REGION_ID, ENDPOINT))
                .build();
    }

}
