package com.sptg.iot.api.util;

import com.sptg.common.core.constant.HttpConstant;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.iot.api.beans.ApiResultBean;
import com.sptg.iot.api.beans.IotReturnCode;
import com.sptg.iot.api.beans.PageData;
import com.sptg.iot.api.entity.*;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zwx
 * @create 2020/10/20 21:54
 */
public class IotHttpUtil {

    private IotSysConf iotSysConf;

    private final RestTemplate restTemplate = new RestTemplate();

    public IotHttpUtil(IotSysConf iotSysConf){
        this.iotSysConf = iotSysConf;
    }

    /**
     * 认证接口，返回accessToken，具有有效期
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean auth(Map<String, Object> bizParamsMap){
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON_UTF8);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = "https://scep.ctwing.cn/paas/authentication/api/v1/apps/access_token";
        URI uri = URI.create(url);
        responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
        return responseEntity.getBody();
    }

    /**
     * AEP 产品信息列表
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean syncAepProductList(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        int page = 0;
        int page_size = 100;
        boolean flag = true;
        PageData<IotAepProduct> pageData = new PageData<>();
        List<IotAepProduct> items = new ArrayList<>();
        pageData.setItems(items);
        ApiResultBean<PageData<IotAepProduct>> apiResultBean = new ApiResultBean<>();
        while(flag){
            ResponseEntity<ApiResultBean<PageData<IotAepProduct>>> responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", HttpConstant.APPLICATION_JSON_UTF8);
            headers.add("accessToken", accessToken);
            page = page + 1;
            bizParamsMap.put("page", page);
            bizParamsMap.put("page_size", page_size);
            HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
            ParameterizedTypeReference<ApiResultBean<PageData<IotAepProduct>>> reference = new ParameterizedTypeReference<ApiResultBean<PageData<IotAepProduct>>>() {};
            String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/device/getProductList";
            URI uri = URI.create(url);
            try{
                responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
                ApiResultBean<PageData<IotAepProduct>> infoApiResultBean = responseEntity.getBody();
                PageData<IotAepProduct> data = infoApiResultBean.getData();
                pageData.setCount(data.getCount());
                List<IotAepProduct> list = data.getList();
                if(list == null || (list != null && list.size() < page_size)){
                    flag = false;
                }
                if(list != null){
                    items.addAll(list);
                }
            }catch (HttpClientErrorException e){
                ApiResultBean<PageData<IotAepProduct>> errorApiResultBean = new ApiResultBean<>();
                errorApiResultBean.setCode(e.getStatusCode().value());
                errorApiResultBean.setMsg(e.getMessage());
                return errorApiResultBean;
            }
        }
        apiResultBean.setCode(OperationConstant.ZERO);
        apiResultBean.setMsg("成功");
        apiResultBean.setData(pageData);
        return apiResultBean;
    }

    /**
     * 感知平台设备注册
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean register(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON_UTF8);
        headers.add("accessToken", accessToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/device/create";
        URI uri = URI.create(url);
        responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
        return responseEntity.getBody();
    }

    /**
     * 同步设备列表
     * @param bizParamsMap 请求参数
     * @Param prefix 地址前缀
     * @return
     */
    public ApiResultBean<PageData<IotDevice>> syncIotDeviceList(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        int page = 0;
        int page_size = 100;
        boolean flag = true;
        PageData<IotDevice> pageData = new PageData<>();
        List<IotDevice> items = new ArrayList<>();
        pageData.setItems(items);
        ApiResultBean<PageData<IotDevice>> apiResultBean = new ApiResultBean<>();
        while(flag){
            ResponseEntity<ApiResultBean<PageData<IotDevice>>> responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
            headers.add("accessToken", accessToken);
            page = page + 1;
            bizParamsMap.put("page", page);
            bizParamsMap.put("page_size", page_size);
            HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
            ParameterizedTypeReference<ApiResultBean<PageData<IotDevice>>> reference = new ParameterizedTypeReference<ApiResultBean<PageData<IotDevice>>>() {};
            String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/device/list";
            URI uri = URI.create(url);
            try{
                responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
                ApiResultBean<PageData<IotDevice>> infoApiResultBean = responseEntity.getBody();
                PageData<IotDevice> data = infoApiResultBean.getData();
                pageData.setCount(data.getCount());
                int size = data.getItems().size();
                if(size < page_size){
                    flag = false;
                }
                items.addAll(data.getItems());
            }catch (HttpClientErrorException e){
                ApiResultBean<PageData<IotDevice>> errorApiResultBean = new ApiResultBean<>();
                errorApiResultBean.setCode(e.getStatusCode().value());
                errorApiResultBean.setMsg(e.getMessage());
                return errorApiResultBean;
            }
        }
        apiResultBean.setCode(OperationConstant.ZERO);
        apiResultBean.setMsg("成功");
        apiResultBean.setData(pageData);
        return apiResultBean;
    }

