package com.xtd.project.hkmanager.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xtd.framework.redis.RedisCache;
import com.xtd.framework.web.controller.BaseController;
import com.xtd.framework.web.domain.AjaxResult;
import com.xtd.framework.web.page.TableDataInfo;
import com.xtd.project.hkmanager.entity.*;
import com.xtd.project.hkmanager.service.DeviceManagerService;
import com.xtd.project.hkmanager.service.DevicePhotoService;
import com.xtd.project.hkmanager.service.SynLogService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lym
 * @date 2020/4/2 16:53
 */
@RestController
@RequestMapping("/device")
@Api(description = "监控点管理")
public class DeviceController extends BaseController {

    @Autowired
    DeviceManagerService deviceManagerService;

    @Autowired
    DevicePhotoService devicePhotoService;

    @Autowired
    private RedisCache redisCache;
    @Autowired
    SynLogService synLogService;

    /**
     * 同步监控点信息
     * @return
     */
    @ApiOperation(value = "同步监控点信息",notes = "同步监控点信息")
    @ApiResponse(code = 200,message = "操作成功")
    @GetMapping("/synDevice")
    public AjaxResult synDevice(Integer pageNo,Integer pageSize,Integer saveNum){
        if (saveNum == null){
            saveNum = 0;
        }

        //路径
        String url = "/resource/v1/camera/advance/cameraList";
        Integer total = 0;
        //组装请求参数
        Map<String,Object> bodys = new HashMap<String, Object>();
        setPage(bodys,pageNo,pageSize);
        String body = JSON.toJSON(bodys).toString();

        //调用接口
        Object object = postSelect(url,body,null,null,null);
        if (object != null){
            Map json = (Map) object;
            total = (Integer) json.get("total");
            Object listData = json.get("list");
            //return AjaxResult.success(object);
            int i = batchSave(listData);
            saveNum += i;
            pageNo = Integer.parseInt(bodys.get("pageNo").toString());
            pageSize = Integer.parseInt(bodys.get("pageSize").toString());
            if (total > (pageNo * pageSize)){ //递归调用
                return synDevice(pageNo + 1,pageSize,saveNum);
            }

            saveSynLog(saveNum);
            if (saveNum < 1){
                return AjaxResult.success("没有可同步设备信息");
            }

            return AjaxResult.success("成功同步"+ saveNum +"个设备信息");
        }
        return AjaxResult.error();
    }

    /**
     * 批量添加
     * @param data
     * @return
     */
    public int batchSave(Object data){
        List<JSONObject> lists = (List<JSONObject>) data;
        Map<String, Device> map = new HashMap<>();
        Device device = null;
        for (JSONObject json:lists){
            device = new Device();
            String guid = json.get("cameraIndexCode").toString();
            device.setGuid(guid);
            device.setFkEncodeId(json.get("encodeDevIndexCode") == null ?null:json.get("encodeDevIndexCode").toString());
            device.setDeviceName(json.get("cameraName") == null?null:json.get("cameraName").toString());
            device.setType(json.get("cameraTypeName") == null?null:json.get("cameraTypeName").toString());
            device.setFkRegionId(json.get("regionIndexCode") == null?null:json.get("regionIndexCode").toString());
            device.setChannelNo(json.get("channelNo") == null?null:Integer.parseInt(json.get("channelNo").toString()));
            device.setTranstypeName(json.get("transTypeName") == null?null:json.get("transTypeName").toString());
            device.setDeviceStatus(getDeviceStatus(guid));
            device.setCreateUser(getUserId());
            device.setFkOrgGuid(getDeptId());
            map.put(guid,device);
        }

        int i = 0;
        if (map.size() > 0){
            i = deviceManagerService.batchSave(map);
        }

        return i;
    }

    //设备在线状态
    public int getDeviceStatus(String guid){
        //路径
        String url = "/nms/v1/online/camera/get";
        //组装请求参数
        Map<String,Object> bodys = new HashMap<String, Object>();
        List<String> indexCodes = new ArrayList<>();
        indexCodes.add(guid);
        bodys.put("indexCodes",indexCodes);
        setPage(bodys,1,10);
        String body = JSON.toJSON(bodys).toString();

        //调用接口
        Object object = postSelect(url,body,null,null,null);
        int status = 0; //0:离线， 1:在线
        if (object != null){
            Map map = (Map) object;
            Object listData = map.get("list");
            List<JSONObject> list = (List<JSONObject>) listData;
            JSONObject json = list.get(0);
            status = json.get("online") == null?0:(int) json.get("online");
        }

        return status;
    }

    /**
     * 添加同步日志
     * @param saveNum
     */
    private void saveSynLog(Integer saveNum){
        SynLog synLog = new SynLog();
        synLog.setType(1);

        JSONObject json = new JSONObject();
        json.put("saveNum",saveNum);
        synLog.setLogData(json.toJSONString());
        synLog.setCreateUser(getUserId());
        synLogService.saveSelective(synLog);
    }

