package com.fs.watch.controller;

import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.ServiceException;
import com.fs.common.utils.StringUtils;
import com.fs.company.domain.CompanyUser;
import com.fs.his.utils.RedisCacheUtil;
import com.fs.watch.domain.*;
import com.fs.watch.domain.vo.AlarmClockVos;
import com.fs.watch.param.WatchSetUpSendParam;
import com.fs.watch.scheduled.DynamicSendMedicationTask;
import com.fs.watch.scheduled.DynamicSendStudyTask;
import com.fs.watch.service.DeviceSetUpService;
import com.fs.watch.service.WatchSendMsgSetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisServer;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/device/set/up")
public class DeviceSetUpController extends BaseController {
    @Autowired
    private DeviceSetUpService deviceSetUpService;
    @Autowired
    private DynamicSendMedicationTask dynamicSendMedicationTask;
    @Autowired
    private DynamicSendStudyTask dynamicSendStudyTask;
    @Autowired
    private WatchSendMsgSetService watchSendMsgSetService;
    /**
     * 获取用户信息(app用户)
     *
     * @param deviceId 用户编号
     * @return 结果
     */
    @GetMapping("/getUserInfo")
    public AjaxResult getUserInfo(@RequestParam("deviceId") String deviceId) {
        return AjaxResult.success(deviceSetUpService.getUserinfo(deviceId));
    }

    /**
     * 下发用户设置到设备
     *
     * @param userInfo 用户设置
     * @return 结果
     */
    @PostMapping("/userinfo")
    public AjaxResult userinfo(@RequestBody UserInfo userInfo) {
        return toAjax(deviceSetUpService.userinfo(userInfo));
    }