    /**
     * 设备查询（同步设备详情）
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean<IotDevice> syncIotDeviceDetail(Map<String, Object> bizParamsMap, String urlPrefix, String accessToken){
        ResponseEntity<ApiResultBean<IotDevice>> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, HttpConstant.APPLICATION_JSON);
        headers.add(HttpHeaders.CONTENT_LENGTH, "256");
        headers.add("accessToken", accessToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean<IotDevice>> reference = new ParameterizedTypeReference<ApiResultBean<IotDevice>>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + urlPrefix + "/device/search";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean<IotDevice> apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

    /**
     * 同步告警列表
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean<PageData<IotAlarm>> syncIotAlarmList(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        int page = 0;
        int page_size = 100;
        boolean flag = true;
        PageData<IotAlarm> pageData = new PageData<>();
        List<IotAlarm> items = new ArrayList<>();
        pageData.setItems(items);
        ApiResultBean<PageData<IotAlarm>> apiResultBean = new ApiResultBean<>();
        while(flag){
            ResponseEntity<ApiResultBean<PageData<IotAlarm>>> responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
            headers.add("accessToken", accessToken);
            page = page + 1;
            bizParamsMap.put("page", page);
            bizParamsMap.put("page_size", page_size);
            HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
            ParameterizedTypeReference<ApiResultBean<PageData<IotAlarm>>> reference = new ParameterizedTypeReference<ApiResultBean<PageData<IotAlarm>>>() {};
            String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/alarm/list";
            URI uri = URI.create(url);
            try{
                responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
                ApiResultBean<PageData<IotAlarm>> infoApiResultBean = responseEntity.getBody();
                PageData<IotAlarm> data = infoApiResultBean.getData();
                pageData.setCount(data.getCount());
                int size = data.getItems().size();
                if(size < page_size){
                    flag = false;
                }
                items.addAll(data.getItems());
            }catch (HttpClientErrorException e){
                ApiResultBean<PageData<IotAlarm>> errorApiResultBean = new ApiResultBean<>();
                errorApiResultBean.setCode(e.getStatusCode().value());
                errorApiResultBean.setMsg(e.getMessage());
                return apiResultBean;
            }
        }
        apiResultBean.setCode(OperationConstant.ZERO);
        apiResultBean.setMsg("成功");
        apiResultBean.setData(pageData);
        return apiResultBean;
    }

    /**
     * 同步告警详情
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean<IotAlarm> syncIotAlarmDetail(Map<String, Object> bizParamsMap, String urlPrefix, String accessToken){
        ResponseEntity<ApiResultBean<IotAlarm>> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
        headers.add("accessToken", accessToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean<IotAlarm>> reference = new ParameterizedTypeReference<ApiResultBean<IotAlarm>>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + urlPrefix + "/alarm/search";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean<IotAlarm> apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

    /**
     * 同步告警阈值列表
     * @param bizParamsMap
     * @param urlPrefix 地址前缀
     * @return
     */
    public ApiResultBean<PageData<IotAlarmThreshold>> syncAlarmThresholdList(Map<String, Object> bizParamsMap, String urlPrefix, String accessToken){
        int page = 0;
        int page_size = 100;
        boolean flag = true;
        PageData<IotAlarmThreshold> pageData = new PageData<>();
        List<IotAlarmThreshold> items = new ArrayList<>();
        pageData.setItems(items);
        ApiResultBean<PageData<IotAlarmThreshold>> apiResultBean = new ApiResultBean<>();
        while(flag){
            ResponseEntity<ApiResultBean<PageData<IotAlarmThreshold>>> responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
            headers.add("accessToken", accessToken);
            page = page + 1;
            bizParamsMap.put("page", page);
            bizParamsMap.put("page_size", page_size);
            HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
            ParameterizedTypeReference<ApiResultBean<PageData<IotAlarmThreshold>>> reference = new ParameterizedTypeReference<ApiResultBean<PageData<IotAlarmThreshold>>>() {};
            String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + urlPrefix + "/alarm/thresholdList";
            URI uri = URI.create(url);
            try{
                responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
                ApiResultBean<PageData<IotAlarmThreshold>> infoApiResultBean = responseEntity.getBody();
                PageData<IotAlarmThreshold> data = infoApiResultBean.getData();
                pageData.setCount(data.getCount());
                int size = data.getItems().size();
                if(size < page_size){
                    flag = false;
                }
                items.addAll(data.getItems());
            }catch (HttpClientErrorException e){
                ApiResultBean<PageData<IotAlarmThreshold>> errorApiResultBean = new ApiResultBean<>();
                errorApiResultBean.setCode(e.getStatusCode().value());
                errorApiResultBean.setMsg(e.getMessage());
                return apiResultBean;
            }
        }
        apiResultBean.setCode(OperationConstant.ZERO);
        apiResultBean.setMsg("成功");
        apiResultBean.setData(pageData);
        return apiResultBean;
    }

