package com.sptg.third.biz.grid.controller;

import cn.hutool.json.JSONUtil;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.third.api.contants.UrlContants;
import com.sptg.third.api.entity.grid.GridConfig;
import com.sptg.third.api.feigns.grid.GridVideoCloudFeign;
import com.sptg.third.biz.grid.service.GridConfigServiceInterface;
import com.sptg.video.cloud.api.entity.VCAccount;
import com.sptg.video.cloud.api.entity.VCDevice;
import com.sptg.video.cloud.api.feigns.VCAccountFeign;
import com.sptg.video.cloud.api.feigns.VCDeviceFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.*;

/**
 * @author zwx
 * @create 2020/11/28 20:23
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class GirdVideoCloudController implements GridVideoCloudFeign {

    private final GridConfigServiceInterface gridConfigServiceInterface;
    private final VCDeviceFeign vcDeviceFeign;
    private final VCAccountFeign vcAccountFeign;
    private final RestTemplate restTemplate;

    /**
     * 增量推送视频云账号到网格
     * @return
     */
    @Override
    @PostMapping(value = "/third/grid/videoCloud/account/increment/push")
    public ResultBean<String> gridVideoCloudAccountIncrementPush() {
        GridConfig gridConfig = this.gridConfigServiceInterface.getById(1L);
        ResultBean<List<VCAccount>> resultBean = this.vcAccountFeign.getList();
        List<VCAccount> vcAccountList = resultBean.getData();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(int i = 0; i < vcAccountList.size(); i++){
            VCAccount vcAccount = vcAccountList.get(i);
            if(vcAccount.getLastPushTime() == null){
                Map<String, Object> map = buildGridVCAccountData(vcAccount);
                mapList.add(map);
            }
        }
        if(mapList.size() > 0){
            Map resultMap = getRequestResult(mapList, gridConfig, UrlContants.Grid.VIDEO_CLOUD_ACCOUNT_SYNC);
            if(resultMap.get("code").equals(200)){
                for(int i = 0; i < vcAccountList.size(); i++){
                    VCAccount vcAccount = vcAccountList.get(i);
                    vcAccount.setLastPushTime(new Date());
                }
                this.vcAccountFeign.updateBatch(vcAccountList);
                return new ResultBean<>(ResultEnum.SUCCESS);
            }else{
                return new ResultBean<>(ResultEnum.FAILURE, (String) resultMap.get("msg"));
            }
        }else{
            return new ResultBean<>(ResultEnum.SUCCESS);
        }
    }

    /**
     * 增量推送视频云账号到网格
     * @return
     */
    @Override
    @PostMapping(value = "/third/grid/videoCloud/account/total/push")
    public ResultBean<String> gridVideoCloudAccountTotalPush() {
        GridConfig gridConfig = this.gridConfigServiceInterface.getById(1L);
        ResultBean<List<VCAccount>> resultBean = this.vcAccountFeign.getList();
        List<VCAccount> vcAccountList = resultBean.getData();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(int i = 0; i < vcAccountList.size(); i++){
            VCAccount vcAccount = vcAccountList.get(i);
            Map<String, Object> map = buildGridVCAccountData(vcAccount);
            mapList.add(map);
        }
        if(mapList.size() > 0){
            Map resultMap = getRequestResult(mapList, gridConfig, UrlContants.Grid.VIDEO_CLOUD_ACCOUNT_SYNC);
            if(resultMap.get("code").equals(200)){
                for(int i = 0; i < vcAccountList.size(); i++){
                    VCAccount vcAccount = vcAccountList.get(i);
                    vcAccount.setLastPushTime(new Date());
                }
                this.vcAccountFeign.updateBatch(vcAccountList);
                return new ResultBean<>(ResultEnum.SUCCESS);
            }else{
                return new ResultBean<>(ResultEnum.FAILURE, (String) resultMap.get("msg"));
            }
        }else{
            return new ResultBean<>(ResultEnum.SUCCESS);
        }
    }

    /**
     * 增量推送监控设备到网格
     * @return
     */
    @Override
    @PostMapping(value = "/third/grid/videoCloud/device/increment/push")
    public ResultBean<String> gridVideoCloudDeviceIncrementPush() {
        GridConfig gridConfig = this.gridConfigServiceInterface.getById(1L);
        ResultBean<List<VCDevice>> resultBean = this.vcDeviceFeign.getList();
        List<VCDevice> vcDeviceList = resultBean.getData();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(int i = 0; i < vcDeviceList.size(); i++){
            VCDevice vcDevice = vcDeviceList.get(i);
            if(vcDevice.getLastPushTime() == null){ //没有推送时间的，说明没有推送过，需要推送出去
                Map<String, Object> map = buildGridVCDeviceData(vcDevice);
                mapList.add(map);
            }
        }
        if(mapList.size() > 0){
            Map resultMap = getRequestResult(mapList, gridConfig, UrlContants.Grid.VIDEO_CLOUD_DEVICE_SYNC);
            if(resultMap.get("code").equals(200)){
                for(int i = 0; i < vcDeviceList.size(); i++){
                    VCDevice vcDevice = vcDeviceList.get(i);
                    vcDevice.setLastPushTime(new Date());
                }
                this.vcDeviceFeign.updateBatch(vcDeviceList);
                return new ResultBean<>(ResultEnum.SUCCESS);
            }else{
                return new ResultBean<>(ResultEnum.FAILURE, (String) resultMap.get("msg"));
            }
        }else{
            return new ResultBean<>(ResultEnum.SUCCESS);
        }
    }

    @Override
    @PostMapping(value = "/third/grid/videoCloud/device/total/push")
    public ResultBean<String> gridVideoCloudDeviceTotalPush() {
        GridConfig gridConfig = this.gridConfigServiceInterface.getById(1L);
        ResultBean<List<VCDevice>> resultBean = this.vcDeviceFeign.getList();
        List<VCDevice> vcDeviceList = resultBean.getData();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for(int i = 0; i < vcDeviceList.size(); i++){
            VCDevice vcDevice = vcDeviceList.get(i);
            Map<String, Object> map = buildGridVCDeviceData(vcDevice);
            mapList.add(map);
        }
        if(mapList.size() > 0){
            Map resultMap = getRequestResult(mapList, gridConfig, UrlContants.Grid.VIDEO_CLOUD_DEVICE_SYNC);
            if(resultMap.get("code").equals(200)){
                for(int i = 0; i < vcDeviceList.size(); i++){
                    VCDevice vcDevice = vcDeviceList.get(i);
                    vcDevice.setLastPushTime(new Date());
                }
                this.vcDeviceFeign.updateBatch(vcDeviceList);
                return new ResultBean<>(ResultEnum.SUCCESS);
            }else{
                return new ResultBean<>(ResultEnum.FAILURE, (String) resultMap.get("msg"));
            }
        }else{
            return new ResultBean<>(ResultEnum.SUCCESS);
        }
    }

    /**
     * 增构建网格视频云账号接收对象
     * @param vcAccount
     * @return
     */
    private Map<String, Object> buildGridVCAccountData(VCAccount vcAccount){
        Map<String, Object> map = new HashMap<>();
        map.put("oldId", vcAccount.getId());
        map.put("accountName", vcAccount.getAccountName());
        map.put("provinceCode", vcAccount.getProvinceCode());
        map.put("provinceName", vcAccount.getProvinceName());
        map.put("cityCode", vcAccount.getCityCode());
        map.put("cityName", vcAccount.getCityName());
        map.put("countryCode", vcAccount.getCountryCode());
        map.put("countryName", vcAccount.getCountryName());
        map.put("email", vcAccount.getEmail());
        map.put("isAsUser", vcAccount.getIsAsUser());
        map.put("lastLoginTimeString", vcAccount.getLastLoginTimeString());
        map.put("mobile", vcAccount.getMobile());
        map.put("orgCode", vcAccount.getOrgCode());
        map.put("orgName", vcAccount.getOrgName());
        map.put("qq", vcAccount.getQq());
        map.put("realName", vcAccount.getRealName());
        map.put("sex", vcAccount.getSex());
        map.put("userPwd", vcAccount.getUserPwd());
        return map;
    }

    /**
     * 构建网格视频监控设备接收对象
     * @param vcDevice
     * @return
     */
    private Map<String, Object> buildGridVCDeviceData(VCDevice vcDevice){
        Map<String, Object> map = new HashMap<>();
        map.put("oldId", vcDevice.getDeviceId());
        map.put("deviceId", vcDevice.getDeviceId());
        map.put("deviceName", vcDevice.getDeviceName());
        map.put("deviceNum", vcDevice.getDeviceNum());
        map.put("devicePassword", vcDevice.getPassword());
        map.put("deviceType", vcDevice.getDeviceType());
        map.put("modelSequence", vcDevice.getModelSequence());
        map.put("protocolType", vcDevice.getProtocolType());
        map.put("isOnline", vcDevice.getIsOnline());
        map.put("isSupportCloudStorage", vcDevice.getIsSupportCloudStorage());
        map.put("isSupportLocalStorage", vcDevice.getIsSupportLocalStorage());
        map.put("isSupportPtz", vcDevice.getIsSupportPtz());
        map.put("isSupportMotionDetection", vcDevice.getIsSupportMotionDetection());
        map.put("isSupportManualAlarm", vcDevice.getIsSupportManualAlarm());
        map.put("isSupportExternalAlarmSwitch", vcDevice.getIsSupportExternalAlarmSwitch());
        map.put("isHaveInversion", vcDevice.getIsHaveInversion());
        map.put("cloudStorageType", vcDevice.getCloudStorageType());
        map.put("cloudStorageConfId", vcDevice.getCloudStorageConfId());
        map.put("streamType", vcDevice.getStreamType());
        map.put("address", vcDevice.getAddress());
        map.put("isOwner", vcDevice.getIsOwner());
        map.put("parentNvrNum", vcDevice.getParentNvrNum());
        map.put("alarmStatus", vcDevice.getAlarmStatus());
        map.put("longitude", vcDevice.getLatitude());
        map.put("latitude", vcDevice.getLatitude());
        map.put("maintainer", vcDevice.getMaintainer());
        map.put("block", vcDevice.getBlock());
        map.put("blockTime", vcDevice.getBlockTime());
        map.put("routeId", vcDevice.getRouteId());
        map.put("equipType", vcDevice.getEquipType());
        map.put("updateStateTimeString", vcDevice.getUpdateStateTimeString());
        map.put("accountName", vcDevice.getAccountName());
        return map;
    }

    /**
     * 获取请求结果
     * @param mapList  请求体
     * @param gridConfig host+port
     * @param apiPath 请求路径
     * @return
     */
    private Map getRequestResult(List<Map<String, Object>> mapList, GridConfig gridConfig, String apiPath){
        ResponseEntity responseEntity = null;
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE,"application/json;charset=UTF-8");
        headers.add("Blade-Auth",gridConfig.getToken());
        HttpEntity<String> requestEntity = new HttpEntity<String>(JSONUtil.toJsonStr(mapList), headers);
        ParameterizedTypeReference<Object> reference = new ParameterizedTypeReference<Object>() {
        };
        String url = gridConfig.getGridHost()+":"+gridConfig.getGridPort()+apiPath;
        URI uri = URI.create(url);
        responseEntity = this.restTemplate.exchange(uri, HttpMethod.POST, requestEntity, reference);
        return (Map) responseEntity.getBody();
    }
}
