import Taro from "@tarojs/taro";
import dayjs from "dayjs";
import classnames from "classnames";
import { debounce } from "lodash";
// eslint-disable-next-line import/no-named-as-default
import React, {
  Component,
  PropsWithChildren,
  useEffect,
  useState,
} from "react";

import Echarts from "./components/Echart/index";
import Gears from "./components/Gears/index"
import {
  Block,
  View,
  Text,
  Image,
  Video,
  Input,
  Button,
} from "@tarojs/components";

/*** redux ***/
import { connect } from "react-redux";
/*** redux end ***/

/* 公共组件 */
import Navbar from "@/components/navbar/navbar";
import PopupCountdown from "@/components/popup/popup-countdown";
import PopupStepTips from "@/components/popup/popup-step-tips";
import PopupConfirm from "@/components/popup/popup-confirm";
import PopupAlert from "@/components/popup/popup-alert";
import PopupStatus from "@/components/popup/popup-status";
import PopupInstrumentUploadTips from "@/components/popup/popup-instrument-upload-tips";
import ConnectionBluetoot from "@/components/bluetoot/connection";
/* 公共组件 END */

/* 本页组件 */
import ElectricityView from "./components/ElectricityView/index";
import ModeListView from "./components/ModeList/FR200";
import ModeContent from "./components/ModeContent/FR200";
import Footer from "./components/Footer";
/* 本页组件 END */

import { go, getStorageSync, setStorageSync, msg } from "@/utils/traoAPI";
import { InstrumentInfo } from "@/utils/Interface";
import "./FR200.less";

import {
  notifyBLECharacteristicValueChange,
  sendCommand,
} from "@/utils/bluetoothWXAPI";
import {
  deviceCommandSamples,
  bleCommandSamples,
} from "@/components/bluetoot/connection/wl200";

import { minSecToS, s_to_ms, s_to_hms, sleep, s_to_s } from "@/utils/util";
// import { DeviceToolKit as DeviceToolKitWE100 } from "@flossom-npm/iot-translater-we100";
import {
  DeviceToolKit as DeviceToolKitWM,
  TResponseFromDevice as TResponseFromDeviceWM,
} from "@flossom-npm/iot-translater";
import commandMap from "@/utils/commandMap";
import { Popup } from "@antmjs/vantui";
import { fr200BleCommand } from "@/components/bluetoot/connection/fr200";

const deviceToolKitInstanceFR200 = new DeviceToolKitWM("FR200");
let deviceToolKitInstance = deviceToolKitInstanceFR200;

let currentTimeTimer: any = null; // 当前项目时间定时器
let CountdownTimer: any = null;
let timer: any = null;
let showTipsTimer: any = null;
let loadingTipsTimer: any = null; // 蓝牙连接提示
// 设备运行时间校准频率，每多少秒校准一次
const TIME_CALIBRATION_FREQUENCY = 5;

const MODE_WORKING_ENUM = {
  STANDBY: "standby", // 待命
  WORKING: "working", // 工作
  PAUSE: "pause",
  END: "end",
};

// 不同模式启动前的倒计时时间
let CountDownTime = {
  powerfulSoothing: 6,
  Stability: 3,
  Brighten: 3,
  FirmSkin: 3,
  MaskCustom: 6,
  BrightenStand: 6,
  FirmSkinStand: 6,
  SmallpoxSoothingPro: 6,
  SmallpoxSoothing: 4,
  MixNursePro: 6,
  MixNurse: 4,
  ScalpCare: 6,
};

let DeviceSyncData = {
  totalWorkingMinutes: 0,
  totalWorkingSeconds: 0,
};

class IotCarePlanFR200 extends Component<any, any> {
  constructor(props) {
    super(props);
    this.state = {
      name: "FR200",
      title: "FR200", // 页面标题
      // 当前设备
      currentDevice: {
        name: "",
        model: "",
      },

      /** 连接设备 */
      hasVersion: false, // 是否已查询到版本号
      basicModeList: [], //模式列表
      modelActiveIndex: 0, //模式下标
      sliderProgress: 22,
      DeviceConnectStatus: 1, // 设备连接状态 0未连接 1已连接
      Electricity: 4, // WL200电量
      matrixElectricity: 4, // WE200发箍电量

      workMode: "", //当前模式
      // 挡位调节组件参数
      GearData:[
        {name:'额头',forehead:5,Total:10},
        {name:'左脸颊',forehead:6,Total:10},
        {name:'右脸颊',forehead:2,Total:10},
      ],

      gear: { gear: 1 },
      currentShowDialog: "",
      showVideoPlayBtn: true, // 视频播放按钮
      duration: 0, // 视频总时长
      hadShowBreakTips: false, // 是否展示过支架断开提示

      isConnectShow: false, // 是否弹出连蓝牙弹窗：在蓝牙断开时弹出
      /** 连接设备 End */

      /** 护理过程 */
      isStandStatus: false, // 当前模式是否舱体/支架模式
      isShowStepTips: false, // 是否显示介绍步骤弹窗
      isConnectionBlutoot: true, // 是否已连接蓝牙
      isShowNurse: true, // 是否开始并显示护理 FR200默认已经开始准备护理
      isStopNurse: false, // 是否暂停护理
      isEndNurse: false, // 是否结束护理
      errorTips: "", // 错误提示
      /** 护理过程 END*/

      // 模式列表
      isModeLock: false, // 模式是否锁定
      isSwitchActiveMode: false, // 是否显示弹窗切换模式
      ModeList: [],
      ModeType: "all", // all
      modeClass: "", // 1基础护理 2专区护理 3专研促渗 4敏期护理 5智能测肤
      ActiveModeItem: {
        openSourceData: [],
      }, // 当前选中模式
      SwitchActiveModeItem: {}, // 切换选中模式
      ModeID: "mode_", // 模式KEY
      activeModeID: "", // 当前选中模式ID:用于高亮
      ModeStepIndex: 0, // 当前护理功效步骤：每个步骤时间不定，所以时间另外计算，根据步骤显示
      ModeStepTimeArray: [], // 护理功效时间步骤，用于切换显示GIF
      currentServiceData: {
        // 当前展示的开启暂停GIF: 因为时间判断不方便，所以单独领出来
        startSource: "",
        stopSource: "",
      },

      // 倒计时
      isShowCountdown: false, // 倒计时弹窗
      countdown: 3,
      // 是否结束护理
      isEndCarePlan: false,
      currentTime: "01:00",

      // 护理时间不够
      isNotEnoughTime: false,
      // 通用错误提示
      isShowErrorTipsText: false, // 护理模式切换错误弹窗
      errorTipsText: "", // 护理模式切换错误提示

      isShowNursingSuccess: false, // 护理成功弹窗
      isShowTipsSave: false, // 切换模式时，提示是否保存部分护理记录

      // 初次护理弹窗
      isFirstTipShow: false,
      nurseInfo: [],

      // 上一次护理记录未生成，是否继续连接设备
      isShowReReadRecordConnect: false,

      // 按钮是否不可运行:FR200不可禁用
      isFooterBtnDisabled: false,
      // isFirstEntryMode: false, // 模式首次打开

      isShowHistoryMsg: false, // 是否显示正在同步历史
    };
  }

  // 不涉及渲染的页面变量
  isRuning: any = true; // 设备默认运行中：fr200贴脸就会自动开始工作
  jsonStatus: any = {}; // 同步设备返回数据，用于结束
  workJsonStatus: any = {}; // 同步工作中的仪器
  tempModeCurrent: any = {}; // 临时保存的当前模式
  elapsedTime: any = 0; // 设备已运行时间
  workStatus: any = ""; // 工作状态
  FR200NursingHistory: any = null; // 护理缓存历史
  hadCheckReport = false; // 是否已检查仪器护理记录
  hadGotInstrumentHistoryData = false; // 是否已缓存仪器历史数据
  hadLoadedPage = false; // 判断是否首次进入页面

  // FR200同步状态
  FR200Status: any = {
    gear: 1, // 1-5 挡位
    isCharging: false, // 是否充电
    joulePerSecond: 0, // 每秒焦耳 0-10
    nasolabialOrMandibularOutput: false, // 鼻唇或下颌输出
    partition: 0, // 分割？
    pointOutChangeSide: false, // 交叉输出点
    impedance: 107, // 阻抗?
  };

  /** FR200模式类型：名称 */
  ModeTypeArray: string[] = [
    "all",
    "Base",
    "Zone",
    "Permeation",
    "Sensitive",
    "Intelligence",
  ];