    /**
     * 同步告警工单列表
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean<PageData<IotAlarmWorkOrder>> syncAlarmWorkOrderList(Map<String, Object> bizParamsMap, String urlPrefix, String accessToken){
        int page = 0;
        int page_size = 100;
        boolean flag = true;
        PageData<IotAlarmWorkOrder> pageData = new PageData<>();
        List<IotAlarmWorkOrder> items = new ArrayList<>();
        pageData.setItems(items);
        ApiResultBean<PageData<IotAlarmWorkOrder>> apiResultBean = new ApiResultBean<>();
        while(flag){
            ResponseEntity<ApiResultBean<PageData<IotAlarmWorkOrder>>> responseEntity = null;
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
            headers.add("accessToken", accessToken);
            page = page + 1;
            bizParamsMap.put("page", page);
            bizParamsMap.put("page_size", page_size);
            HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
            ParameterizedTypeReference<ApiResultBean<PageData<IotAlarmWorkOrder>>> reference = new ParameterizedTypeReference<ApiResultBean<PageData<IotAlarmWorkOrder>>>() {};
            String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + urlPrefix + "/order/list";
            URI uri = URI.create(url);
            try{
                responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
                ApiResultBean<PageData<IotAlarmWorkOrder>> infoApiResultBean = responseEntity.getBody();
                PageData<IotAlarmWorkOrder> data = infoApiResultBean.getData();
                pageData.setCount(data.getCount());
                int size = data.getItems().size();
                if(size < page_size){
                    flag = false;
                }
                items.addAll(data.getItems());
            }catch (HttpClientErrorException e){
                ApiResultBean<PageData<IotAlarmWorkOrder>> errorApiResultBean = new ApiResultBean<>();
                errorApiResultBean.setCode(e.getStatusCode().value());
                errorApiResultBean.setMsg(e.getMessage());
                return apiResultBean;
            }
        }
        apiResultBean.setCode(OperationConstant.ZERO);
        apiResultBean.setMsg("成功");
        apiResultBean.setData(pageData);
        return apiResultBean;
    }

    /**
     * 同步告警工单列表
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean updateAlarmWorkOrder(Map<String, Object> bizParamsMap, String urlPrefix, String accessToken){
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
        headers.add("accessToken", accessToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + urlPrefix + "/order/update";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

    /**
     * 订阅接口
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean subscribe(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
        headers.add("accessToken", accessToken);
        HttpEntity<String> requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/setting/subscribe";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

    /**
     * 订阅接口查询
     * @param bizParamsMap
     * @return
     */
    public ApiResultBean inquireSubscribe(Map<String, Object> bizParamsMap, String prefix, String accessToken){
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON);
        headers.add("accessToken", accessToken);
        HttpEntity requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/setting/inquire";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

    public ApiResultBean iotAlarmSendSms(Map<String, Object> bizParamsMap, String prefix, String accessToken) {
        ResponseEntity<ApiResultBean> responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", HttpConstant.APPLICATION_JSON_UTF8);
        headers.add("accessToken", accessToken);
        HttpEntity requestEntity = new HttpEntity<>(JsonUtils.objectToJson(bizParamsMap),headers);
        ParameterizedTypeReference<ApiResultBean> reference = new ParameterizedTypeReference<ApiResultBean>() {};
        String url = iotSysConf.getHost() + ":" + iotSysConf.getPort() + "/" + prefix + "/sms/sendSms";
        URI uri = URI.create(url);
        try{
            responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
            return responseEntity.getBody();
        }catch (HttpClientErrorException e){
            ApiResultBean apiResultBean = new ApiResultBean<>();
            apiResultBean.setCode(e.getStatusCode().value());
            apiResultBean.setMsg(e.getMessage());
            return apiResultBean;
        }
    }

}