    /**
     * 设备实时定位
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/realtime/location")
    public AjaxResult realtimeLocation(@RequestParam("deviceNumber") String deviceNumber) {
        return deviceSetUpService.realtimeLocation(deviceNumber)?AjaxResult.success():AjaxResult.error("设备离线!");
    }

    /**
     * 设备数据一键同步
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/datasync")
    public AjaxResult datasync(@RequestParam("deviceNumber") String deviceNumber) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return AjaxResult.success(deviceSetUpService.datasync(deviceNumber));
        }
        return toAjax(false);
    }

    /**
     * 设备跌倒检测开关
     *
     * @param deviceNumber 设备编号
     * @param flag         开/关
     * @return 结果
     */
    @GetMapping("/fallcheck")
    public AjaxResult fallcheck(@RequestParam("deviceNumber") String deviceNumber, @RequestParam("flag") Boolean flag) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.fallcheck(deviceNumber, flag));
        }
        return toAjax(false);

    }

    /**
     * 设备自动定位开关
     *
     * @param deviceNumber 设备编号
     * @param flag         开/关
     * @param time         时间
     * @param mode         耗电模式
     * @return 结果
     * gps_interval_time - unit is minute
     * power_mode - 可选，设备省电设置：
     * 1 - low耗电
     * 2 - mid耗电
     * 3 - high耗电
     * 这个指令仅对H200生效，其他设备请使用 设备数据上传间隔设置
     */
    @GetMapping("/autolocate")
    public AjaxResult autolocate(@RequestParam("deviceNumber") String deviceNumber,
                                 @RequestParam("flag") Boolean flag,
                                 @RequestParam("time") Integer time,
                                 @RequestParam("mode") Integer mode
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.autolocate(deviceNumber, flag, time, mode));
        }
        return toAjax(false);
    }

    /**
     * 下发通讯录
     *
     * @param phoneBooks 通讯录列表
     * @return 结果
     * sos - 是否紧急联系人, 要求至少有一个号码是SOS的
     * forbid - 可选，1 拦截陌生来电, 2 不拦截陌生来电。不传的时候不设置陌生来电拦截
     */
    @PostMapping("/phonebook/sync")
    public AjaxResult phonebook(@RequestBody PhoneBooks phoneBooks) {
        if (StringUtils.isNotBlank(phoneBooks.getDeviceId())) {
            return deviceSetUpService.phonebook(phoneBooks);
        }
        return toAjax(false);
    }

    /**
     * 清空通讯录
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/phonebook/clear")
    public AjaxResult phonebookClear(@RequestParam("deviceNumber") String deviceNumber) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.phonebookClear(deviceNumber));

        }
        return toAjax(false);
    }

    /**
     * 设备数据上传间隔设置
     *
     * @param deviceNumber 设备编号
     * @param flag         开/关
     * @param time         时间
     * @param mode         耗电模式
     * @return 结果
     * <p>
     * gps_interval_time - unit is minute
     * power_mode - 可选，设备省电设置：
     * 1 - low耗电;手表放置和进入睡眠的时候会关闭4G模块，无法上传数据，无法接听呼入电话
     * 2 - mid耗电;手表放置的时候不会关闭4G模块，可以上传数据，接听呼入电话；手表进入睡眠的时候会关闭4G模块，无法上传数据，无法接听呼入电话
     * 3 - high耗电;手表放置和进入睡眠的时候，都不会关闭4G模块，数据上传和电话呼入呼出不受影响
     */
    @GetMapping("/datafreq")
    public AjaxResult datafreq(@RequestParam("deviceNumber") String deviceNumber,
                               @RequestParam("flag") Boolean flag,
                               @RequestParam("time") Integer time,
                               @RequestParam("mode") Integer mode
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.datafreq(deviceNumber, flag, time, mode));

        }
        return toAjax(false);
    }

    /**
     * 翻腕亮屏设置
     *
     * @param deviceNumber 设备编号
     * @param flag         开/关
     * @param start        开始
     * @param end          结束
     * @return 结果
     * open - true 打开, false 关闭
     * start_hour - start hour of lcd gesture, 0 - 23
     * end_hour - end hour of lcd gesture, 0 - 23
     */
    @GetMapping("/lcdgesture")
    public AjaxResult lcdgesture(@RequestParam("deviceNumber") String deviceNumber,
                                 @RequestParam("flag") Boolean flag,
                                 @RequestParam(value = "start",required = false) Integer start,
                                 @RequestParam(value = "end",required = false) Integer end) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.lcdgesture(deviceNumber, flag, start, end));

        }
        return toAjax(false);
    }

    /**
     * 心率报警设置
     *
     * @param hrWarnSetting 设置信息
     * @return 结果
     * open - true 打开心率报警, false 关闭心率报警
     * high - 正常心率最高值
     * low - 正常心率最低值
     * threshold - 产生几次异常心率，开始报警
     * alarm_interval - 报警间隔，单位分钟
     */
    @PostMapping("/hralarm")
    public AjaxResult hralarm(@RequestBody HrWarnSetting hrWarnSetting) {
        if (StringUtils.isNotBlank(hrWarnSetting.getDeviceId())) {
            return toAjax(deviceSetUpService.hralarm(hrWarnSetting));

        }
        return toAjax(false);
    }

    /**
     * 血氧报警设置
     *
     * @param spo2WarnSetting 设置信息
     * @return 结果
     * open - true 打开血氧报警, false 关闭血氧心率报警
     * low - 低于此血氧值报警
     */
    @PostMapping("/spo2alarm")
    public AjaxResult spo2alarm(@RequestBody Spo2WarnSetting spo2WarnSetting) {
        if (StringUtils.isNotBlank(spo2WarnSetting.getDeviceId())) {
            return toAjax(deviceSetUpService.spo2alarm(spo2WarnSetting));
        }
        return toAjax(false);
    }

    /**
     * 血压报警设置
     *
     * @param bpWarnSetting 设置信息
     * @return 结果
     * open - true 打开血压报警, false 关闭血压报警
     * sbp_high - 高压最高值，单位：mmhg
     * sbp_below - 高压最低值，单位：mmhg
     * dbp_high - 低压最高值，单位：mmhg
     * dbp_below - 低压最低值，单位：mmhg
     */
    @PostMapping("/bpalarm")
    public AjaxResult bpalarm(@RequestBody BpWarnSetting bpWarnSetting) {
        if (StringUtils.isNotBlank(bpWarnSetting.getDeviceId())) {
            return toAjax(deviceSetUpService.bpalarm(bpWarnSetting));

        }
        return toAjax(false);
    }

    /**
     * 温度报警设置
     *
     * @param deviceNumber 设备编号
     * @param flag         开/关
     * @param high         高温
     * @param low          低温
     * @return 结果
     * temperatue set as 10 times of your prefer value, e.g. 36.1 set 361
     */
    @GetMapping("/temperature/alarm")
    public AjaxResult temperature(@RequestParam("deviceNumber") String deviceNumber,
                                  @RequestParam("flag") Boolean flag,
                                  @RequestParam(value = "high",required = false) Integer high,
                                  @RequestParam(value = "low",required = false) Integer low) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.temperature(deviceNumber, flag, high, low));

        }
        return toAjax(false);
    }

    /**
     * 自动房颤设置
     *
     * @param deviceNumber  设备编号
     * @param flag          打开自动房颤, false 关闭自动房颤
     * @param interval      自动房颤测量间隔，单位秒，最小取值30，最大取值120，设置超出范围则按60生效
     * @param rriSingleTime 可选值。设置为true，按照心率间隔，每次测量完心率后测量一次。设置为false，一直测量
     * @return 结果
     */
    @GetMapping("/autoaf")
    public AjaxResult autoaf(@RequestParam("deviceNumber") String deviceNumber,
                             @RequestParam("flag") Boolean flag,
                             @RequestParam(value = "interval",required = false) Integer interval,
                             @RequestParam(value = "rriSingleTime",required = false) Boolean rriSingleTime) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.autoaf(deviceNumber, flag, interval, rriSingleTime));

        }
        return toAjax(false);
    }

    /**
     * 设置闹钟
     *
     * @param alarmClockVos 闹钟设置
     * @return 结果
     * 最多设置5个闹钟
     * repeat - true 重复, false 一次性
     * monday ~ sunday 对应的那天是否打开
     * hour/minute: 时间 小时:分钟, 24小时
     * title: 闹钟内容
     */
    @PostMapping("/clockalarm/set")
    public AjaxResult clockalarm(@RequestBody AlarmClockVos alarmClockVos) {
        if (StringUtils.isNotBlank(alarmClockVos.getDeviceId())) {
            return deviceSetUpService.clockalarm(alarmClockVos);
        }
        return toAjax(false);
    }

    /**
     * 清除闹钟
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/clockalarm/clear")
    public AjaxResult clockalarmClear(@RequestParam("deviceNumber") String deviceNumber) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.clockalarmClear(deviceNumber));
        }
        return toAjax(false);
    }

    /**
     * 设置久坐
     *
     * @param sedentaries 久坐设置
     * @return 结果
     * 最多设置3个久坐提醒
     * repeat - true 重复, false 一次性
     * monday ~ sunday 对应的那天是否打开
     * start_hour/end_hour: 久坐检查时间段，开始/结束小时 24小时
     * duration: 设置累计久坐分钟数达到多少分钟提醒, 单位为5分钟，即设置1，等于5分钟
     * threshold: 一分钟内步数少于多少，判断这一分钟为久坐，计数+1，单位步，默认40
     * duration/threshold: 只针对新设备新版本有效
     */
    @PostMapping("/sedentary/set")
    public AjaxResult sedentary(@RequestBody Sedentaries sedentaries) {
        if (StringUtils.isNotBlank(sedentaries.getDeviceId())) {
            return toAjax(deviceSetUpService.sedentary(sedentaries));

        }
        return toAjax(false);
    }

    /**
     * 清除久坐
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/sedentary/clear")
    public AjaxResult sedentaryClear(@RequestParam("deviceNumber") String deviceNumber) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.sedentaryClear(deviceNumber));
        }
        return toAjax(false);
    }

    /**
     * 目标设置
     *
     * @param targetSetting 目标信息
     * @return 结果
     */
    @PostMapping("/goal")
    public AjaxResult goal(@RequestBody TargetSetting targetSetting) {
        if (StringUtils.isNotBlank(targetSetting.getDeviceId())) {
            return toAjax(deviceSetUpService.goal(targetSetting));
        }
        return toAjax(false);
    }

    /**
     * 设备恢复出厂
     *
     * @param deviceNumber 设备编号
     * @return 结果
     */
    @GetMapping("/factory/reset")
    public AjaxResult reset(@RequestParam("deviceNumber") String deviceNumber) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.reset(deviceNumber));
        }
        return toAjax(false);
    }

    /**
     * 设置语言
     *
     * @param languageSetting 语言编号
     * @return 结果
     */
    @PostMapping("/language/set")
    public AjaxResult language(@RequestBody LanguageSetting languageSetting) {
        if (StringUtils.isNotBlank(languageSetting.getDeviceId())) {
            return toAjax(deviceSetUpService.language(languageSetting));
        }
        return toAjax(false);
    }

    /**
     * 发送设备消息
     *
     * @param deviceNumber 设备编号
     * @param title        标题
     * @param description  详情
     * @return 结果
     */
    @GetMapping("/message")
    public AjaxResult message(
            @RequestParam("deviceNumber") String deviceNumber,
            @RequestParam("title") String title,
            @RequestParam("description") String description,
            @RequestParam(value = "type",required = false) String type,
            HttpServletRequest request
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            //1.判断请求端
            String requestType = request.getHeader("x-frontend-type");
            Long userId = null;
            Integer operatorType = null;
            if ("admin".equals(requestType)) {
                userId = getSysUserId();
                operatorType = 0;

            } else if ("company".equals(requestType)) {
                //判断登录用户是角色
                CompanyUser companyUser = getLoginUser().getUser();
                userId = companyUser.getUserId();
                operatorType = 1;

            } else if ("doctor".equals(requestType)) {
                userId = Long.valueOf(getDoctorId());
                operatorType = 2;
            }
            if (userId == null) {
                throw new ServiceException("请先登录!");
            }
            return deviceSetUpService.message(deviceNumber, title, description,type,operatorType,userId,null);
        }
        return toAjax(false);
    }

    /**
     * 设置跌倒检测灵敏度
     *
     * @param deviceNumber  设备编号
     * @param fallThreshold 跌倒检测的灵敏度，默认14000
     * @return 结果
     */
    @GetMapping("/fallcheck/sensitivity")
    public AjaxResult sensitivity(
            @RequestParam("deviceNumber") String deviceNumber,
            @RequestParam("fallThreshold") Integer fallThreshold
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.sensitivity(deviceNumber, fallThreshold));
        }
        return toAjax(false);
    }

    /**
     * todo
     */
