package com.yuchen.saas.park.service.iot;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.reflect.TypeToken;
import com.thinkunion.park.service.common.iot.capability.devicemodel.DeviceModel;
import com.thinkunion.park.service.common.iot.util.ModelGsonUtils;
import com.thinkunion.sdk.iot.IoTClient;
import com.thinkunion.sdk.iot.bean.api.*;
import com.thinkunion.sdk.iot.bean.pojo.DeviceInfo;
import com.thinkunion.sdk.iot.bean.pojo.ProductInfo;
import com.thinkunion.sdk.iot.exception.IotClientException;
import com.thinkunion.sdk.iot.exception.IotServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class IoTRemoteService {

    @Resource
    private IoTClient ioTClient;

    /**
     * 查询产品的物模型信息
     */
    public DeviceModel getDeviceModel(String productKey) {
        try {
            QueryProductProfileRequest request = new QueryProductProfileRequest();
            request.setProductKey(productKey);
            QueryProductProfileResponse response = this.ioTClient.send(request);
            if (response.getCode().equals("200")) {
                return ModelGsonUtils.fromJson(response.getData().getModel(), new TypeToken<DeviceModel>() {
                }.getType());
            }
            return null;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 查询所有产品信息
     */
    public List<ProductInfo> findAllProduct() {
        try {
            QueryProductListRequest request = new QueryProductListRequest();
            QueryProductListResponse response = ioTClient.send(request);
            if (response.getCode().equals("200")) {
                return response.getData();
            } else {
                return Arrays.asList();
            }
        } catch (IotServerException | IotClientException e) {
            log.error(e.getMessage(), e);
            return Arrays.asList();
        }
    }

    /**
     * 查询产品的设备列表
     */
    public List<DeviceInfo> findDeviceList(String productKey) {
        try {
            QueryDeviceListByProductKeyRequest request = new QueryDeviceListByProductKeyRequest();
            request.setProductKey(productKey);
            QueryDeviceListByProductKeyResponse response = ioTClient.send(request);
            if (response.getCode().equals("200")) {
                return response.getData();
            } else {
                return Arrays.asList();
            }
        } catch (IotServerException | IotClientException e) {
            log.error(e.getMessage(), e);
            return Arrays.asList();
        }
    }

    /**
     * 设置设备属性值
     */
    public boolean setProperty(Map<String, Object> params) {
        try {
            SettingDevicePropertyRequest request = new SettingDevicePropertyRequest();
            request.setProductKey(params.get("productKey").toString());
            request.setDeviceName(params.get("deviceName").toString());
            JSONObject paramsObject = JSON.parseObject(JSON.toJSONString(params.get("params")));
            paramsObject.forEach((key, obj) -> {
                if (obj instanceof JSON) {
                    JSON json = (JSON) obj;
                    request.addParam(key, json.toJSONString());
                } else {
                    request.addParam(key, obj.toString());
                }
            });
            SettingDevicePropertyResponse response = this.ioTClient.send(request);
            if (response.getCode().equals("200")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 调用设备服务能力
     */
    public boolean callService(Map<String, Object> params) {
        try {
            CallingDeviceServiceRequest request = new CallingDeviceServiceRequest();
            request.setProductKey(params.get("productKey").toString());
            request.setDeviceName(params.get("deviceName").toString());
            request.setIdentifier(params.get("identify").toString());
            JSONObject paramsObject = JSON.parseObject(JSON.toJSONString(params.get("params")));
            paramsObject.forEach((key, obj) -> {
                if (obj instanceof JSON) {
                    JSON json = (JSON) obj;
                    request.addParam(key, json.toJSONString());
                } else {
                    request.addParam(key, obj.toString());
                }
            });
            CallingDeviceServiceResponse response = this.ioTClient.send(request);
            if (response.getCode().equals("200")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            //e.printStackTrace();
            log.error(e.getMessage(), e);

            return false;
        }
    }

    /**
     * 调用设备服务能力，返回结果
     */
    public CallingDeviceServiceResponse callServiceReturn(Map<String, Object> params) {
        try {
            CallingDeviceServiceRequest request = new CallingDeviceServiceRequest();
            request.setProductKey(params.get("productKey").toString());
            request.setDeviceName(params.get("deviceName").toString());
            request.setIdentifier(params.get("identify").toString());
            JSONObject paramsObject = JSON.parseObject(JSON.toJSONString(params.get("params")));
            paramsObject.forEach((key, obj) -> {
                if (obj instanceof JSON) {
                    JSON json = (JSON) obj;
                    request.addParam(key, json.toJSONString());
                } else {
                    request.addParam(key, obj.toString());
                }
            });
            log.info("======调用iot最终传参：{}",JSON.toJSONString(request));
            return this.ioTClient.send(request);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }
}