  async onLoad() {
    // 保持屏幕常亮
    Taro.setKeepScreenOn({
      keepScreenOn: true,
    });
    this.initData();
    this.getInstrumentClockSummary();
    this.getInstrumentClockDetail();
  }
  componentDidMount() {}

  componentWillUnmount() {}

  componentDidShow() {
    console.log("页面显示了");

    if (!this.hadLoadedPage) {
      this.hadLoadedPage = true; // 二次进入页面（非首次进入）
      return;
    }

    this.getFR200NursingHistory();
    // 重置初始值，每次进入页面重新检查面罩护理记录
    this.hadCheckReport = false;
    this.hadGotInstrumentHistoryData = false;
  }

  componentDidHide() {
    console.log("Hide");
    // 页面隐藏后，下次显示需要重新检查记录
    this.hadCheckReport = false;
  }

  async initData() {
    let obj = getStorageSync("instrument_detail");
    if (obj) {
      this.setState({
        currentDevice: obj,
        title: obj.name,
      });

      await this.GetModeList(obj.id);

      // 如果不存在设备模式值，则判断为首次进入，弹窗提示
      let isFirstTipShow = getStorageSync("first_instrument_" + obj.id);
      if (!isFirstTipShow) {
        this.firstNurseInfo();
      }
    }

    // 开发者工具
    const platform = Taro.getSystemInfoSync().platform;
    if (platform !== "devtools") {
      // 仅手机端初始化蓝牙
      this.init();
    }
  }

  getOption() {
    const option = {
      grid: { top: 8, right: 8, bottom: 24, left: 36 },
      xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      },
      yAxis: {
        type: "value",
      },
      series: [
        {
          data: [820, 932, 901, 934, 1290, 1330, 1320],
          type: "line",
          smooth: true,
        },
      ],
      tooltip: {
        trigger: "axis",
      },
      // title: {
      //   text: 'ECharts 示例'
      // },
      // tooltip: {},
      // xAxis: {
      //   data: ['A', 'B', 'C', 'D', 'E']
      // },
      // yAxis: {},
      // series: [{
      //   name: '数量',
      //   type: 'bar',
      //   data: [5, 20, 36, 10, 10]
      // }]
    };
    return option;
  }

  async init() {
    // 查询自定义设备指令
    const queryInstructionParams = {
      commandType: "InfoQuery",
      infoQueryType: "customModeInfo",
    };
    let commandBuffer = deviceToolKitInstance.toBleCommand(
      queryInstructionParams as any
    );
    sendCommand({ value: commandBuffer }).then((res) => {
      console.log(
        "查询自定义组合模式指令发送成功 参数为=>",
        queryInstructionParams
      );
    });

    // 监听蓝牙连接状态改变
    Taro.onBLEConnectionStateChange(this.listener);
    await this.notifyBLECharacteristicValueChange();

    // this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY);
  }
  listener = (res) => {
    console.log("listener res", res);
    if (res?.connected) return;
    // 蓝牙未连接才执行下面逻辑
    Taro.offBLECharacteristicValueChange((res) => {
      console.log("offBLECharacteristicValueChange", res);
    });
    clearTimeout(loadingTipsTimer);
    console.log(commandMap.WL200Command, "监听到蓝牙断开, 打开断开提示");

    this.workStatus = "";
    // 显示蓝牙断开弹窗
    this.setState({
      isConnectShow: true, // 打开蓝牙链接弹窗
      isConnectionBlutoot: false, // 断开蓝牙
      isShowCountdown: false, // 关闭倒计时，防止倒计时还在运行
    });
    this.footerIsDisabled();
  };

  GetModeList = async (id) => {
    let params = {
      instrumentId: id,
    };
    let res = await InstrumentInfo.modeInfoList(params);
    if (res.data.code === 200) {
      if (res.data.data.length > 0) {
        this.setState({
          ActiveModeItem: res.data.data[0],
          ModeList: res.data.data,
        });

        setTimeout(() => {
          this.modeCurrentFun(res.data.data[0]);
        }, 100);
      } else {
        this.setState({ ModeList: [] });
      }
    }
  };

  /**
   * 倒计时弹窗
   * param 重置倒计时
   * callback 回调函数
   */
  showCountdownFun(count = 3, callback: any = null) {
    this.setState({
      countdown: count,
    });
    setTimeout(() => {
      clearInterval(CountdownTimer);
      this.setState({
        isShowCountdown: true,
      });
      CountdownTimer = setInterval(() => {
        if (this.state.countdown === 0) {
          clearInterval(CountdownTimer);
          this.setState({
            isShowCountdown: false,
          });
          if (callback) callback();
        } else {
          this.setState({
            countdown: this.state.countdown - 1,
          });
        }
      }, 1000);
    }, 0);
  }

  /** 选中护理模式 */
  modeCurrentFun = async (data, isNotCheck = false) => {
    // 护理检查改变模式，是否提示切换护理模式
    // isNotCheck为真时，不进行校验，直接切换
    this.tempModeCurrent = data;

    // 仅在未开始护理前，切换模式的时候提示模式弹窗
    // FR200默认开始护理
    if (!this.state.isShowNurse) {
      this.openStepTips();
    }

    // 如果按钮不可点击则报错，内部自带检查底部按钮函数
    this.onEmitErrorTips();
    if (!isNotCheck) {
      let isReturn = this.modeRuningChange();
      if (isReturn) return;
    }

    let { isShowNurse } = this.state;
    let currentServiceData = {
      startSource: "",
      stopSource: "",
    };
    if (data.serviceData.length) {
      currentServiceData = data.serviceData[0];
    }

    let currentTime = data.modeTimeStr;

    this.setState({
      ActiveModeItem: data,
      activeModeID: data.id,
      ModeID: "mode_" + data.id,
      currentServiceData,
      ModeStepIndex: 0,
      currentTime,
      ModeType: this.ModeTypeArray[data.modeClass],
    });

    setTimeout(() => {
      // 设置时间组合
      if (data.serviceData.length > 0) {
        this.setServiceTimeData();
      }
    });

    // 如果是正在运行中切换，则直接准备运行
    if (isShowNurse) {
      if (!this.footerIsDisabled()) {
        this.stepNext(); // 如果切换模式，则不执行开始逻辑
        setTimeout(() => {
          this.onNursingTap("switch");
        }, 800);
      }
    }
  };
  /** 设备运行中切换模式 */
  modeRuningChange() {
    // 运行中切换模式逻辑
    if (
      this.workStatus === MODE_WORKING_ENUM.PAUSE ||
      this.workStatus === MODE_WORKING_ENUM.WORKING
    ) {
      const { totalWorkingMinutes, totalWorkingSeconds } = DeviceSyncData;
      const totalTime = totalWorkingMinutes * 60 + totalWorkingSeconds; // 设备时间
      let { ActiveModeItem } = this.state;
      if (!ActiveModeItem || totalTime === 0) {
        return false;
      }

      if (this.isRuning === true && this.state.DeviceConnectStatus == 1) {
        // 提示切换护理模式
        if (this.isCheckNurseTime()) {
          // 满足时间条件，提示是否保存部分护理记录
          this.judgementWorkStatus(
            MODE_WORKING_ENUM.PAUSE,
            this.state.ActiveModeItem?.modeType
          );
          this.setState({
            isShowTipsSave: true,
          });
        }
        return true;
      }
    }
    return false;
  }
  //  加减组件- 减号操作
