package com.sptg.gateway.controller;

import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.dto.DeviceRemoteInfoDto;
import com.sptg.device.api.entity.*;
import com.sptg.device.api.feigns.*;
import com.sptg.permissions.api.entity.AppPackage;
import com.sptg.permissions.api.feigns.AppPackageFeign;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.statistics.api.entity.SysDeviceLog;
import com.sptg.statistics.api.feigns.SysDeviceLogFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * title: TestController
 * package: com.sptg.gateway.controller
 * description: 设备控制器
 *
 *
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class DeviceController {

    private final DeviceFeign deviceFeign;
    private final DeviceLogFeign deviceLogFeign;
    private final DeviceRegisterFeign deviceRegisterFeign;
    private final SysDeviceLogFeign sysDeviceLogFeign;
    private final DeviceRemoteInfoFeign deviceRemoteInfoFeign;

    /**
     * 设备心跳检测接口
     * @param serialNumber 设备信息
     * @return ResultBean<String>
     */
    @PostMapping(value = "/device/check/heartbeat")
    public ResultBean<String> heartbeat(@RequestBody String serialNumber){
        Device device = new Device();
        device.setSerialNumber(serialNumber);
        this.deviceFeign.heartbeat(device);
        Date nowTime = new Date();
        return new ResultBean<>(ResultEnum.SUCCESS,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(nowTime));
    }

    @PostMapping(value = "/device/heartbeat/check")
    public ResultBean<String> heartbeat(@RequestBody Device device){
        Assert.hasText(device.getSerialNumber(),"设备序列号必填");
//        Assert.hasText(device.getNetworkSignal(),"网络信号必填");
//        Assert.hasText(device.getNetworkType(),"网络类型必填");
        this.deviceFeign.heartbeat(device);
        Date nowTime = new Date();
        return new ResultBean<>(ResultEnum.SUCCESS,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(nowTime));
    }

    /**
     * 功能描述: 设备开机
     * @param device { serialNumber : 设备序列号,必填 }
     * @return ResultBean<Device> 设备信息及队列服务器信息
     *
     *
     */
    @PostMapping(value = "/device/status/start")
    public ResultBean<Device> getConnection(@RequestBody Device device){
        Assert.hasText(device.getSerialNumber(),"设备序列号不能为空");
//        Assert.notNull(device.getVersionNumber(),"设备版本号不能为空");
        return this.deviceRegisterFeign.getConnection(device);
    }

    /**
     * 功能描述: 大豪适配器
     * @return ResultBean<Device> 设备信息及队列服务器信息
     *
     *
     */
    @PostMapping(value = "/device/dh/status/start")
    public ResultBean<MqConf> getDHConnection(@RequestBody Device device){
//        Assert.hasText(device.getSerialNumber(),"设备序列号不能为空");
//        Assert.notNull(device.getVersionNumber(),"设备版本号不能为空");
        return this.deviceRegisterFeign.getDHConnection();
    }

    /**
     * 功能描述: 设备故障
     * @param device
     * {
     *     serialNumber :   设备序列号,必填
     *     remark       :   备注（故障原因）,选填
     * }
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/device/status/fault")
    public ResultBean<Boolean> fault(@RequestBody Device device){
        if (StringUtils.isEmpty(device.getSerialNumber())){
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        //  获取设备信息
        device = this.deviceFeign.getEntityBySerialNumber(device.getSerialNumber());
        Assert.notNull(device,"设备序列号不存在");
        SysDeviceLog log = new SysDeviceLog();
        //  设备基本信息
        log.setSerialNumber(device.getSerialNumber());
        log.setXqName(device.getXqName());
        log.setDyName(device.getDyName());
        log.setXqId(device.getXqId());
        log.setUnitId(device.getUnitId());
        log.setInstallPath(device.getInstallPath());
        //  设备区域信息
        log.setRegionProvince(device.getRegionProvince());
        log.setRegionCity(device.getRegionCity());
        log.setRegionArea(device.getRegionArea());
        //  设备机构相关信息
        log.setRootOrgId(device.getRootOrgId());
        log.setOrgPosition(device.getOrgPosition());
        //  事件描述
        log.setEvent(-1);
        log.setMessage(device.getRemark());
        log.setCreateDate(new Date());
        log.setStatus(OperationConstant.ZERO);
        //  保存设备日志记录
        this.sysDeviceLogFeign.addSysDeviceLog(log);
        return new ResultBean<>(ResultEnum.SUCCESS);
    }

    /**
     * 功能描述: 添加设备日志
     * @param deviceLog 设备日志信息
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/device/log/add")
    public ResultBean<Boolean> addLog(@RequestBody DeviceLog deviceLog){
        if (StringUtils.isEmpty(deviceLog.getSerialNumber()) || StringUtils.isEmpty(deviceLog.getContent())){
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        return this.deviceLogFeign.add(deviceLog);
    }

    private final AppPackageFeign appPackageFeign;
    private final ConfFeign confFeign;

    /**
     * 检查设备应用程序更新
     * @return ResultBean<AppPackage>
     */
    @PostMapping(value = "/device/check/update")
    public ResultBean<AppPackage> checkUpdate(@RequestBody AppPackage appPackage){
        Assert.hasText(appPackage.getDeviceFactory(),"设备厂商不能为空");
        Assert.hasText(appPackage.getDeviceModelNumber(),"设备型号不能为空");
        Assert.notNull(appPackage.getVersion(),"当前版本号不能为空");
        appPackage = this.appPackageFeign.getNewestVersion(appPackage);
        if (null != appPackage){
            String host = this.confFeign.getFileServerHost();
            appPackage.setDownloadUrl(host + appPackage.getDownloadUrl());
        }
        return new ResultBean<>(ResultEnum.SUCCESS,appPackage);
    }

    private final InstructPublishLogFeign instructPublishLogFeign;

    @PostMapping(value = "/device/instruct/callback")
    public ResultBean<Boolean> instructCallBack(@RequestBody InstructPublishLog publishLog){
        log.warn("---设备消费回调记录----");
        log.warn(JsonUtils.objectToJson(publishLog));
        Assert.notNull(publishLog.getId(),"Id不能为空");
        Assert.notNull(publishLog.getStatus(),"消费状态不能为空");
        return this.instructPublishLogFeign.instructCallback(publishLog);
    }

    @PostMapping(value = "/device/instruct/biz/callback")
    public ResultBean<Boolean> instructBizCallBack(@RequestBody InstructPublishLog publishLog){
        log.warn("---设备业务阶段性回调记录----");
        log.warn(JsonUtils.objectToJson(publishLog));
        Assert.notNull(publishLog.getId(),"Id不能为空");
        Assert.notNull(publishLog.getBizStatus(),"设备业务阶段性状态不能为空");
        return this.instructPublishLogFeign.instructBizCallback(publishLog);
    }

    @PostMapping(value = "/device/instruct/handle/callback")
    public ResultBean<Boolean> instructHandleCallBack(@RequestBody InstructPublishLog publishLog){
        log.warn("---设备处理状态回调记录----");
        log.warn(JsonUtils.objectToJson(publishLog));
        Assert.notNull(publishLog.getId(),"Id不能为空");
        Assert.notNull(publishLog.getHandleStatus(),"设备处理状态不能为空");
        return this.instructPublishLogFeign.instructHandleCallback(publishLog);
    }

    /**
     * 大豪设备指令的回调接口，通知SaaS平台，仅用于大豪
     * @param publishLog
     * @return
     */
    @PostMapping(value = "dh/device/instruct/callback")
    public ResultBean<Boolean> instructCallBackTest(@RequestBody InstructPublishLog publishLog){
//        Assert.notNull(publishLog.getId(),"Id不能为空");
//        Assert.notNull(publishLog.getStatus(),"状态不能为空");
        if(null != publishLog.getId()){
            return this.instructPublishLogFeign.dhInstructCallback(publishLog);
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 设备远程信息上传接口
     * @param deviceRemoteInfoDto
     * @return
     */
    @PostMapping(value = "/device/remote/info/upload")
    public ResultBean<Boolean> remoteInfoUpload(@RequestBody DeviceRemoteInfoDto deviceRemoteInfoDto){
        Assert.notNull(deviceRemoteInfoDto.getSerialNumber(),"设备序列号不能为空");
        ResultBean<Boolean> resultBean;
        Date today = new Date();
        DeviceRemoteInfo deviceRemoteInfo = this.deviceRemoteInfoFeign.getBySerialNumber(deviceRemoteInfoDto.getSerialNumber());
        if(deviceRemoteInfo == null){
            deviceRemoteInfoDto.setCreateDate(today);
            deviceRemoteInfoDto.setUpdateDate(today);
            deviceRemoteInfoDto.setStatus(OperationConstant.ZERO);
            resultBean = this.deviceRemoteInfoFeign.add(deviceRemoteInfoDto);
        }else{
            deviceRemoteInfoDto.setId(deviceRemoteInfo.getId());
            deviceRemoteInfoDto.setCreateDate(deviceRemoteInfo.getCreateDate());
            deviceRemoteInfoDto.setUpdateDate(today);
            deviceRemoteInfoDto.setStatus(deviceRemoteInfo.getStatus());
            BeanUtils.copyProperties(deviceRemoteInfoDto, deviceRemoteInfo);
            resultBean = this.deviceRemoteInfoFeign.edit(deviceRemoteInfo);
        }
        if(resultBean.getData()){
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }else{
            return new ResultBean<>(ResultEnum.ERROR, false);
        }
    }
}