    /**
     * 查询
     * @param device
     * @return
     */
    @ApiOperation(value = "列表查询",notes = "列表查询")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "device",value = "监控点信息",dataType = "DeviceForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/selectList")
    public TableDataInfo selectList(@RequestBody DeviceForm device){
        //device.setFkOrgGuid(getDeptId());
        List list = deviceManagerService.selectList(device);
        return getDataTable(list);
    }

    /**
     * 添加
     * @param device
     * @return
     */
    @ApiOperation(value = "添加监控点信息",notes = "添加监控点信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "device",value = "监控点信息",dataType = "Device")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/save")
    public AjaxResult save(@RequestBody @Valid Device device){
        device.setCreateUser(getUserId());
        device.setFkOrgGuid(getDeptId());
        int i = deviceManagerService.saveSelective(device);
        if (i > 0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 获取单个设备信息
     * @param guid
     * @return
     */
    @ApiOperation(value = "查询监控点详细信息",notes = "查询监控点详细信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "guid",value = "主键",dataType = "String")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @GetMapping("/getById")
    public AjaxResult getById(@RequestParam("guid") String guid){
        return AjaxResult.success(deviceManagerService.queryByPrimaryKey(guid));
    }

    @ApiOperation(value = "修改监控点信息",notes = "修改监控点信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "device",value = "监控点信息",dataType = "Device")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/update")
    public AjaxResult update(@RequestBody @Valid Device device){
        device.setModifiedUser(getUserId());
        int i = deviceManagerService.modifyByPrimaryKeySelective(device);
        if (i > 0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @ApiOperation(value = "删除监控点信息",notes = "删除监控点信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "guid",value = "主键",dataType = "String")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @GetMapping("/delete")
    public AjaxResult delete(@RequestParam("guid") String guid){
        int i = deviceManagerService.delByPrimaryKey(guid);
        if (i > 0){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 摄像头云台控制
     * @return
     */
    @ApiOperation(value = "云台控制",notes = "云台控制")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "videoPZTForm",value = "云台控制信息",dataType = "VideoPZTForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/videoPZT")
    public AjaxResult videoPZT(@RequestBody VideoPZTForm videoPZTForm){
        //路径
        String url = "/video/v1/ptzs/controlling";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<String, Object>();
        bodys.put("cameraIndexCode",videoPZTForm.getDeviceId());
        bodys.put("action",videoPZTForm.getAction());
        bodys.put("command",videoPZTForm.getCommand());
        bodys.put("speed",videoPZTForm.getSpeed());
        bodys.put("presetIndex",videoPZTForm.getPresetIndex());

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 摄像头手动抓图
     * @return
     */
    @ApiOperation(value = "动抓图",notes = "动抓图")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "guid",value = "主键",dataType = "String")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @GetMapping("/gradPhoto")
    public AjaxResult gradPhoto(@RequestParam("guid") String guid) {
        //路径
        String url = "/video/v1/manualCapture";
        //组装请求参数
        Map<String,Object> bodys = new HashMap<String, Object>();
        bodys.put("cameraIndexCode",guid);
        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            JSONObject jsonObject = (JSONObject) object;
            DevicePhoto devicePhoto = new DevicePhoto();
            devicePhoto.setFkOrgGuid(getDeptId());
            devicePhoto.setCreateUser(getUserId());
            devicePhoto.setFkDeviceId(guid);
            devicePhoto.setUrl(jsonObject.getString("picUrl"));
            devicePhotoService.saveSelective(devicePhoto);

            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    /*@GetMapping("/getPhoto")
    public AjaxResult getPhoto(){
        DevicePhotoForm devicePhoto = new DevicePhotoForm();
        devicePhoto.setFkOrgGuid(getDeptId());
        List<DevicePhoto> li = devicePhotoService.selectList(devicePhoto);
        return AjaxResult.success(li);
    }*/

    /**
     * 3D放大
     * @param videoPZTForm
     * @return
     */
    @ApiOperation(value = "3D控制",notes = "3D控制")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "videoPZTForm",value = "云台控制信息",dataType = "VideoPZTForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/pzt3D")
    public AjaxResult pzt3D(@RequestBody VideoPZTForm videoPZTForm){
        //路径
        String url = "/video/v1/ptzs/selZoom";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<String, Object>();
        bodys.put("cameraIndexCode",videoPZTForm.getDeviceId());
        bodys.put("startX",videoPZTForm.getStartX());
        bodys.put("startY",videoPZTForm.getStartY());
        bodys.put("endX",videoPZTForm.getEndX());
        bodys.put("endY",videoPZTForm.getEndY());

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 开始手动录像
     * @return
     */
    @ApiOperation(value = "开始手动录像",notes = "开始手动录像")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "videoPZTForm",value = "控制信息",dataType = "VideoPZTForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/startVideo")
    public AjaxResult startVideo(@RequestBody VideoPZTForm videoPZTForm){
        //路径
        String url = "/video/v1/manualRecord/start";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",videoPZTForm.getDeviceId());
        bodys.put("recordType",videoPZTForm.getRecordType()); //录像类型： 范围:0-65535，参考附录A.31,中心存储必填，设备存储不传入
        bodys.put("type",videoPZTForm.getType()); //下发的存储类型，0-中心存储 1-设备存储 如果不传入，默认为0-中心存储

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            Map map = (Map) object;
            redisCache.setCacheObject(videoPZTForm.getDeviceId(),map.get("taskID"));
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    /**
     * 停止手动录像
     * @return
     * taskID:手动录像编号
     */
    @ApiOperation(value = "停止手动录像",notes = "停止手动录像")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "videoPZTForm",value = "控制信息",dataType = "VideoPZTForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/stopVideo")
    public AjaxResult stopVideo(@RequestBody VideoPZTForm videoPZTForm){
        //路径
        String url = "/video/v1/manualRecord/stop";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",videoPZTForm.getDeviceId());
        bodys.put("taskID",videoPZTForm.getTaskID()); //手动录像编号
        bodys.put("type",videoPZTForm.getType()); //下发的存储类型，0-中心存储 1-设备存储 如果不传入，默认为0-中心存储

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            redisCache.deleteObject(videoPZTForm.getDeviceId());
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    @ApiOperation(value = "手动录像状态",notes = "手动录像状态")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "videoPZTForm",value = "控制信息",dataType = "VideoPZTForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/recordStatus")
    public AjaxResult RecordStatus(@RequestBody VideoPZTForm videoPZTForm){
        //路径
        String url = "/video/v1/manualRecord/status";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",videoPZTForm.getDeviceId());
        bodys.put("taskID",videoPZTForm.getTaskID()); //手动录像编号
        bodys.put("type",videoPZTForm.getType()); //下发的存储类型，0-中心存储 1-设备存储 如果不传入，默认为0-中心存储

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){//手动录像状态,0：未接入 1：正常执行 2：异常
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    /**
     * 预置点配置
     * @return
     */
    @ApiOperation(value = "预置点配置",notes = "预置点配置")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "presetConfigForm",value = "预置点配置信息",dataType = "PresetConfigForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/presetSave")
    public AjaxResult presetSave(@RequestBody @Valid PresetConfigForm presetConfigForm){
        //路径
        String url = "/video/v1/presets/addition";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",presetConfigForm.getDeviceId());
        bodys.put("presetName",presetConfigForm.getPresetName());
        bodys.put("presetIndex",presetConfigForm.getPresetIndex());

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    /**
     * 查询预置点配置信息
     * @return
     */
    @ApiOperation(value = "查询预置点配置信息",notes = "查询预置点配置信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "deviceId",value = "监控点id",dataType = "String")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @GetMapping("/presetSearches")
    public AjaxResult presetSearches(@RequestParam("deviceId") String deviceId){
        //路径
        String url = "/video/v1/presets/searches";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",deviceId);

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    @ApiOperation(value = "删除预置点配置",notes = "删除预置点配置")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "presetConfigForm",value = "预置点配置信息",dataType = "PresetConfigForm")
    )
    @ApiResponse(code = 200,message = "操作成功")
    @PostMapping("/presetdelete")
    public AjaxResult presetdelete(@RequestBody PresetConfigForm presetConfigForm){
        //路径
        String url = "/video/v1/presets/deletion";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",presetConfigForm.getDeviceId());
        bodys.put("presetIndex",presetConfigForm.getPresetIndex());

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    @ApiOperation(value = "获取预览url",notes = "获取预览url")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "playForm",value = "播放视频参数",dataType = "PlayForm")
    )
    @PostMapping("/previewUrl")
    public AjaxResult previewUrl(@RequestBody PlayForm playForm){
        //路径
        String url = "/video/v1/cameras/previewURLs";

        //组装请求参数
        Map<String,Object> bodys = new HashMap<>();
        bodys.put("cameraIndexCode",playForm.getDeviceId());
        bodys.put("streamType",playForm.getStreamType());
        bodys.put("protocol",playForm.getProtocol());
        bodys.put("transmode",playForm.getTransmode());
        bodys.put("expand",playForm.getExpand());

        String body = JSON.toJSON(bodys).toString();
        //调用接口
        Object object = postAction(url,body,null,null,null);
        if (object != null){
            return AjaxResult.success(object);
        }
        return AjaxResult.error();
    }

    /**
     *
     * @return
     */
    @ApiOperation(value = "获取安防平台配置信息",notes = "获取安防平台配置信息")
    @GetMapping("/getArtemisConfigInfo")
    public AjaxResult getArtemisConfigInfo(){
        ArtemisConfigInfo form = new ArtemisConfigInfo();
        form.setPath(OPENAPI_PATH);
        form.setAppkey(ARTEMISCONFIG_APPKEY);
        form.setAppsecret(ARTEMISCONFIG_APPSECRET);
        String host = ARTEMISCONFIG_HOST.substring(0,ARTEMISCONFIG_HOST.indexOf(":"));
        form.setHost(host);
        return AjaxResult.success(form);
    }
}