handleMinus = async (data,inde) => {
  let GearData =this.state.GearData
  if(GearData[inde].forehead !== 1){
    GearData[inde].forehead = GearData[inde].forehead - 1
    this.setState({GearData})
  }
};
//  加减组件- 加号操作
handleAdd = async (data,inde) => {
  let GearData =this.state.GearData
  if(GearData[inde].forehead !== GearData[inde].Total){
    GearData[inde].forehead = GearData[inde].forehead + 1
    this.setState({GearData})
  }
};

  /** 切换护理模式 */
  switchModeCurrentFun = async (data) => {
    this.setState({
      SwitchActiveModeItem: data,
      activeModeID: data.id,
      ModeID: "mode_" + data.id,
    });
  };
  // 打开模式切换弹窗
  openModeSwitch = () => {
    console.log("openModeSwitch");
    this.setState({
      isSwitchActiveMode: true,
    });
  };
  // 取消并关闭切换护理模式弹窗
  cancelModeSwitchBtn = () => {
    this.setState({
      isSwitchActiveMode: false,
    });
  };
  // 弹窗确定切换护理模式
  confirmModeSwitchBtn = () => {
    let { SwitchActiveModeItem } = this.state;
    this.cancelModeSwitchBtn();
    this.modeCurrentFun(SwitchActiveModeItem);

    this.setState({
      ModeType: this.ModeTypeArray[SwitchActiveModeItem.modeClass],
    });
  };

  stepNext = () => {
    let modeClass = this.state.ActiveModeItem.modeClass;
    this.workStatus = "pause";
    this.isRuning = true; // 暂停也是运行中
    this.setState({
      ModeType: this.ModeTypeArray[modeClass],
      isShowNurse: true,
      isStopNurse: true,
    });

    setTimeout(() => {
      this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY);
    });
  };
  /** 开始护理按钮：点击开始，页面进行到下一步 */
  onStartNurse = async () => {
    // 如果检查通过，可运行，则执行下一步
    if (!this.footerIsDisabled()) {
      this.stepNext();

      setTimeout(() => {
        this.onNursingTap();
        // 倒计时弹窗: 倒计时完成后，自动开始，并判断弹窗
        let downNum = CountDownTime[this.state.ActiveModeItem.modeType] || 3;
        this.showCountdownFun(downNum, () => {});
      }, 500);

      return;
    }
    // 如果检查失败，则报错
    this.onEmitErrorTips();
  };

  /**
   * @name 不可切换光照提示
   * @description 检测紧贴肌肤
   */
  onEmitErrorTips = async () => {
    setTimeout(() => {
      let { ActiveModeItem } = this.state;

      // 按钮不可点击时，提示报错
      let isDisabled = this.footerIsDisabled();
      if (isDisabled) {
        this.showTips("检测到您的设备没有紧贴肌肤，请紧贴肌肤后重新尝试");
      }
    });
  };

  // 绘制能量图
  drawProwerPicture() {}

  /** 切换光照 */
  onSwitchChange = async () => {
    // todo
    let { isStopNurse } = this.state;
    if (isStopNurse) {
      // 开始光照逻辑
      this.onNursingTap();
    } else {
      // 暂停光照逻辑
      this.handleWorkStatus(false, MODE_WORKING_ENUM.PAUSE);
    }
    this.setState({
      isStopNurse: !isStopNurse,
    });
  };

  /**
   * @name 每次进入设备运行页，打开首个模式的介绍弹窗
   */
  openStepTips = () => {
    let isFirstEntryModeNot = getStorageSync(
      "isFirstEntryMode_" + this.state.currentDevice.id
    );
    // 1.如果没有持久化不再提示，每次进入都会弹窗提示
    if (!isFirstEntryModeNot) {
      // 2.必须要有数据才弹窗
      if (this.state.ActiveModeItem.openSourceData.length > 0) {
        this.setState({ isShowStepTips: true });
      }
    }
  };
  closeStepTips = (data) => {
    if (data.isLocal) {
      setStorageSync("isFirstEntryMode_" + this.state.currentDevice.id, true); // 关闭首次进入弹窗
    }
    this.setState({ isShowStepTips: false });
  };

  /** 蓝牙连接相关 */
  switchBLEMatch = (jsonStatus: any) => {
    console.log("蓝牙连接相关", jsonStatus);
    switch (jsonStatus.bleCommandType) {
      // 如果设备配对链接发送配对码的时候，设备应答小程序配对码是否正确。
      case "SendMatchCode":
        if (jsonStatus.matchedSuccess) {
          console.log("设备配对成功");
          this.setState({
            DeviceConnectStatus: 1,
          });
        }
        break;
    }
  };

  // 蓝牙特征更改
  notifyBLECharacteristicValueChange = () => {
    console.log("notifyBLECharacteristicValueChange deviceInfo 参数为=>");
    const bluetoothInfo = this.props.bluetoothInfo;
    notifyBLECharacteristicValueChange({
      deviceId: bluetoothInfo.deviceId,
      servicesuuid: bluetoothInfo.servicesuuid,
      characteristicsuuid1: bluetoothInfo.characteristicsuuid1,
      characteristicsuuid0: bluetoothInfo.characteristicsuuid0,
    }).then((res) => {
      Taro.onBLECharacteristicValueChange((value) => {
        const jsonStatus: any = deviceToolKitInstance.toJsonStatus(value.value);
        console.log(
          "onBLECharacteristicValueChange jsonStatus => ",
          jsonStatus
        );
        if (!jsonStatus || jsonStatus == null) {
          return;
        }
        this.workStatus = jsonStatus.workStatus; // 记录工作状态
        // end 和 endWork 都是护理结束, endWork不关机, end 关机, 对小程序而言处理流程都一样
        if (jsonStatus.workStatus && jsonStatus.workStatus == "endWork") {
          jsonStatus.workStatus = "end";
          console.log(jsonStatus.workStatus, "护理结束");
        }

        switch (jsonStatus?.commandType) {
          //设备配对和连接的返回
          case "BleMatch":
            // 蓝牙相关指令
            this.switchBLEMatch(jsonStatus);
            break;
          //设备状态同步
          case "DeviceStatusSync":
            this.setState({
              Electricity: jsonStatus.battery,
            });
            switch (jsonStatus.workStatus) {
              case "standby":
                //设备的待机状态 可能workMode字段为空
                console.log("设备状态同步 待机状态", jsonStatus);
                // this.judgementWorkStatus(
                //   MODE_WORKING_ENUM.STANDBY,
                //   jsonStatus.workMode
                // );
                break;
              case "pause":
                //设备的暂停状态
                console.log("设备状态同步 暂停状态", jsonStatus);
                // this.judgementWorkStatus(
                //   MODE_WORKING_ENUM.PAUSE,
                //   jsonStatus.workMode
                // );
                break;
              case "working":
                //设备的运行中状态
                console.log("设备状态同步 运行中状态", jsonStatus);
                // this.judgementWorkStatus(
                //   MODE_WORKING_ENUM.WORKING,
                //   jsonStatus.workMode
                // );
                break;
              default:
                break;
            }
            console.log(
              "jsonStatus?.workMode === this.state.ActiveModeItem.modeType",
              jsonStatus?.workMode === this.state.ActiveModeItem.modeType
            );
            console.log(
              "this.state.DeviceConnectStatus",
              this.state.DeviceConnectStatus
            );
            console.log("this.isRuning", this.isRuning);
            if (jsonStatus?.workMode === this.state.ActiveModeItem.modeType) {
              if (this.state.workMode !== jsonStatus?.workMode) {
                this.setState({
                  workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时，才允许改变小程序变量缓存
                });
              }

              // 判断设备是否在运行中(护理中)
              // 仅当设备模式与小程序是否一致，才允许更改设备运行时间
              if (this.isRuning) {
                if (
                  this.state.DeviceConnectStatus === 1 &&
                  jsonStatus.workStatus !== MODE_WORKING_ENUM.END
                ) {
                  this.updateDeviceSyncData(
                    {
                      totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
                      totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
                    },
                    jsonStatus
                  );
                }
              }
            }

            break;
          //设备对控制指令的响应
          case "DeviceControl":
            console.log("设备控制响应", jsonStatus);
            if (jsonStatus.responseStatus == "OK") {
              console.log("发送控制指令成功");
              this.workJsonStatus = jsonStatus;
              this.workStatus = jsonStatus.workStatus;

              setTimeout(() => console.log("this.workStatus", this.workStatus));
              this.setState({
                Electricity: jsonStatus.battery,
                matrixElectricity: jsonStatus.matrixBattery,
              });

              // 判断设备主动上报的关机事件
              if (jsonStatus.workStatus === MODE_WORKING_ENUM.END) {
                // 判断id是否一致, 一致的话则生成护理报表, 并提示
                if (jsonStatus.id == this.FR200NursingHistory.id) {
                  debounce(
                    this.checkInstrumentRecord.bind(this, jsonStatus),
                    500
                  );
                }
                return;
              }

              if (jsonStatus?.workMode === this.state.ActiveModeItem.modeType) {
                this.setState({
                  workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时，才允许改变小程序变量缓存
                });

                // 判断是否在isRuning(护理中)
                // 仅当设备模式与小程序是否一致，才允许更改设备运行时间
                if (
                  this.state.DeviceConnectStatus === 1 &&
                  this.isRuning == 2 &&
                  jsonStatus.workStatus !== MODE_WORKING_ENUM.END
                ) {
                  this.updateDeviceSyncData(
                    {
                      totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
                      totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
                    },
                    jsonStatus
                  );
                }
              }

              if (
                jsonStatus.workMode === MODE_WORKING_ENUM.WORKING &&
                this.isRuning
              ) {
                const { ActiveModeItem } = this.state;
                const item = ActiveModeItem;
                if (jsonStatus.workMode !== item.modeType) {
                  clearTimeout(loadingTipsTimer);
                  this.setState({
                    isShowCountdown: false,
                  });
                }
              }
            }
            break;
          // 设备对信息查询指令的响应
          case "InfoQuery":
            console.log("设备对信息查询指令的响应 InfoQuery", jsonStatus);
            switch (jsonStatus.infoQueryType) {
              // 离线记录
              case "offlineClockInInfo":
                console.log("离线记录", jsonStatus);
                break;
              // 版本信息
              case "versionInfo":
                console.log("版本信息", jsonStatus);
                break;
              // 时间同步
              case "timeSync":
                console.log("时间同步", jsonStatus);
                break;
              default:
                break;
            }
            break;
          default:
            break;
        }
      });

      /**
       * 延迟600毫秒获取附属设备状态
       */
      const querySubDeviceArrayBuffer = deviceToolKitInstance.toBleCommand({
        ...bleCommandSamples.querySubDevice,
        queryType: "WL200",
      } as any);
      setTimeout(() => {
        console.log("发送查询附属设备指令 querySubDeviceArrayBuffer");
        sendCommand({
          value: querySubDeviceArrayBuffer,
        });
      }, 600);

      /**
       * 延迟500毫秒获取设备电量
       */
      const queryDeviceArrayBuffer = deviceToolKitInstance.toBleCommand(
        bleCommandSamples.queryDeviceStatus as any
      );
      setTimeout(() => {
        console.log("发送查询设备电量指令");
        sendCommand({
          value: queryDeviceArrayBuffer,
        });
      }, 500);
    });
  };

  /**监听关机事件*/
  onEndDevice = () => {
    this.rmFR200NursingHistory(this.FR200NursingHistory, true);
    // 判断护理时间，如果不足，则提示不足
    if (!this.isCheckNurseTime()) {
      this.setState({ isNotEnoughTime: true });
    } else {
      this.endNurseFun();
    }
  };

  /** 同步设备运行信息：运行时间 */
  updateDeviceSyncData = (newData, jsonStatus) => {
    DeviceSyncData = {
      ...DeviceSyncData,
      ...newData,
    };
    if (newData.hasOwnProperty("totalWorkingSeconds")) {
      this.renderDeviceStatus.renderWorkTime(jsonStatus);
    }
  };

  // 页面同步护理剩余时间
  renderDeviceStatus = {
    renderWorkTime: (jsonStatus) => {
      const { totalWorkingMinutes, totalWorkingSeconds } = DeviceSyncData;
      let { ActiveModeItem, currentTime } = this.state;
      const totalTime = totalWorkingMinutes * 60 + totalWorkingSeconds;
      console.log("仪器上报的已经运行的总秒数", totalTime);
      console.log("时间校准频率，默认5秒一次", TIME_CALIBRATION_FREQUENCY);
      //对比仪器上报运行的总秒数  和小程序页面运行的已经运行的总秒数，如果不一致就进行校准
      const currentScene = ActiveModeItem; // 获取当前的场景
      let sceneTime = ActiveModeItem?.breakTimeStr
        ? minSecToS(ActiveModeItem.breakTimeStr)
        : minSecToS(currentScene.modeTimeStr); // 场景时间

      console.log("场景时间 sceneTime", sceneTime);
      console.log("当前显示时间 currentTime", currentTime);
      console.log("设备运行时间 totalTime", totalTime);

      // 更新界面倒计时
      this.resetTimer();

      if (
        sceneTime > totalTime &&
        this.isRuning === true &&
        this.state.DeviceConnectStatus == 1
      ) {
        // 界面倒计时同步设备时间
        const t = sceneTime - totalTime; // 场景时间 - 已运行时间 = 剩余时间
        this.setState({
          currentTime: s_to_ms(t),
        });
      } else {
        this.setState({
          currentTime: "00:00",
        });
        this.judgementWorkStatus(MODE_WORKING_ENUM.END, jsonStatus.workMode);
      }

      // 每次同步后，更新历史缓存
      setTimeout(() => {
        this.updateFR200NursingHistory(null, jsonStatus);
      }, 100);
    },
  };

  // 仪器开始倒计时
  setLoadingTips(time) {
    this.setState({
      countdown: time,
    });
    if (time >= 0) {
      loadingTipsTimer = setTimeout(() => {
        this.setLoadingTips(--time);
      }, 1000);
    } else {
      // 停止倒计时
      // that.data.startSettingCountDown = false;
      this.setState({
        isShowCountdown: false,
      });
    }
  }

  /**
   * 设备上报不同状态
   * params 工作状态 工作模式 响应状态
   */
  judgementWorkStatus(nWorkStatus, nWorkMode) {
    const { workMode, ActiveModeItem, ModeList } = this.state;
    const opts: any = {};
    // ActiveModeItem
    let nowModeItem;
    if (nWorkMode) {
      nowModeItem = ModeList.find((item) => {
        return item.modeType === nWorkMode;
      });
    }
    opts.workStatus = nWorkStatus;

    let nowCurrentTime = ActiveModeItem.modeTimeStr;
    // 完成重连同步则删除重连时间字段
    if (ActiveModeItem?.breakTimeStr) {
      nowCurrentTime = ActiveModeItem?.breakTimeStr;
    }

    const statusF = {
      sleep: () => {
        this.setState({
          isShowCountdown: false,
        });
      },
      standby: () => {
        this.setState({
          isShowCountdown: false,
        });
        if (nowModeItem?.isCabinMode && this.isRuning === true) {
          opts.currentTime = nowCurrentTime;
        } else if (!nowModeItem?.isCabinMode && this.isRuning === true) {
          // fix: 启动非支架模式倒计时时，连上支架，仪器的状态变为standby
          this.isRuning === false;
        }
      },
      setting: () => {
        // that.data.hadShowBreakTips = false;
        this.setState({
          hadShowBreakTips: false,
        });
        if (this.isRuning === false && !ActiveModeItem.isCabinMode) {
          this.isRuning = true;
          this.setState({
            title: "正在护理",
            isStopNurse: false,
          });
        } else if (this.isRuning === false && ActiveModeItem.isCabinMode) {
          this.isRuning = true;
          // this.setState({
          //   title: "正在护理",
          // });
          this.setState({
            title: "正在护理",
            isStopNurse: false,
          });
        }
        if (nowModeItem) {
          opts.currentTime = nowCurrentTime;
        }
        // 倒计时loading
        // if (!this.state.isShowCountdown) {
        //   this.setState({
        //     isShowCountdown: true,
        //   });
        //   this.setLoadingTips(CountDownTime[workMode] || 6);
        // }
      },
      working: () => {
        this.setState({
          title: "正在护理",
          isStopNurse: false,
          isShowCountdown: false,
          hadShowBreakTips: false,
        });
      },
      pause: () => {
        clearInterval(currentTimeTimer);
        this.setState({
          isShowCountdown: false,
        });
        if (ActiveModeItem.isCabinMode) {
          this.setState({
            title: "暂停护理",
            isStopNurse: true,
          });
        }
      },
      end: () => {
        // 已进入了报告阶段, 防止重复进入, 主要防止在手动点击结束护理接收到仪器消息
        console.log("END 护理结束");
        clearInterval(currentTimeTimer);

        this.endnursing(true);
      },
    };
    statusF[nWorkStatus] && statusF[nWorkStatus]();
    if (Object.keys(opts).length) {
      this.setState(opts);
    }
  }

  /**
   * 保存护理报告
   * 1.是否跳转 2.数据
   * */
  saveNurseReport = async (isJump = true, from) => {
    this.endNurseFun();
  };

  /**
   * 结束护理
   * param isAuto 是否仪器自动结束
   */
  endnursing = (isAuto) => {
    if (isAuto == true) {
      // 仪器自动上报完成, 直接上报并跳转报告页
      clearInterval(currentTimeTimer);
      const isEnough = this.isCheckNurseTime();
      if (isEnough) {
        this.saveNurseReport(true, "endnursing");
      }
    } else {
      // 手动点击结束, 弹出弹窗, 看看是否需要结束
      this.onEndPlan();
    }
  };

  // 重置并同步计时器
  resetTimer = () => {
    // 切换模式后, 需要重新设置计时器, 以防进行中的计时器
    currentTimeTimer && clearInterval(currentTimeTimer);
    currentTimeTimer = setInterval(() => {
      let {
        DeviceConnectStatus,
        currentTime,
        ModeStepTimeArray,
        ModeStepIndex,
        ActiveModeItem,
      } = this.state;
      if (
        this.workStatus == MODE_WORKING_ENUM.WORKING &&
        this.isRuning &&
        DeviceConnectStatus == 1
      ) {
        let totalSeconds = ActiveModeItem?.breakTimeStr
          ? minSecToS(ActiveModeItem.breakTimeStr)
          : minSecToS(ActiveModeItem.modeTimeStr);
        // 现在的倒计时剩余时间：同步时检查是否断开重连，如果是，则使用断开的剩余时长，进行倒计时计算
        let currentSeconds = minSecToS(currentTime);
        let checkTime = totalSeconds - currentSeconds;

        // 缓存经过的时间：用于接口提交
        this.elapsedTime = checkTime;
        // 如果存在中断时间，则要加上间隔的时间
        if (ActiveModeItem?.breakTimeStr) {
          let intervalTime =
            minSecToS(ActiveModeItem.modeTimeStr) -
            minSecToS(ActiveModeItem.breakTimeStr);
          this.elapsedTime += intervalTime;
        }

        // 判断剩余时间是否大于1
        if (currentSeconds >= 1) {
          // 小程序显示倒计时
          this.setState({
            currentTime: s_to_ms(--currentSeconds),
          });

          let length = ModeStepTimeArray.length;
          if (length) {
            // 模式多个步骤节点切换
            // 已运行时间达到下一节点时，切换
            if (checkTime > ModeStepTimeArray[ModeStepIndex]) {
              // 已运行时间达到下一节点，且存在下一节点，步骤切换时更新
              if (ModeStepIndex < length - 1) {
                let index = ModeStepIndex + 1; // 提前步骤+1
                let currentServiceData = {
                  startSource: "",
                  stopSource: "",
                };
                let serviceLength = ActiveModeItem.serviceData.length;
                if (serviceLength > index) {
                  currentServiceData = ActiveModeItem.serviceData[index];
                }

                console.log("********************");
                console.log("********************");
                console.log(
                  "仅在时间达到下一步，步骤切换时更新currentServiceData",
                  currentServiceData
                );
                this.setState({
                  ModeStepIndex: index,
                  currentServiceData,
                });
              }
            }
          }
        } else {
          clearInterval(currentTimeTimer);
          this.setState({
            currentTime: "00:00",
            ModeStepIndex: 0,
          });
          this.saveNurseReport(true, "setTimer"); // 保存护理计划，并且结束
        }
      }
    }, 1000);
  };

  // 检测并控制工作状态
  handleWorkStatus = (isBtnClick: boolean, workStatus) => {
    const { DeviceConnectStatus, ActiveModeItem } = this.state;
    let newWorkStatus =
      workStatus ||
      (this.workStatus == MODE_WORKING_ENUM.WORKING ? "pause" : "working");
    if (isBtnClick && newWorkStatus == "working") {
      // todo FR200 不判断舱体，判断肌肤
      if (!ActiveModeItem.isCabinMode && DeviceConnectStatus != 1) {
        console.log("DeviceConnectStatus", DeviceConnectStatus);
        this.showTips("检测到您的设备没有紧贴肌肤，请紧贴肌肤后点击重新检测");
        return;
      }
    }

    const sendParams = {
      ...deviceCommandSamples.pause,
      workMode: ActiveModeItem.modeType, // 使用模式
      workStatus: newWorkStatus,
    };
    console.log("准备发送自定义或工作指令", ActiveModeItem, sendParams);
    const pauseArrayBuffer = deviceToolKitInstance.toBleCommand(
      sendParams as any
    );
    sendCommand({
      value: pauseArrayBuffer,
    }).then(() => {
      this.workStatus = newWorkStatus;
      this.resetTimer();
      console.info(
        `handleWorkStatus 发送${newWorkStatus}指令成功 参数为 =>`,
        sendParams
      );
    });
  };

  /**
   * @name 点击开始护理
   * @params type 传值 switch 则用于区分是否切换模式的启动
   */
  onNursingTap(type = "") {
    // 如果已禁止运行，则停止执行后续逻辑
    if (this.state.isFooterBtnDisabled) return;
    // 防止多次点击
    if (this.state.hadClickStart) return;
    this.setState({
      hadClickStart: true,
    });
    setTimeout(() => {
      this.setState({
        hadClickStart: false,
      });
    }, 500);

    const { ActiveModeItem, DeviceConnectStatus } = this.state;

    if (DeviceConnectStatus != 1) {
      console.log("DeviceConnectStatus 开始处", DeviceConnectStatus);
      this.showTips("检测到FR200未连接成功，请确认FR200开机并佩戴");
      return;
    }

    // 仅在切换模式的时候，弹窗倒计时.
    if (type === "switch") {
      let downNum = CountDownTime[ActiveModeItem.modeType] || 3;
      this.showCountdownFun(downNum, () => {}); // 倒计时弹窗
    }

    // 开始执行护理
    this.workStatus = MODE_WORKING_ENUM.WORKING; // 不管当前什么状态，直接设为工作状态
    this.handleWorkStatus(true, MODE_WORKING_ENUM.WORKING);
    this.setState({
      isStopNurse: false,
    });
  }

  // 结束护理
  endNurseFun() {
    this.handleWorkStatus(false, "end");
    if (this.isCheckNurseTime()) {
      this.PostNursingLogClock();
    } else {
      // 时间不满足，回到主页
      this.handleWorkStatus(false, "end");
      this.setState({
        isEndCarePlan: false,
        isNotEnoughTime: true,
      });
    }
  }

  /** 检查时间是否达标仪器最低护理时间 */
  isCheckNurseTime() {
    const { currentDevice, ActiveModeItem } = this.state;
    const currentScene = ActiveModeItem;
    let sceneTime = minSecToS(currentScene.modeTimeStr);
    const timeRemaining = sceneTime - minSecToS(this.state.currentTime); // 当前模式已运行时间

    let nursingTimeStr = currentDevice?.nursingTimeStr;
    let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间

    console.log("检查已运行时间", timeRemaining, nursingTime);
    if (timeRemaining >= nursingTime) {
      return true;
    } else {
      return false;
    }
  }
  /*** 护理记录 START ***/
  /** 小程序查询护理记录概要 */
  getInstrumentClockSummary() {
    this.hadGotInstrumentHistoryData = true;
    console.log("发送指令clockSummary 获取设备护理概要");
    setTimeout(() => {
      const queryClockSummary = deviceToolKitInstance.toBleCommand({
        ...(fr200BleCommand.InfoQuery.clockSummary as any),
      });
      sendCommand({
        value: queryClockSummary,
      });
    }, 1000);
  }
  /** 小程序查询最近一条护理详情 */
  getInstrumentClockDetail() {
    this.hadGotInstrumentHistoryData = true;
    console.log("发送指令clockDetail 查询最近一条护理详情");
    setTimeout(() => {
      const queryClockSummary = deviceToolKitInstance.toBleCommand({
        ...(fr200BleCommand.InfoQuery.clockDetail as any),
      });
      sendCommand({
        value: queryClockSummary,
      });
    }, 2000);
  }

  /**
   * @title 检查护理记录
   * @description
   * 1.判断是否存在工作状态：如果不存在，则等待两秒用于连接设备与赋值，再执行后面的代码
   *
   * 2.判断是否已存在缓存的护理记录：如果没有历史，则缓存
   *
   * 3.判断是否当天（如果不是当天，则删除记录）
   *
   * 4.判断设备状态-未运行/已完成/待机
   * 4-1.已有缓存护理记录，判断ID一致，同步时间。若主动结束，需判断时间是否满足仪器最低护理时间，满足直接跳转护理报告页；不满足需提示不满足，回到首页
   * 4-2.已有缓存护理记录，判断ID不一致（同步异常）。直接提交，固定设置为一分钟。
   *
   * 5.判断设备状态-运行中
   * 正常执行逻辑
   *
   * */
  checkInstrumentRecord = async (jsonStatus: any) => {
    console.log("检查护理记录");
    let { currentDevice, ActiveModeItem, ModeList } = this.state;

    await sleep(2);

    let isSyncHistory = Taro.getStorageSync("isSyncHistory");
    if (isSyncHistory) {
      this.setState({ isShowHistoryMsg: false });
      Taro.removeStorageSync("isSyncHistory");
    }
    console.log(
      "this.workJsonStatus",
      this.workJsonStatus,
      this.workJsonStatus.workMode
    );

    this.setState({
      isFooterBtnDisabled: false,
    });
    if (this.workJsonStatus.workMode) {
      // FR200可能要判断是否水分测试 Test
      console.log("this.workJsonStatus.workMode", this.workJsonStatus.workMode);
      if (this.workJsonStatus.workMode.indexOf("Stand") > -1) {
        console.log(
          "this.workJsonStatus.workMode",
          this.workJsonStatus.workMode
        );
        this.setState({
          isStandStatus: true,
        });
        setTimeout(() => this.footerIsDisabled(), 100);
      }
    }

    // 2.判断是否已存在缓存的护理记录：如果没有历史，则缓存
    let workStatus = this.workJsonStatus.workStatus;
    let FR200NursingHistory = this.FR200NursingHistory;
    if (!this.FR200NursingHistory) {
      console.log("小程序缓存没有数据, 忽略");
      if (
        workStatus == MODE_WORKING_ENUM.WORKING ||
        workStatus == MODE_WORKING_ENUM.PAUSE
      ) {
        // 缓存没有数据, 要存缓存
        this.setFR200NursingHistory(jsonStatus);
      }
      return;
    }

    // 3.判断是否当天（如果不是当天，则删除记录）
    if (!dayjs().isSame(FR200NursingHistory?.createDate, "day")) {
      console.log("小程序缓存有数据，但是不是当天数据，忽略");
      this.rmFR200NursingHistory(FR200NursingHistory);
      return;
    }

    // 仪器缓存模式，判断是否存在于现有模式中
    let recordModeItem = ModeList.find((item) => {
      return item.id == FR200NursingHistory.currentServiceData.modeId;
    });
    if (!FR200NursingHistory || !recordModeItem) {
      console.log("仪器有数据, 但是缓存没有数据, 忽略");
      return;
    }

    console.log("workStatus", workStatus);
    console.log("jsonStatus", jsonStatus, this.workJsonStatus);
    console.log("currentTime", FR200NursingHistory.currentTime);

    let historyElapsedTime =
      minSecToS(recordModeItem.modeTimeStr) -
      minSecToS(FR200NursingHistory.currentTime);

    this.elapsedTime =
      this.elapsedTime > historyElapsedTime
        ? this.elapsedTime
        : historyElapsedTime;
    // 4.判断设备状态-未运行/已完成/待机
    if (
      workStatus == MODE_WORKING_ENUM.STANDBY ||
      workStatus == MODE_WORKING_ENUM.END ||
      !workStatus
    ) {
      // 判断id是否一致, 一致的话则生成护理报表
      if (jsonStatus.id == FR200NursingHistory.id) {
        console.log("id一致, 设备没有运行/已完成/待机");
        let totalSeconds = jsonStatus.totalSeconds; // 从仪器上获取的使用时间

        let nursingTimeStr = currentDevice?.nursingTimeStr;
        let nursingTime = nursingTimeStr ? minSecToS(nursingTimeStr) : 60; // 设备生成护理记录至少需要运行时间

        if (totalSeconds < nursingTime) {
          // 护理时间不足
          this.setState({ isNotEnoughTime: true });
          this.rmFR200NursingHistory(FR200NursingHistory);
          return;
        }

        // 小程序时间和设备时间，谁大用谁
        let timeValue =
          totalSeconds > this.elapsedTime
            ? s_to_hms(totalSeconds)
            : s_to_hms(this.elapsedTime);

        let params = {
          instrumentId: currentDevice.id,
          instrumentName: currentDevice.name,
          modeId: ActiveModeItem.id,
          modeName: ActiveModeItem.modeName,
          nursingTime: timeValue,
        };
        this.handleWorkStatus(false, "end");
        let res: any = await this.PostNursingLogClock(params);
        console.log("res", res);
        this.rmFR200NursingHistory(FR200NursingHistory);
      } else {
        // ID不一致，同步异常，统一提交一分钟
        let params = {
          instrumentId: currentDevice.id,
          instrumentName: currentDevice.name,
          modeId: ActiveModeItem.id,
          modeName: ActiveModeItem.modeName,
          nursingTime: "00:01:00",
        };
        this.handleWorkStatus(false, "end");
        let res: any = await this.PostNursingLogClock(params);
        console.log("res", res);
        this.rmFR200NursingHistory(FR200NursingHistory);
      }
    } else {
      console.log("id一致, 设备运行中或暂停");
      // 5.判断设备状态-运行中
      // 同步时间
      if (jsonStatus.id == FR200NursingHistory.id) {
        if (FR200NursingHistory.currentTime) {
          this.isRuning = true;
          this.resetTimer();
        }
      }
    }
  };

  /** 获取小程序本地缓存的历史记录 */
  getFR200NursingHistory() {
    this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");

    // 是否同步历史记录
    let isSyncHistory = Taro.getStorageSync("isSyncHistory");
    if (isSyncHistory) {
      let ActiveModeItem = this.FR200NursingHistory.ActiveModeItem;
      // 直接进入开始护理状态
      this.setState({
        isShowNurse: true,
        isShowHistoryMsg: true,
        currentServiceData: this.FR200NursingHistory.currentServiceData,
        tempModeCurrent: ActiveModeItem,
        ActiveModeItem: ActiveModeItem,
        activeModeID: ActiveModeItem.id,
        ModeID: "mode_" + ActiveModeItem.id,
        currentTime: this.FR200NursingHistory.currentTime,
      });
      setTimeout(() => {
        // 设置时间组合
        if (ActiveModeItem.serviceData.length > 0) {
          this.setServiceTimeData();
        }
      });
    }
  }
  /** 设置WL200护理历史 */
  setFR200NursingHistory = (jsonStatus: any) => {
    let { currentDevice, ActiveModeItem } = this.state;
    const params = {
      createDate: dayjs().format("YYYY-MM-DD"),
      workMode: jsonStatus.workMode,
      instrumentId: currentDevice.id,
      instrumentName: currentDevice.name,
      modeId: ActiveModeItem.id,
      modeName: ActiveModeItem.modeName,
      id: jsonStatus.id,
      neededTotalSeconds: jsonStatus.neededTotalSeconds,
      jsonStatus,
      ActiveModeItem: this.state.ActiveModeItem,
    };
    this.FR200NursingHistory = JSON.parse(JSON.stringify(params));
    Taro.setStorageSync("FR200NursingHistory", params);
    console.log("保存setFR200NursingHistory");
  };
  /** 更新WL200护理历史运行时间 */
  updateFR200NursingHistory = (data: any = null, jsonStatus = null) => {
    this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");

    if (this.FR200NursingHistory) {
      let params: any = this.FR200NursingHistory;

      // 设置当前时间
      params.currentTime = this.state.currentTime;

      // 设置正确封面
      if (data) {
        params.currentServiceData = data;
      } else {
        let currentServiceData = {
          startSource: "",
          stopSource: "",
        };
        let serviceLength = this.state.ActiveModeItem.serviceData.length;
        if (serviceLength > 0) {
          currentServiceData = this.state.ActiveModeItem.serviceData[0];
        }
        params.currentServiceData = currentServiceData;

        if (jsonStatus) {
          // 缓存每秒数据
          if (!params.dataArray) params.dataArray = [];
          params.dataArray.push(jsonStatus);
        }
      }
      Taro.setStorageSync("FR200NursingHistory", params);
      console.log("更新updateFR200NursingHistory");
    } else {
      this.setFR200NursingHistory(jsonStatus);
    }
  };
  /**
   * @name 删除WL200护理历史
   * @description 参数1 护理历史 参数2 强制删除
   * 如果传入护理历史ID与现有ID相等，则删除。
   * 如果参数二为真，则强制删除
   */
  rmFR200NursingHistory = (FR200NursingHistory, hard = false) => {
    const nowFR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");

    Taro.setStorageSync("FR200Echart", nowFR200NursingHistory); // 临时保存用于观看和调试
    if (nowFR200NursingHistory.id == FR200NursingHistory.id) {
      Taro.removeStorageSync("FR200NursingHistory");
      this.FR200NursingHistory.id = "";
    } else if (hard) {
      Taro.removeStorageSync("FR200NursingHistory");
      this.FR200NursingHistory.id = "";
    }
  };

  /** 提交护理记录 */
  PostNursingLogClock = async (data: any = null, isJump = true) => {
    let { currentDevice, ActiveModeItem } = this.state;

    let params = {};
    if (data) {
      params = data;
    } else {
      params = {
        instrumentId: currentDevice.id,
        instrumentName: currentDevice.name,
        modeId: ActiveModeItem.id,
        modeName: ActiveModeItem.modeName,
        nursingTime: s_to_hms(this.elapsedTime),
      };
    }

    let res: any = await InstrumentInfo.apiNursingLog.addLog(params);
    console.log("PostNursingLogClock", res);

    if (res.data.code === 200) {
      let params = {
        instrumentId: currentDevice.id,
      };
      // 上传护理完成的仪器ID
      let res = await InstrumentInfo.apiClock.addClockInstrument(params);
      console.log(res, "护理完成");

      this.rmFR200NursingHistory(this.FR200NursingHistory); // 护理完成，删除记录
      if (isJump) {
        this.setState({
          isShowNursingSuccess: true,
        });
        setTimeout(() => {
          this.setState({
            isShowNursingSuccess: false,
          });
          this.goFaceReport();
        }, 2000);
      }
    }
  };
  /*** 护理记录 END ***/

  //蓝牙断开连接处理
  bluetoothDisconnectProcessing() {
    clearInterval(timer);
    Taro.offBLEConnectionStateChange(this.listener); // 需传入与监听时同一个的函数对象
    Taro.offBLECharacteristicValueChange((res) => {
      console.log("offBLECharacteristicValueChange", res);
    });
    if (!this.state.isToOTA) {
      Taro.closeBluetoothAdapter();
    }
  }

  /** 获取护理时间组合 */
  getServiceTimeData() {
    const { ActiveModeItem } = this.state;
    let serviceData = ActiveModeItem.serviceData.map((item) => {
      let totalWorkingMinutes = parseInt(
        item.serviceStartTimeStr.split(":")[0]
      ); // 仅分钟数
      let totalWorkingSeconds = parseInt(item.serviceEndTimeStr.split(":")[1]); // 仅秒数
      // let totalWorkingMinutes = 1; // 仅分钟数
      // let totalWorkingSeconds = 0; // 仅秒数
      return {
        totalWorkingMinutes,
        totalWorkingSeconds,
      };
    });
    return serviceData;
  }
  /** 设置护理时间组合 */
  setServiceTimeData() {
    let ServiceTimeData = this.getServiceTimeData();

    // 组合时间
    let ModeStepTimeArray: any = [];
    ServiceTimeData.reduce((old, cur) => {
      let curTime = cur.totalWorkingMinutes * 60 + cur.totalWorkingSeconds;
      let newTotalWorkingMinutes = cur.totalWorkingMinutes;
      let newTotalWorkingSeconds = cur.totalWorkingSeconds;
      if (old) {
        newTotalWorkingMinutes += old.totalWorkingMinutes;
        newTotalWorkingSeconds += old.totalWorkingSeconds;

        let oldTime = old.totalWorkingMinutes * 60 + old.totalWorkingSeconds;
        let value = oldTime + curTime;
        ModeStepTimeArray.push(value);
        return {
          totalWorkingMinutes: newTotalWorkingMinutes,
          totalWorkingSeconds: newTotalWorkingSeconds,
        };
      }
      ModeStepTimeArray.push(curTime);
      return {
        totalWorkingMinutes: newTotalWorkingMinutes,
        totalWorkingSeconds: newTotalWorkingSeconds,
      };
    }, null);
    this.setState({
      ModeStepTimeArray: ModeStepTimeArray,
      ModeStepIndex: 0, // 每次切换组合模式，重置组合步骤
    });
    console.log("组合时间ModeStepTimeArray", ModeStepTimeArray);
  }

  /* 组合模式 */
  /** 获取自定义组合模式数组 */
  getCustomModesArray = () => {
    const { ModeList, ActiveModeItem } = this.state;
    const combineIds = ActiveModeItem.combineData.map(
      (item) => item.combineModeId
    );
    let modesArray = ModeList.filter((item) =>
      combineIds.includes(item.id)
    ).map((item) => {
      let totalWorkingMinutes = parseInt(item.modeTimeStr.split(":")[0]); // 仅分钟数
      let totalWorkingSeconds = parseInt(item.modeTimeStr.split(":")[1]); // 仅秒数
      return {
        workMode: item.modeType,
        totalWorkingMinutes,
        totalWorkingSeconds,
      };
    });
    return modesArray;
  };

  // 护理的错误提示
  showTips(ctx) {
    if (!ctx) return;
    if (showTipsTimer) clearTimeout(showTipsTimer);
    this.setState({
      errorTips: ctx,
    });
    showTipsTimer = setTimeout(() => {
      this.setState({
        errorTips: "",
      });
    }, 2000);
  }

  /** 结束护理弹窗 */
  onEndPlan = async () => {
    this.setState({
      isEndCarePlan: true,
    });
  };
  confirmEndBtn = () => {
    console.log("confirmEndBtn", this.isCheckNurseTime());
    if (this.isCheckNurseTime()) {
      this.endNurseFun();
      this.cancelEndBtn();
    } else {
      this.handleWorkStatus(false, "end");
      this.setState({
        isEndCarePlan: false,
        isNotEnoughTime: true,
      });
    }
  };
  cancelEndBtn = () => {
    this.setState({
      isEndCarePlan: false,
    });
  };
  /** 弹窗 END*/

  // 打开通用错误弹窗
  openErrorTipsText = (str) => {
    this.setState({
      isShowErrorTipsText: true,
      errorTipsText: str,
    });
  };
  // 关闭通用错误弹窗
  closeErrorTipsText = () => {
    this.setState({
      isShowErrorTipsText: false,
    });
  };

  closeNotEnoughTime = () => {
    this.setState({
      isNotEnoughTime: false,
    });
    Taro.reLaunch({
      url: "/pages/index/index",
    });
  };

  /** 完成护理提交：跳转护理报告页 */
  goFaceReport = () => {
    // 跳转前置空定时器，防止重复提交
    if (currentTimeTimer) clearInterval(currentTimeTimer);
    go("/pages/face_report/face_report?id=" + this.state.currentDevice.id);
  };

  // 完成配对
  pairingChange = () => {
    this.setState({
      isConnectShow: false,
      isShowNurse: true,
    });
    setTimeout(() => {
      this.onNursingTap("switch");
    });
  };
  connectionClose = () => {
    this.setState({
      isConnectShow: false,
    });
    Taro.reLaunch({ url: "/pages/index/index" });
  };

  // 手动护理模式切换：提示是否保存护理
  /**仅关闭*/
  closeTipsSave = () => {
    this.setState({
      isShowTipsSave: false,
    });
  };
  /**关闭+切换*/
  cancelTipsSave = () => {
    this.setState({
      isShowTipsSave: false,
    });
    this.modeCurrentFun(this.tempModeCurrent, true); // 不提交护理记录，也不进行校验
  };
  /**关闭+提交+切换*/
  confirmTipsSave = async () => {
    this.setState({
      isShowTipsSave: false,
    });
    this.PostNursingLogClock(null, false); // 先提交护理记录
    this.modeCurrentFun(this.tempModeCurrent, true); // 不进行校验
  };

  /** 初次护理信息弹窗 */
  firstNurseInfo = async () => {
    let { currentDevice } = this.state;
    let res = await InstrumentInfo.firstNurseInfo({
      instrumentId: currentDevice.id,
    });
    console.log(res, "接口");

    if (res.data.code === 200) {
      let isFirstTipShow = getStorageSync(
        "first_instrument_" + currentDevice.id
      );
      console.log(isFirstTipShow, "查看返回值");

      if (!isFirstTipShow) {
        if (res.data.data.length !== 0) {
          // 首次进入页面：自动打开打卡介绍弹窗
          this.setState({ nurseInfo: res.data.data, isFirstTipShow: true });
        }

        setStorageSync("first_instrument_" + currentDevice.id, true);
      } else {
        this.setState({ nurseInfo: res.data.data });
      }
    }
  };
  onTipShowOpen = async () => {
    this.setState({ isFirstTipShow: true });
  };
  onTipShowClose = async () => {
    setStorageSync("first_instrument_" + this.state.currentDevice.id, true);
    this.setState({ isFirstTipShow: false });
  };
  /** 初次护理信息弹窗 END */

  /**
   * @name 设备运行开关按钮是否禁用
   * @description 判断所选模式与设备连接状态是否一致
   * @returns 返回true则禁用
   */
  footerIsDisabled = () => {
    // 默认不禁用，FR200无法禁用
    let isFooterBtnDisabled = false;

    // this.setState({
    //   isFooterBtnDisabled: isFooterBtnDisabled,
    // });

    return isFooterBtnDisabled; // 数据更新有延迟，返回用于判断
  };

  customBack = () => {
    Taro.reLaunch({ url: "/pages/index/index" });
  };

  onModeLockOpen = async () => {
    this.setState({ isModeLock: true });
  };
  onModeLockClose = async () => {
    this.setState({ isModeLock: false });
  };

  render() {
    let {
      title,
      isConnectShow,
      GearData,
      isShowStepTips,
      isShowNurse,
      isStopNurse,
      ModeList,
      ModeType,
      ModeStepIndex,
      currentServiceData,
      ActiveModeItem,
      isSwitchActiveMode,
      ModeID,
      activeModeID,
      isShowCountdown,
      countdown,
      Electricity,
      matrixElectricity,
      errorTips,
      isEndCarePlan,
      currentTime,
      DeviceConnectStatus,
      isShowErrorTipsText,
      errorTipsText,
      isNotEnoughTime,
      isShowNursingSuccess,
      currentDevice,
      isConnectionBlutoot,
      isShowTipsSave,
      isFirstTipShow,
      nurseInfo,
      isShowReReadRecordSave,
      isFooterBtnDisabled,
      isShowHistoryMsg,
      isModeLock,
    } = this.state;

    return (
      <Block>
        <Navbar
          titleSlot={title}
          isBack
          isCustomBack
          customBack={this.customBack}
        />

        <View catchMove>
          <PopupAlert
            isShow={isModeLock}
            zIndex={10020}
            myClassName="level-up"
            title="提示"
            content="该模式即将上线，敬请期待"
            confirmButtonText="我知道了"
            textAlgin="center"
            close={this.onModeLockClose}
            confirm={this.onModeLockClose}
          />
          <PopupInstrumentUploadTips
            isShow={isFirstTipShow}
            zIndex={10020}
            myClassName="level-up"
            title="打卡介绍"
            data={nurseInfo}
            close={this.onTipShowClose}
            confirm={this.onTipShowClose}
          />

          <PopupCountdown isShow={isShowCountdown} countdown={countdown} />

          <PopupConfirm
            isLarge
            isClose
            isShow={isEndCarePlan}
            title="提示"
            content="是否结束护理"
            textAlgin="center"
            cancelButtonText="取消"
            confirmButtonText="确定"
            close={this.cancelEndBtn}
            confirm={this.confirmEndBtn}
          />
          <PopupConfirm
            isLarge
            isClose
            isShow={isSwitchActiveMode}
            title="护理模式切换"
            content={
              <ModeListView
                ModeID={ModeID}
                activeModeID={activeModeID}
                isPop
                isShowNurse={isShowNurse}
                ModeList={ModeList}
                ModeType={ModeType}
                onEmit={this.switchModeCurrentFun}
                onEmitShowAll={this.openModeSwitch}
                onModeLockOpen={this.onModeLockOpen}
              />
            }
            textAlgin="center"
            cancelButtonText="取消"
            confirmButtonText="确定"
            close={this.cancelModeSwitchBtn}
            confirm={this.confirmModeSwitchBtn}
          />

          {ActiveModeItem.openSourceData.length > 0 && (
            <PopupStepTips
              isShow={isShowStepTips}
              isLarge
              isFirstEntry={false}
              confirmButtonText="知道了"
              data={ActiveModeItem.openSourceData}
              close={this.closeStepTips}
            />
          )}

          <PopupAlert
            isShow={isNotEnoughTime}
            isClose
            title="提示"
            content="您的本次护理时间不足，请重新护理"
            confirmButtonText="确认"
            textAlgin="center"
            close={this.closeNotEnoughTime}
            confirm={this.closeNotEnoughTime}
          />

          <PopupAlert
            isShow={isShowErrorTipsText}
            isClose
            zIndex={10020}
            myClassName="level-up"
            title="提示"
            content={errorTipsText}
            confirmButtonText="知道了"
            textAlgin="center"
            close={this.closeErrorTipsText}
            confirm={this.closeErrorTipsText}
          />

          <PopupConfirm
            isShow={isShowTipsSave}
            isClose
            zIndex={10020}
            myClassName="level-up"
            title="提示"
            content={
              <Block>
                <View>当前模式已护理部分时间</View>
                <View>是否保存护理记录</View>
              </Block>
            }
            cancelButtonText="取消"
            confirmButtonText="确认"
            textAlgin="center"
            close={this.closeTipsSave}
            cancel={this.cancelTipsSave}
            confirm={this.confirmTipsSave}
          />

          <PopupStatus
            isShow={isShowNursingSuccess}
            isClose
            title="您已结束本次护理"
            type="success"
            content="正在上传护理记录……"
            confirmButtonText="知道了"
            textAlgin="center"
            close={() => {
              /*不需要做处理*/
            }}
          />

          {isConnectShow && (
            <ConnectionBluetoot
              deviceInfo={currentDevice}
              close={this.connectionClose}
              isDisconnect={!isConnectionBlutoot}
              offlineChange={() => {}}
              pairingChange={this.pairingChange}
              upgradeFun={() => {}}
            />
          )}

          <Popup
            show={isShowHistoryMsg}
            className="custom-popup"
            overlay={false}
          >
            <View className="sync-history-msg">正在同步护理记录...</View>
          </Popup>
        </View>

        <View>
          <View className="iot-main">
            <View className="banner-box">
              <View>
                {!isShowNurse && (
                  <Video
                    className="video-or-image"
                    src={ActiveModeItem.modeVideo}
                    loop
                  />
                )}

                {isShowNurse && (
                  <Block>
                    {isStopNurse ? (
                      <Image
                        className="video-or-image"
                        src={currentServiceData.stopSource}
                      />
                    ) : (
                      <Image
                        className="video-or-image"
                        src={currentServiceData.startSource}
                      />
                    )}
                  </Block>
                )}
                {errorTips && (
                  <Block>
                    <View className="msg-tips">
                      <Image
                        className="msg-tips-img"
                        src={require("@/img/tips.png")}
                      />
                      <View className="msg-tips-content">{errorTips}</View>
                    </View>
                  </Block>
                )}
              </View>

              <View className="iot-device">
                <View className="item">
                  <Text className="device-time">
                    护理时间：
                    <Text className="time">{currentTime}</Text>
                  </Text>
                </View>
                <View className="line" />
                <ElectricityView
                  Electricity={Electricity}
                  matrixElectricity={matrixElectricity}
                  DeviceConnectStatus={DeviceConnectStatus}
                />
              </View>
            </View>

            {ModeList.length > 0 && (
              <ModeListView
                isPop={false}
                isShowNurse={isShowNurse}
                ModeList={ModeList}
                ModeType={ModeType}
                ModeID={ModeID}
                activeModeID={activeModeID}
                onEmit={this.modeCurrentFun}
                onEmitShowAll={this.openModeSwitch}
                onModeLockOpen={this.onModeLockOpen}
              />
            )}

            {ActiveModeItem.combineData && (
              <ModeContent
                isShowNurse={isShowNurse}
                ActiveModeItem={ActiveModeItem}
                ModeStepIndex={ModeStepIndex}
              />
            )}

            <Echarts></Echarts>
            <Gears 
             onEmitMinus={this.handleMinus}
             onEmitAdd={this.handleAdd}
            GearData={GearData}></Gears>
          </View>

          <Footer
            isDisabled={isFooterBtnDisabled}
            isShowNurse={isShowNurse}
            isStopNurse={isStopNurse}
            onEmitStartNurse={this.onStartNurse}
            onEmitSwitchChange={this.onSwitchChange}
            onEmitEndPlan={this.onEndPlan}
            onEmitErrorTips={this.onEmitErrorTips}
          />
        </View>
      </Block>
    );
  }
}

const mapStateToProps = (state) => ({
  bluetoothInfo: state.deviceInfo.bluetoothInfo,
});
const mapDispatchToProps = (dispatch) => ({
  // userRefresh(data) {
  //   dispatch(userRefresh(data));
  // },
});
export default connect(mapStateToProps, mapDispatchToProps)(IotCarePlanFR200);