//    /**
//     * 逆地理编码
//     *
//     * @param deviceNumber 设备编号
//     * @param title 标题
//     * @param description 详情
//     * @return 结果
//     * 此接口根据不同账号有相应限制，具体情况请联系相关人士确定
//     */
//    @PostMapping("/location/geocode/regeo")
//    public AjaxResult regeo(
//            @RequestParam("deviceNumber") String deviceNumber,
//            @RequestParam("title") String title,
//            @RequestParam("description") String description
//    ) {
//        return toAjax(deviceSetUpService.message(deviceNumber,title,description));
//    }

    /**
     * 心率数据测量间隔设置
     *
     * @param deviceNumber 设备编号
     * @param interval     unit is minute, minimum 1 minute
     * @return 结果
     */
    @GetMapping("/measure/interval/hr")
    public AjaxResult measureInterval(
            @RequestParam("deviceNumber") String deviceNumber,
            @RequestParam("interval") Integer interval
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.measureInterval(deviceNumber, interval));
        }
        return toAjax(false);
    }

    /**
     * 其他非心率数据测量间隔设置
     *
     * @param deviceNumber 设备编号
     * @param interval     unit is minute, minimum 5 minute
     * @return 结果
     */
    @GetMapping("/measure/interval/other")
    public AjaxResult other(
            @RequestParam("deviceNumber") String deviceNumber,
            @RequestParam("interval") Integer interval
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.other(deviceNumber, interval));
        }
        return toAjax(false);
    }

    /**
     * Gps定位
     *
     * @param deviceNumber 设备编号
     * @param gpsAutoCheck 定位开关
     * @param gpsIntervalTime  定位间隔，unit is minute
     * @param runGps 是否每次都进行GPS定位
     * @return 结果
     */
    @GetMapping("/gps/locate")
    public AjaxResult gpsLocate(
            @RequestParam("deviceNumber") String deviceNumber,
            @RequestParam("gpsAutoCheck") Boolean gpsAutoCheck,
            @RequestParam("gpsIntervalTime") Integer gpsIntervalTime,
            @RequestParam("runGps") Boolean runGps
    ) {
        if (StringUtils.isNotBlank(deviceNumber)) {
            return toAjax(deviceSetUpService.gpsLocate(deviceNumber, gpsAutoCheck,gpsIntervalTime,runGps));
        }
        return toAjax(false);
    }

    /**
     * 用药提醒设置
     *
     * @param param 请求参数
     * @return 结果
     */
    @PostMapping("/medication")
    public AjaxResult medication(@RequestBody WatchSetUpSendParam param) {
        try {
            // 调用任务调度更新
//            dynamicSendMedicationTask.scheduleTask(param);
            WatchSendMsgSet watchSendMsgSet = new WatchSendMsgSet();
            watchSendMsgSet.setType("medication");
            watchSendMsgSet.setStatus(param.getFlag()?1:0);
            watchSendMsgSet.setStart(param.getStart());
            watchSendMsgSet.setEnd(param.getEnd());
            watchSendMsgSetService.updateWatchSendMsgSetByType(watchSendMsgSet);
            return AjaxResult.success("用药提醒设置成功");
        } catch (Exception e) {
            // 捕获任务调度失败的异常
            return AjaxResult.error("用药提醒设置失败：" + e.getMessage());
        }
    }

    /**
     * 看课提醒
     *
     * @param param 请求参数
     * @return 结果
     */
    @PostMapping("/study")
    public AjaxResult study(@RequestBody WatchSetUpSendParam param) {
        try {
            // 调用任务调度更新
//            dynamicSendStudyTask.scheduleTask(param);
            WatchSendMsgSet watchSendMsgSet = new WatchSendMsgSet();
            watchSendMsgSet.setType("study");
            watchSendMsgSet.setStatus(param.getFlag()?1:0);
            watchSendMsgSet.setStart(param.getStart());
            watchSendMsgSet.setEnd(param.getEnd());
            watchSendMsgSetService.updateWatchSendMsgSetByType(watchSendMsgSet);
            return AjaxResult.success("看课提醒设置成功");
        } catch (Exception e) {
            // 捕获任务调度失败的异常
            return AjaxResult.error("看课提醒设置失败：" + e.getMessage());
        }
    }

    /**
     * 获取看课提醒设置的
     *
     * @param type 请求参数
     * @return 结果
     */
    @GetMapping("/getSet")
    public AjaxResult getSet(@RequestParam("type") String type) {
        WatchSendMsgSet watchSendMsgSet = watchSendMsgSetService.selectWatchSendMsgSetByType(type);
        WatchSetUpSendParam param = new WatchSetUpSendParam();
        if (watchSendMsgSet != null) {
            param.setFlag(watchSendMsgSet.getStatus() != 0);
            param.setStart(watchSendMsgSet.getStart());
            param.setEnd(watchSendMsgSet.getEnd());
        }
        return AjaxResult.success(param);
    }

}
