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,
  useRef,
} from "react";

// import Echarts from "./components/Echart/index";
// import EchartFace from "./components/Echart_face/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/WL200";
import ModeContent from "./components/ModeContent/WL200";
import Footer from "./components/Footer/WL200";
/* 本页组件 END */

import { go, getStorageSync, setStorageSync, msg } from "@/utils/traoAPI";
import { InstrumentInfo } from "@/utils/Interface";
import "./WL200.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 commandMap from "@/utils/commandMap";
import { Popup } from "@antmjs/vantui";

const deviceToolKitInstanceWL200 = new DeviceToolKitWE100("WL200", "WL200");

let currentTimeTimer: any = null; // 当前项目时间定时器
let CountdownTimer: any = null;
let timer: any = null;
let showTipsTimer: any = null;
let loadingTipsTimer: any = null; // 蓝牙连接提示
let switchModeStatus = "free"; // 用于标记是否在切换模式中, free: 空闲, switching: 切换中
// 设备运行时间校准频率，每多少秒校准一次
const TIME_CALIBRATION_FREQUENCY = 5;

// 组合模式：分别对应的是哪几个模式类型
// 黄光590nm
// 红光630nm
// 近红外光830nm

// 模式类型中文名
const WORK_MODE_Chinese_NAME = {
  强效舒缓: "powerfulSoothing",
  维稳修复: "Stability", // 黄光？近红外光?
  均色提亮: "Brighten", // 黄光？近红外光?
  紧致淡纹: "FirmSkin", // 黄光？近红外光?
  自定义: "MaskCustom",
  均色提亮Pro: "BrightenStand",
  紧致淡纹Pro: "FirmSkinStand",
  痘肌舒缓Pro: "SmallpoxSoothingPro",
  痘肌舒缓: "SmallpoxSoothing",
  混合Pro: "MixNursePro",
  混合: "MixNurse",
  头皮护理: "ScalpCare",
};

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,
};
let deviceToolKitInstance = deviceToolKitInstanceWL200;

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

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

      workMode: "", //当前模式
      videoRef: {},
      isMuted: false,
      gear: { gear: 1 },
      currentShowDialog: "",
      step: 1, // 1:选择模式并播放视频, 2:护理中
      showVideoPlayBtn: true, // 视频播放按钮
      duration: 0, // 视频总时长
      hadShowBreakTips: false, // 是否展示过支架断开提示

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

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

      // 模式列表
      isModeLock: false, // 模式锁定
      isSwitchActiveMode: false, // 是否显示弹窗切换模式
      ModeList: [],
      ModeType: "all", // all visor面罩 cabin舱体 yimeish医美
      modeClass: "", // 1面罩 2舱体 3医美
      ActiveModeItem: {
        openSourceData: [],
      }, // 当前选中模式
      SwitchActiveModeItem: {}, // 切换选中模式
      ModeID: "mode_", // 模式KEY
      activeModeID: "", // 当前选中模式ID:用于高亮
      ModeStepIndex: 0, // 当前护理功效步骤：每个步骤时间不定，所以时间另外计算，根据步骤显示
      ModeStepTimeArray: [], // 护理功效时间步骤，用于切换显示GIF
      currentServiceData: {
        // 当前展示的开启暂停GIF: 因为时间判断不方便，所以单独领出来
        startSource: "",
        stopSource: "",
      },

      // 模式组合
      isCombineSuccess: false, // 组合模式是否设置成功
      // 倒计时
      isShowCountdown: false, // 倒计时弹窗
      countdown: 3,
      // 是否结束护理
      isEndCarePlan: false,
      currentTime: "01:00",

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

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

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

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

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

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

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

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

  componentWillUnmount() {}

  componentDidShow() {
    console.log("页面显示了");
    if (!this.hadLoadedPage) {
      this.hadLoadedPage = true; // 二次进入页面（非首次进入）
      return;
    }

    this.getWL200NursingHistory();
    // 重置初始值，每次进入页面重新检查面罩护理记录
    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();
    }

    // 初始化蓝牙
    // 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.tempModeCurrent = res.data.data[0];
        this.setState({
          ActiveModeItem: res.data.data[0],
          ModeList: res.data.data,
          activeModeID: res.data.data[0].id,
          ModeID: "mode_" + res.data.data[0].id,
        });

        // 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;

    // 仅在未开始护理前，切换模式的时候提示模式弹窗
    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;
    let modeArray = ["all", "visor", "cabin", "yimeish"];
    this.setState({
      ActiveModeItem: data,
      activeModeID: data.id,
      ModeID: "mode_" + data.id,
      currentServiceData,
      ModeStepIndex: 0,
      currentTime,
      // ModeType: modeArray[data.modeClass],
    });

    // 只有点击过开始，才隐藏其他模式类型
    if (isShowNurse) {
      this.setState({
        ModeType: modeArray[data.modeClass],
      });
    }

    setTimeout(() => {
      // 设置时间组合
      if (data.serviceData.length > 0) {
        this.setServiceTimeData();
      }
      // 存在组合模式时，设置组合模式
      if (data.combineData.length > 0) {
        this.setCustomMaskData();
      }
    });

    // 如果是正在运行中切换，则直接准备运行
    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.state.step == 2 && this.state.facialMaskConnectStatus == 1) {
        // 提示切换护理模式
        if (this.isCheckNurseTime()) {
          // 满足时间条件，提示是否保存部分护理记录
          this.judgementWorkStatus(
            MODE_WORKING_ENUM.PAUSE,
            this.state.ActiveModeItem?.modeType
          );
          this.setState({
            isShowTipsSave: true,
          });
        }
        return true;
      }
    }
    return false;
  }

  /** 切换护理模式 */
  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);

    let modeArray = ["all", "visor", "cabin", "yimeish"];
    this.setState({
      ModeType: modeArray[SwitchActiveModeItem.modeClass],
    });
  };

  stepNext = () => {
    // //0未定义（全部）  1面罩模式 2舱体模式 3医美术后
    let modeArray = ["all", "visor", "cabin", "yimeish"];
    let modeClass = this.state.ActiveModeItem.modeClass;
    this.workStatus = "pause";
    this.setState({
      ModeType: modeArray[modeClass],
      isShowNurse: true,
      isStopNurse: true,
      step: 2,
    });

    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 isCabinMode是否舱体模式。 0.检测面罩与舱体是否仍在连接中，需要分离 1.检测是否连接失败，需要重新连接
   */
  onEmitErrorTips = async () => {
    setTimeout(() => {
      let { ActiveModeItem } = this.state;

      // 按钮不可点击时，提示报错
      let isDisabled = this.footerIsDisabled();
      if (isDisabled) {
        if (ActiveModeItem.isCabinMode === 0) {
          this.showTips("检测到面罩与舱体仍在连接中，该模式需要分离面罩和舱体");
        } else {
          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);
    let { ActiveModeItem } = this.state;
    switch (jsonStatus.bleCommandType) {
      // 如果设备配对链接发送配对码的时候，设备应答小程序配对码是否正确。
      case "SendMatchCode":
        if (jsonStatus.matchedSuccess) {
          console.log("设备配对成功");
          this.setState({
            facialMaskConnectStatus: 1,
          });
        }
        break;

      // 设备状态主动上报，这种指令是主机主动上报某个附属设备断开或者连上了
      case "BleStatusSync":
        console.log("BleStatusSync 附属设备状态主动上报", jsonStatus);
        switch (jsonStatus.connectMessage?.deviceName) {
          case "WL200":
            if (jsonStatus.connectMessage?.connectType == "CONNECTED") {
            } else {
              this.setState({
                facialMaskConnectStatus: 0, // 蓝牙断开
                isFooterBtnDisabled: false, // 蓝牙断开所以不可点击
              });
              // 断开连接直接暂停:会自动暂停定时器
              this.judgementWorkStatus(
                MODE_WORKING_ENUM.PAUSE,
                ActiveModeItem?.modeType
              );
              // 设备断开时，给定一个断开时间
              ActiveModeItem.breakTimeStr = this.state.currentTime;
            }
            break;
          // 附属设备是否连接支架
          case "Stand":
            if (jsonStatus.connectMessage?.connectType == "CONNECTED") {
              console.log("舱体支架连接");
              this.setState({
                isStandStatus: true,
              });
              if (!this.state.isStandStatus && this.state.step === 2) {
                // 断开连接直接暂停
                this.judgementWorkStatus(
                  MODE_WORKING_ENUM.PAUSE,
                  ActiveModeItem?.modeType
                );
              }
            } else {
              console.log("舱体支架断开连接");

              if (this.state.isStandStatus && this.state.step === 2) {
                // 断开连接直接暂停
                this.judgementWorkStatus(
                  MODE_WORKING_ENUM.PAUSE,
                  ActiveModeItem?.modeType
                );
              }

              // 设备断开时，给定一个断开时间
              ActiveModeItem.breakTimeStr = this.state.currentTime;

              this.setState({
                isStandStatus: false,
                isStopNurse: true,
                ActiveModeItem,
              });

              setTimeout(() => {
                this.onEmitErrorTips();
              }, 500);
            }
            setTimeout(() => {
              this.footerIsDisabled();
            }, 100);
            break;
          default:
            console.log("监听到到设备连接状态改变 this.footerIsDisabled()");
            this.footerIsDisabled(); // 判断底部运行按钮是否可点击
            break;
        }
        break;

      //小程序主动问主机，现在链接了哪些附属设备，这时候主机给小程序的回复消息
      case "QueryMatchStatus":
        console.log("QueryMatchStatus 设备回复小程序", jsonStatus);

        const isStandDevice = jsonStatus?.subDeviceList?.includes("Stand");
        deviceToolKitInstance = deviceToolKitInstanceWL200;
        console.log("支架是否链接", isStandDevice);
        this.setState({
          isStandStatus: isStandDevice,
        });
        setTimeout(() => {
          this.footerIsDisabled();
        });

        // 连上面罩后, 获取仪器记录, 与缓存信息对比
        if (!this.hadGotInstrumentHistoryData) {
          // 查询护理记录
          this.getInstrumentHistoryData();

          // 查询仪器状态
          const queryDeviceArrayBuffer = deviceToolKitInstance.toBleCommand(
            bleCommandSamples.queryDeviceStatus as any
          );
          console.log("发送查询设备指令 获取仪器状态");
          sendCommand({
            value: queryDeviceArrayBuffer,
          });
        }
    }
  };

  // 蓝牙特征更改
  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 "DeviceControl":
            console.log("打印小程序控制设备，给设备发送的指令", jsonStatus);
            //   setTimeout(() => {
            //     console.log("currentTime", this.state.currentTime);
            //   });
            break;
          //设备主动上报给小程序的指令 一般是工作状态改变
          case "DeviceStatusSync":
            console.log(
              "设备主动上报给小程序的指令 一般是工作状态改变",
              jsonStatus
            );

            this.workJsonStatus = jsonStatus;
            this.workStatus = jsonStatus.workStatus;

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

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

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

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

            if (
              jsonStatus.workMode === MODE_WORKING_ENUM.WORKING &&
              this.state.step == 2
            ) {
              const { ActiveModeItem } = this.state;
              const item = ActiveModeItem;
              if (jsonStatus.workMode !== item.modeType) {
                clearTimeout(loadingTipsTimer);
                this.setState({
                  isShowCountdown: false,
                });
              }
            }
            break;
          //设备信息查询返回
          case "InfoQuery":
            switch (jsonStatus.infoQueryType) {
              // 自定义模式设置
              case "customModeSet":
                console.log(">>>>>>>>>>>>>>>设置自定义模式>>>>>>>>>>>>>>>");
                console.log(
                  "InfoQuery customModeSet responseStatus=====>",
                  jsonStatus
                );

                if (jsonStatus.responseStatus == "OK") {
                  console.log("设置成功自定义模式");
                  this.setState({
                    isCombineSuccess: true,
                  });
                }
                break;
              // 自定义模式信息
              case "customModeInfo":
                console.log(">>>>>>>>>>>>>>>查询自定义模式信息>>>>>>>>>>>>>>>");
                console.log(
                  "InfoQuery customModeInfo responseStatus=====>",
                  jsonStatus
                );
                break;
              case "versionInfo":
                break;
              // 当前报告
              case "currentMaskReportInfo":
                // 每次切换模式并开始运行后，生成一个新的自增ID
                // commandType: "InfoQuery"
                // createDate: ""
                // gear: 0
                // id: 73
                // infoQueryType: "currentMaskReportInfo"
                // neededTotalSeconds: 900
                // totalSeconds: 0
                // workMode: "BrightenStand"
                console.log("当前面罩报告 currentMaskReportInfo", jsonStatus);

                if (!this.hadCheckReport) {
                  this.hadCheckReport = true;
                  this.checkInstrumentRecord(jsonStatus);
                } else {
                  this.setWL200NursingHistory(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.rmWL200NursingHistory(this.WL200NursingHistory, 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.state.step == 2 &&
        this.state.facialMaskConnectStatus == 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.updateWL200NursingHistory();
      }, 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 { step, 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 && step == 2) {
          opts.currentTime = nowCurrentTime;
        } else if (!nowModeItem?.isCabinMode && step == 2) {
          // fix: 启动非支架模式倒计时时，连上支架，仪器的状态变为standby
          opts.step = 1;
        }
      },
      setting: () => {
        // that.data.hadShowBreakTips = false;
        this.setState({
          hadShowBreakTips: false,
        });
        if (step != 2 && !ActiveModeItem.isCabinMode) {
          opts.step = 2;
          this.setState({
            title: "正在护理",
            isStopNurse: false,
          });
        } else if (step != 2 && ActiveModeItem.isCabinMode) {
          opts.step = 2;
          // this.setState({
          //   title: "正在护理",
          // });
          this.setState({
            title: "正在护理",
            isStopNurse: false,
          });
        }
        if (nowModeItem) {
          opts.currentTime = nowCurrentTime;
        }
        // startSettingCountDown 用于标记打开了倒计时loading
        if (!this.state.isShowCountdown) {
          this.setState({
            isShowCountdown: true,
          });
          this.setLoadingTips(CountDownTime[workMode] || 6);
        }
      },
      working: () => {
        if (this.state.facialMaskConnectStatus != 1) {
          opts.workStatus = MODE_WORKING_ENUM.STANDBY;
          opts.step = 1;
        } else if (step != 2) {
          opts.step = 2;
          this.setState({
            title: "正在护理",
            isStopNurse: false,
          });
        }

        this.setState({
          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 {
        step,
        facialMaskConnectStatus,
        currentTime,
        ModeStepTimeArray,
        ModeStepIndex,
        ActiveModeItem,
      } = this.state;
      if (
        this.workStatus == MODE_WORKING_ENUM.WORKING &&
        step == 2 &&
        facialMaskConnectStatus == 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 { facialMaskConnectStatus, isStandStatus, ActiveModeItem } =
      this.state;
    let newWorkStatus =
      workStatus ||
      (this.workStatus == MODE_WORKING_ENUM.WORKING ? "pause" : "working");
    if (isBtnClick && newWorkStatus == "working") {
      // 舱体模式
      if (ActiveModeItem.isCabinMode === 1 && !isStandStatus) {
        this.showTips(
          `检测到舱体未连接成功，请确认面罩开机后与舱体连接，并接通舱体电源`
        );
        return;
      }
      // 非舱体模式
      if (!ActiveModeItem.isCabinMode && facialMaskConnectStatus != 1) {
        console.log("facialMaskConnectStatus", facialMaskConnectStatus);
        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, isStandStatus, facialMaskConnectStatus } =
      this.state;

    if (isStandStatus === true && ActiveModeItem.isCabinMode === 0) {
      console.log("已连接舱体，只可选择舱体模式");
      return;
    }
    if (isStandStatus === false && ActiveModeItem.isCabinMode === 1) {
      console.log("未连接舱体！");
      return;
    }

    console.info(
      commandMap.WL200Command,
      "点击开始护理按钮",
      `当前模式: ${ActiveModeItem.modeType}`,
      `当前面罩状态:${facialMaskConnectStatus}`,
      `当前仪器模式:${this.workStatus}`
    );
    console.log(ActiveModeItem);
    console.log("isStandStatus:" + isStandStatus);

    if (facialMaskConnectStatus != 1) {
      console.log("facialMaskConnectStatus 开始处", facialMaskConnectStatus);
      this.showTips("检测到面罩未连接成功，请确认面罩开机并佩戴");
      return;
    }
    // 如果是强效舒缓,需要判断是否连接支架
    if (ActiveModeItem.isCabinMode && !isStandStatus) {
      this.showTips(
        `检测到舱体未连接成功，请确认面罩开机后与舱体连接，并接通舱体电源`
      );
      return;
    } else if (!ActiveModeItem.isCabinMode && isStandStatus) {
      this.showTips(`检测到面罩仍和舱体连接中，请分离后切换`);
      return;
    }
    if (
      ActiveModeItem.modeType === "MaskCustom" &&
      !this.state.isCombineSuccess
    ) {
      this.showTips(`${ActiveModeItem.modeName}模式设置失败，请联系小助手`);
      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 ***/
  /** 小程序查询护理记录 */
  getInstrumentHistoryData() {
    this.hadGotInstrumentHistoryData = true;
    console.log("发送指令currentMaskReportInfo 获取设备护理记录");
    setTimeout(() => {
      const queryCurrentMaskReportInfoBuffer =
        deviceToolKitInstance.toBleCommand({
          ...(bleCommandSamples.queryCurrentMaskReportInfo as any),
        });
      sendCommand({
        value: queryCurrentMaskReportInfoBuffer,
      });
    }, 3000);
  }
  /**
   * @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) {
      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 WL200NursingHistory = this.WL200NursingHistory;
    if (!this.WL200NursingHistory) {
      console.log("小程序缓存没有数据, 忽略");
      if (
        workStatus == MODE_WORKING_ENUM.WORKING ||
        workStatus == MODE_WORKING_ENUM.PAUSE
      ) {
        // 缓存没有数据, 要存缓存
        this.setWL200NursingHistory(jsonStatus);
      }
      return;
    }

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

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

    console.log("workStatus", workStatus);
    console.log("jsonStatus", jsonStatus, this.workJsonStatus);
    console.log("currentTime", WL200NursingHistory.currentTime);
    console.log("isStandStatus", this.state.isStandStatus);

    let historyElapsedTime =
      minSecToS(recordModeItem.modeTimeStr) -
      minSecToS(WL200NursingHistory.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 == WL200NursingHistory.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.rmWL200NursingHistory(WL200NursingHistory);
          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.rmWL200NursingHistory(WL200NursingHistory);
      } 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.rmWL200NursingHistory(WL200NursingHistory);
      }
    } else {
      console.log("id一致, 设备运行中或暂停");
      // 5.判断设备状态-运行中
      // 同步时间
      if (jsonStatus.id == WL200NursingHistory.id) {
        if (WL200NursingHistory.currentTime) {
          this.setState({
            step: 2,
          });
          this.resetTimer();
        }
      }
    }
  };

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

    // 是否同步历史记录
    let isSyncHistory = Taro.getStorageSync("isSyncHistory");
    if (isSyncHistory) {
      let ActiveModeItem = this.WL200NursingHistory.ActiveModeItem;
      // 直接进入开始护理状态
      this.setState({
        isShowNurse: true,
        isShowHistoryMsg: true,
        currentServiceData: this.WL200NursingHistory.currentServiceData,
        tempModeCurrent: ActiveModeItem,
        ActiveModeItem: ActiveModeItem,
        activeModeID: ActiveModeItem.id,
        ModeID: "mode_" + ActiveModeItem.id,
        currentTime: this.WL200NursingHistory.currentTime,
      });
      setTimeout(() => {
        // 设置时间组合
        if (ActiveModeItem.serviceData.length > 0) {
          this.setServiceTimeData();
        }
        // 存在组合模式时，设置组合模式
        if (ActiveModeItem.combineData.length > 0) {
          this.setCustomMaskData();
        }
      });
    }
  }
  /** 设置WL200护理历史 */
  setWL200NursingHistory = (jsonStatus: any) => {
    let { currentDevice, ActiveModeItem, ModeList } = 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.WL200NursingHistory = JSON.parse(JSON.stringify(params));
    Taro.setStorageSync("WL200NursingHistory", params);
    console.log("保存setWL200NursingHistory");
  };
  /** 更新WL200护理历史运行时间 */
  updateWL200NursingHistory = (data: any = null) => {
    this.WL200NursingHistory = Taro.getStorageSync("WL200NursingHistory");

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

      // 设置当前时间
      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;
      }
      Taro.setStorageSync("WL200NursingHistory", params);
      console.log("更新updateWL200NursingHistory");
    }
  };
  /**
   * @name 删除WL200护理历史
   * @description 参数1 护理历史 参数2 强制删除
   * 如果传入护理历史ID与现有ID相等，则删除。
   * 如果参数二为真，则强制删除
   */
  rmWL200NursingHistory = (WL200NursingHistory, hard = false) => {
    const nowWL200NursingHistory = Taro.getStorageSync("WL200NursingHistory");
    if (nowWL200NursingHistory.id == WL200NursingHistory.id) {
      Taro.removeStorageSync("WL200NursingHistory");
      this.WL200NursingHistory.id = "";
    } else if (hard) {
      Taro.removeStorageSync("WL200NursingHistory");
      this.WL200NursingHistory.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.rmWL200NursingHistory(this.WL200NursingHistory); // 护理完成，删除记录
      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;
  };
  setCustomMaskData() {
    console.log("================");
    console.log("setCustomMaskData");
    console.log("================");

    // modesArray 发送组合模式数组指令到设备存储
    let modesArray = this.getCustomModesArray();
    console.log("组合模式modesArray", modesArray);

    let customModeSetCommand = {
      commandType: "InfoQuery",
      infoQueryType: "customModeSet",
      modesArray,
    };
    let commandBuffer = deviceToolKitInstance.toBleCommand(
      customModeSetCommand as any
    );
    sendCommand({
      value: commandBuffer,
    }).then((res) => {
      console.info("发送切换组合模式指令成功", res);
    });
  }
  // 发送启动组合模式指令
  startCombinationMode() {
    const jsonCommand = {
      commandType: "DeviceControl",
      workStatus: "working",
      workMode: "MaskCustom",
    };
    let commandBuffer = deviceToolKitInstance.toBleCommand(jsonCommand as any);
    sendCommand({
      value: commandBuffer,
    }).then(() => {
      console.info("发送启动组合模式指令成功  参数为 =>", jsonCommand);
    });
  }

  // 护理的错误提示
  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.switchTab({ 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 = () => {
    let { isStandStatus } = this.state;
    let isCanClick = isStandStatus
      ? this.tempModeCurrent?.isCabinMode === 1
      : this.tempModeCurrent?.isCabinMode === 0;
    // 如果舱体状态和模式类型不相等，则禁用
    let isFooterBtnDisabled = false;

    if (!isCanClick) {
      isFooterBtnDisabled = true;
    }
    console.log("isCanClick", isCanClick);
    console.log("isFooterBtnDisabled", isFooterBtnDisabled);
    // 仅在值变化时更新state
    // if (isFooterBtnDisabled !== this.state.isFooterBtnDisabled) {
    this.setState({
      isFooterBtnDisabled: isFooterBtnDisabled,
    });
    // }

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

  handleClickVideo = () => {
    let videoRef = Taro.createVideoContext("myVideo");
    // 开始播放
    videoRef.play();
    // 暂停播放
    videoRef.pause();
    console.log("暂停播放", videoRef);
  };
  handleClicksound = () => {
    let isMuted = this.state.isMuted;
    isMuted = !isMuted;
    this.setState({ isMuted });
  };
  GetVideosTime = (event) => {
    let videoRef = Taro.createVideoContext("myVideo", this);
    // videoRef.currentTime
    console.log("获取播放时间", event.detail.currentTime);
  };
  onPlay = (e) => {
    console.log("出发", e);
  };
  customBack = () => {
    Taro.switchTab({ url: "/pages/index/index" });
  };

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

  render() {
    let {
      title,
      isConnectShow,
      isShowStepTips,
      isShowNurse,

      isStopNurse,
      ModeList,
      ModeType,
      ModeStepIndex,
      currentServiceData,
      ActiveModeItem,
      SwitchActiveModeItem,
      isSwitchActiveMode,
      ModeID,
      activeModeID,
      isShowCountdown,
      countdown,
      Electricity,
      isMuted,
      matrixElectricity,
      errorTips,
      isEndCarePlan,
      currentTime,
      facialMaskConnectStatus,
      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"
            isClose={false}
            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
                    id="myVideo"
                    onPlay={this.onPlay}
                    muted={isMuted}
                    onTimeUpdate={this.GetVideosTime}
                  />
                )}
                {/* <button onClick={this.GetVideosTime}>获取视频时长</button> */}
                {/* <button onClick={this.handleClicksound}>音频播放/音频暂停</button> */}
                {/* <button onClick={this.handleClickVideo}>播放/暂停</button> */}
                {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={facialMaskConnectStatus}
                />
              </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>
            <EchartFace></EchartFace> */}
          </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)(IotCarePlanWL200);

// isCharging
