import Taro from "@tarojs/taro";
import dayjs from "dayjs";
import classnames from "classnames";
import { debounce } from "lodash";

import React, {
  Component,
  PropsWithChildren,
  useEffect,
  useState,
} from "react";
/*** redux ***/
import { connect } from "react-redux";
/*** redux end ***/
import {
  Block,
  View,
  Text,
  Image,
  Video,
  Input,
  Button,
  PageMeta,
} from "@tarojs/components";

import { 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";

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

/* 公共组件 */
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/Electricity";
import ModeListView from "./components/ModeList/FR200";
import Footer from "./components/Footer/FR200";
import WaterTest from "./components/WaterTest/index";
/* 本页组件 END */

import Echarts from "./components/Echart";
import EchartsFullScean from "./components/EchartFullScean";

import Gears from "./components/Gears";

import "./FR200.less";

import BluetoothContainer from "./components/Bluetoot/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 = {};

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

class IotCarePlanWE200 extends Component<any, any> {
  constructor(props) {
    super(props);
    this.state = {
      name: "WE200",
      title: "WE200", // 页面标题
      // 当前设备
      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 },
      ],
      waterStepList: [
        {
          value: "Step1",
          name: "额头",
          finish: false,
          schedule: 0,
          color: "#c2e5f3",
          forehead: 0,
        },
        {
          value: "Step2",
          name: "左脸颊",
          finish: false,
          schedule: 0,
          color: "#c2e5f3",
          forehead: 0,
        },
        {
          value: "Step3",
          name: "右脸颊",
          finish: false,
          schedule: 0,
          color: "#c2e5f3",
          forehead: 0,
        },
      ],
      waterStepIndex: 0,
      // 进度条定时器
      timerIdSchedule: null,
      timerIdSuccess: null,

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

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

      /** 护理过程 */
      currentGear: 5, // 默认档位
      isRuningTest: 1, // 是否正在测试
      isShowStepTips: false, // 是否显示介绍步骤弹窗
      isConnectionBlutoot: true, // 是否已连接蓝牙
      isShowNurse: true, // 是否开始并显示护理 FR200默认已经开始准备护理
      isStopNurse: false, // 是否暂停护理
      isEndNurse: false, // 是否结束护理
      errorTips: "", // 错误提示
      /** 护理过程 END*/

      // 模式列表
      currentWorkModeType: 1, // 现在的模式类型
      currentVideoSrc: "", // 现在模式的视频地址
      isModeLock: false, // 模式是否锁定
      isSwitchActiveMode: false, // 是否显示弹窗切换模式
      ModeList: [],
      ModeType: "all", // all  1基础护理 2专区护理 3专研促渗 4敏期护理 5智能测肤
      ActiveModeItem: {
        openSourceData: [],
      }, // 当前选中模式
      SwitchActiveModeItem: {}, // 切换选中模式
      ModeID: "mode_", // 模式KEY
      activeModeID: "", // 当前选中模式ID:用于高亮
      ModeStepIndex: 0, // 当前护理功效步骤：每个步骤时间不定，所以时间另外计算，根据步骤显示
      ModeStepTimeArray: [], // 护理功效时间步骤，用于切换显示GIF

      // TestModeStepIndex: 0, // 水分测试步骤
      EssenceStepIndex: 0, // 精华促渗步骤
      MaskModeStepIndex: 0, // 面膜促渗步骤

      EssenceBuzzingIndex: 0, // 精华蜂鸣
      EssenceVibrateIndex: 0, // 精华震动
      MaskModeBuzzingIndex: 0, // 面膜蜂鸣
      MaskModeVibrateIndex: 0, // 面膜震动

      currentServiceData: {
        // 当前展示的开启暂停GIF: 因为时间判断不方便，所以单独领出来
        startSource: "",
        stopSource: "",
      },

      // 倒计时
      isShowCountdown: false, // 倒计时弹窗
      countdown: 3,
      // 是否结束护理
      isEndCarePlan: false,
      currentTime: "10:00", // 倒计时时间：WR200以视频为准
      currentVideoTime: "10:00", // 当前视频时间

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

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

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

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

      // isFirstEntryMode: false, // 模式首次打开

      isShowHistoryMsg: false, // 是否显示正在同步历史
      showEcharts: false,
      echartsData: "", //传给echarts图表的数据
      series: [
        {
          data: [2, 3, 5, 3, 5, 6, 8, 5, 6, 4],
          type: "line",
          smooth: true,
          z: 1,
          areaStyle: {},
          color: "red",
        },
        {
          data: [2, 3, 5, 3, 5, 6, 8, 5, 6, 4],
          type: "line",
          smooth: true,
          symbolSize: 10,
          lineStyle: {
            color: "#ff8410",
            width: 1,
          },
          itemStyle: {
            color: "#ff8410",
          },
        },
        {
          name: "a",
          data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
          type: "bar",
          barWidth: 22,
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#ffcf56",
          },
        },
        {
          name: "b",
          data: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#febb22",
          },
        },
        {
          name: "c",
          data: [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#ffac28",
          },
        },
        {
          name: "d",
          data: [0, 0, 1, 0, 1, 1, 1, 1, 1, 1],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#ff8410",
          },
        },
        {
          name: "e",
          data: [0, 0, 1, 0, 1, 1, 1, 1, 1, 0],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#f85804",
          },
        },
        {
          name: "f",
          data: [0, 0, 0, 0, 0, 1, 1, 0, 1, 0],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#e02e14",
          },
        },
        {
          name: "h",
          data: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#b30016",
          },
        },
        {
          name: "i",
          data: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
          type: "bar",
          z: 2,
          stack: "x",
          visualMap: false,
          itemStyle: {
            color: "#750010",
          },
        },
      ],
    };
  }
  bluetoothContainer: any = null;
  isFullScreen: boolean = 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, // 阻抗/能量等级：1档<200  200<2档<280 280<3档<360 后面以此类推每加一档+80抗阻
  };
  // 1档 等于0<200,2档等于200<280,3档等于280<360
  /** FR200模式类型：名称 */
  ModeTypeArray: string[] = [
    "all",
    "base",
    "eyes",
    "zone",
    "permeation",
    "sensitive",
    "intelligence",
  ];

  /** 基础版:脸部/眼部/PRO 设备使用时，会自动开启暂停 */
  BaseModeType: string[] = [
    "face",
    "eyes",
    "nasolabialFold",
    "mandibularLine",
    "headLiftingPro",
  ];

  async onLoad(option) {
    console.log(option, "跳转过来的数据");
    if (option.modeId) {
      this.setState({ activeModeID: option.modeId });
    }
    // 保持屏幕常亮
    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();
    }
  }

  async init() {
    // 查询离线记录汇总
    const queryInstructionParams = {
      commandType: "InfoQuery",
      infoQueryType: "offlineClockInInfo",
      dataType: "summary",
    };
    let commandBuffer = deviceToolKitInstance.toBleCommand(
      queryInstructionParams as any
    );
    sendCommand({ value: commandBuffer }).then((res) => {
      console.log("查询查询离线记录汇总 参数为=>", queryInstructionParams);
    });

    // 监听蓝牙连接状态改变
    Taro.onBLEConnectionStateChange(this.listener);
    this.bluetoothContainer = new BluetoothContainer(
      this.props.bluetoothInfo,
      deviceToolKitInstance,
      this
    );
    this.bluetoothContainer.notifyBLECharacteristicValueChange();

    setTimeout(() => {
      this.handleWorkStatus(false, MODE_WORKING_ENUM.STANDBY);
    }, 1000);
  }
  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, // 关闭倒计时，防止倒计时还在运行
    });
  };

  // 获取模式列表
  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({
          ModeList: res.data.data, // 模式列表
          ActiveModeItem: res.data.data[0], // 让模式列表正常显示
          ModeType: this.ModeTypeArray[res.data.data[0].modeClass],
        });

        if (this.state.activeModeID != "") {
          let res1 = res.data.data.find((e) => e.id == this.state.activeModeID);
          setTimeout(() => {
            this.modeCurrentFun(res1);
          }, 100);
        } else {
          setTimeout(() => {
            this.modeCurrentFun(res.data.data[0]);
          }, 100);
        }
        let res1 = res.data.data.find((e) => e.id == this.state.activeModeID);
        setTimeout(() => {
          this.modeCurrentFun(res1);
        }, 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);
  }

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

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

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

    //  根据模式，动态设置底部按钮样式
    let currentWorkModeType = 1;
    if (data.modeType === "moistureTest") {
      currentWorkModeType = 3;
    } else if (
      data.modeType === "maskPenetration" ||
      data.modeType === "essence" ||
      data.modeType === "led"
    ) {
      currentWorkModeType = 2;
    }

    this.setState({
      ActiveModeItem: data,
      activeModeID: data.id,
      ModeID: "mode_" + data.id,
      ModeStepIndex: 0,
      waterStepIndex: 0, // 水分测试步骤
      EssenceStepIndex: 0, // 精华促渗步骤
      MaskModeStepIndex: 0, // 面膜促渗步骤
      ModeType: this.ModeTypeArray[data.modeClass],
      currentWorkModeType,
    });

    // 切换模式时：重新设置视频地址
    this.VideoSrcLoad(data.modeVideo);

    // 开发中，暂时允许直接切换
    // 每次切换模式时清空一下历史数据
    this.changeItemUpdateFR200NursingHistory();
    this.stepNext(); // 仅切换模式，不执行开始逻辑

    // FR200水分测试不可自动运行，需手动点击开始测试，手动启动检测
    // 其他模式可以自动运行
    if (data.modeType !== "moistureTest") {
      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 && 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 () => {
    this.stepNext();

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

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

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

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

  /** 切换光照 */
  onSwitchChange = async () => {
    let { isStopNurse, ActiveModeItem } = this.state;

    console.log("切换光照，", ActiveModeItem);
    if (ActiveModeItem.modeType === "led") {
      this.onSwitchChangeLED();
      return;
    }

    if (isStopNurse) {
      // 开始光照逻辑
      this.onNursingTap();
      this.switchVideoPlay(); // 开始
    } else {
      // 暂停光照逻辑
      this.handleWorkStatus(false, MODE_WORKING_ENUM.PAUSE);
      this.switchVideoPause(); // 暂停
    }
    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;
    }
  };

  /**监听关机事件*/
  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);
      //对比仪器上报运行的总秒数  和小程序页面运行的已经运行的总秒数，如果不一致就进行校准
      let sceneTime = ActiveModeItem?.breakTimeStr
        ? minSecToS(ActiveModeItem.breakTimeStr)
        : minSecToS(this.state.currentVideoTime); // 场景时间

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

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

      if (
        sceneTime > totalTime &&
        this.isRuning &&
        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 { ActiveModeItem, ModeList, currentVideoTime } = this.state;
    const opts: any = {};
    // ActiveModeItem
    let nowModeItem;
    if (nWorkMode) {
      nowModeItem = ModeList.find((item) => {
        return item.modeType === nWorkMode;
      });
    }
    opts.workStatus = nWorkStatus;

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

    const statusF = {
      sleep: () => {
        this.setState({
          isShowCountdown: false,
        });
      },
      standby: () => {
        this.setState({
          isShowCountdown: false,
        });
      },
      setting: () => {
        this.isRuning = true;
        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,
        });
        this.closeTips();
      },
      pause: () => {
        clearInterval(currentTimeTimer);
        this.setState({
          isShowCountdown: false,
        });
        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,
        ActiveModeItem,
        currentVideoTime,
      } = this.state;
      if (
        this.workStatus == MODE_WORKING_ENUM.WORKING &&
        this.isRuning &&
        DeviceConnectStatus == 1
      ) {
        let totalSeconds = ActiveModeItem?.breakTimeStr
          ? minSecToS(ActiveModeItem.breakTimeStr)
          : minSecToS(currentVideoTime);
        // 现在的倒计时剩余时间：同步时检查是否断开重连，如果是，则使用断开的剩余时长，进行倒计时计算
        let currentSeconds = minSecToS(currentTime);
        let checkTime = totalSeconds - currentSeconds;

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

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

          // 根据不同的模式，切换步骤到下一步
          if (ActiveModeItem.modeType === "essence") {
            this.essencePenetrationNext();
          } else if (ActiveModeItem.modeType === "maskPenetration") {
            this.maskPenetrationNext();
          }
        } else {
          clearInterval(currentTimeTimer);
          this.setState({
            currentTime: "00:00",
            waterStepIndex: 0, // 水分测试步骤
            EssenceStepIndex: 0, // 精华促渗步骤
            MaskModeStepIndex: 0, // 面膜促渗步骤
          });
          this.saveNurseReport(true, "setTimer"); // 保存护理计划，并且结束
        }
      }
    }, 1000);
  };

  // 检测并控制工作状态
  handleWorkStatus = async (isBtnClick: boolean, workStatus) => {
    const { DeviceConnectStatus, ActiveModeItem } = this.state;

    // 如果没有指定工作状态，则切换工作状态
    let newWorkStatus =
      workStatus ||
      (this.workStatus == MODE_WORKING_ENUM.WORKING ? "pause" : "working");

    let sendParams: any = {
      ...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 则用于区分是否切换模式的启动，如果是WL200的切换模式，则倒计时
   */
  onNursingTap(type = "") {
    // 如果已禁止运行，则停止执行后续逻辑
    if (this.state.isRuningTest === 2) return;
    // 防止多次点击
    if (this.state.hadClickStart) return;
    this.setState({
      hadClickStart: true,
    });
    setTimeout(() => {
      this.setState({
        hadClickStart: false,
      });
    }, 500);

    const { DeviceConnectStatus } = this.state;

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

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

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

  /** 检查时间是否达标仪器最低护理时间 */
  isCheckNurseTime() {
    const { currentDevice, currentVideoTime } = this.state;
    let sceneTime = minSecToS(currentVideoTime);
    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, currentVideoTime } =
      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
    );

    if (this.workJsonStatus.workMode) {
      // FR200可能要判断是否水分测试 Test
      // console.log("现在运行的模式：", this.workJsonStatus.workMode);
    }

    // 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.modeId;
    });
    if (!FR200NursingHistory || !recordModeItem) {
      console.log("仪器有数据, 但是缓存没有数据, 忽略");
      return;
    }

    let historyElapsedTime =
      minSecToS(currentVideoTime) - 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");
    console.log(
      this.FR200NursingHistory,
      "获取本地数据++++++++++++++++++++++++++++++++++++++++++"
    );

    // 是否同步历史记录
    let isSyncHistory = Taro.getStorageSync("isSyncHistory");
    if (isSyncHistory) {
      let ActiveModeItem = this.FR200NursingHistory.ActiveModeItem;
      // 直接进入开始护理状态
      this.setState({
        isShowNurse: true,
        isShowHistoryMsg: true,
        videoTime: this.FR200NursingHistory.videoTime,
        tempModeCurrent: ActiveModeItem,
        ActiveModeItem: ActiveModeItem,
        activeModeID: ActiveModeItem.id,
        ModeID: "mode_" + ActiveModeItem.id,
        currentTime: this.FR200NursingHistory.currentTime,
      });
    }
  }
  /** 设置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: dayjs().format("YYYY-MM-DD HH:mm:ss"),
      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: any = null) => {
    this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");

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

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

      // 设置正确封面
      if (!data) {
        if (jsonStatus) {
          // 缓存每秒数据
          if (!params.dataArray) params.dataArray = [];
          params.dataArray.push(jsonStatus);
          params.jsonStatus = jsonStatus;
          params.workMode = jsonStatus?.workMode;
          params.modeId = this.state.ActiveModeItem.id;
          params.modeName = this.state.ActiveModeItem.modeName;

          console.log(jsonStatus, 555555555555);
        }
      } else {
        params.jsonStatus = jsonStatus;
        params.workMode = jsonStatus?.workMode;
        params.modeId = data.id;
        params.modeName = data.modeName;
      }

      Taro.setStorageSync("FR200NursingHistory", params);
      // console.log("更新updateFR200NursingHistory");

      // 基础模式可在这里调用函数更新图标Echarts
      // 最新一条数据jsonStatus
      // 注意事项：只拿working状态
      // todo
    } else {
      this.setFR200NursingHistory(jsonStatus);
    }
  };
  // 改变模式时，清空dataArray，防止数据无限叠加
  changeItemUpdateFR200NursingHistory() {
    this.FR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
    if (this.FR200NursingHistory) {
      this.FR200NursingHistory.dataArray = [];
      Taro.setStorageSync("FR200NursingHistory", this.FR200NursingHistory);
    }
  }
  /**
   * @name 删除WL200护理历史
   * @description 参数1 护理历史 参数2 强制删除
   * 如果传入护理历史ID与现有ID相等，则删除。
   * 如果参数二为真，则强制删除
   */
  rmFR200NursingHistory = (FR200NursingHistory, hard = false) => {
    const nowFR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
    if (nowFR200NursingHistory) {
      Taro.setStorageSync("FR200Echart", nowFR200NursingHistory); // 临时保存用于观看和调试
    }

    Taro.removeStorageSync("FR200NursingHistory");
  };

  // 脸部one
  todoPromise = async () => {
    const nowFR200NursingHistory = Taro.getStorageSync("FR200NursingHistory");
    console.log(nowFR200NursingHistory, "nowFR200NursingHistory");

    // 护理脸部
    if (
      [
        "face",
        "eyes",
        "nasolabialFold",
        "mandibularLine",
        "headLiftingPro",
      ].includes(nowFR200NursingHistory.jsonStatus.workMode)
    ) {
      //  把working=工作中的状态数据筛选出来
      let filtered = nowFR200NursingHistory.dataArray.filter(
        (item) => item.workStatus === "working"
      );
      // 能量发数
      filtered = filtered.slice(0, 360);
      // 脸部能量
      let faceEnergy = 0;
      filtered.forEach((item) => {
        faceEnergy += item.joulePerSecond;
      });
      // 计算平均数
      // let sum = filtered.reduce((accumulator, currentValue) => accumulator + currentValue.impedance, 0);
      // let average = sum / filtered.length;

      // 最大
      let max: any = Math.max(...filtered.map((item) => item.impedance));
      max = this.determineTier(max);
      // 最小
      let min: any = Math.min(...filtered.map((item) => item.impedance));
      min = this.determineTier(min);
      // 平均数最大等级处于2
      let average: any = max / 2;
      average = this.determineTier(average);

      // 能量图里面的图谱每10秒为一个数组
      // 创建一个空数组用于存储分组后的结果
      // 创建一个空数组用于存储分组后的结果
      let groupedAa: any[] = [];
      // 使用循环遍历数组 aa
      for (let i = 0; i < filtered.length; i += 10) {
        // 提取每组的三个对象
        let group = filtered.slice(i, i + 10);

        // 找到组中最大的 name 值
        let maxName = Math.max(...group.map((obj) => obj.impedance));

        // 计算并存储每组的平均数
        let average: any = this.determineTier(maxName / 2);
        // let average = maxName / 2;
        if (average >= 1) {
          average = average - 1;
          average = average * 10;
        }
        // 将包含该组对象和平均数的对象添加到 groupedAa 数组中
        groupedAa.push(average);
      }

      let nursingData = {
        // nursingTime:result,
        nursingData: JSON.stringify({
          faceEnergy,
          max,
          min,
          average,
          groupedAa,
          filtered: filtered.length,
          workMode: nowFR200NursingHistory.workMode,
        }),
      };

      return nursingData;
    }
    return {
      nursingData: JSON.stringify({
        workMode: nowFR200NursingHistory.workMode,
      }),
      showFace: true,
    };
  };

  // 计算挡位
  determineTier = (sun) => {
    // 定义每档的范围
    const tiers = [0, 200, 280, 360, 440, 520, 600, 680, 760, 840];

    // 遍历每一档的范围，找到 sun 所属的档
    for (let i = 0; i < tiers.length; i++) {
      if (sun < tiers[i + 1]) {
        return i + 1;
      }
    }

    // 如果 sun 不在任何一档范围内，返回默认档或处理错误
    return "10";
  };
  /** 提交护理记录：完成护理后自动调用，会跳转页面 */
  PostNursingLogClock = async (data: any = null, isJump = true) => {
    // todo 建议写一个Promise异步函数，用 await 执行,在提交前处理好数据

    // return;
    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 res1: any = await this.todoPromise();
    if (!res1?.showFace) {
      params = { ...params, ...res1 };
    }
    console.log(res1, "查看返回数据");

    let res2: any = await InstrumentInfo.apiNursingLog.addLog(params);
    console.log("PostNursingLogClock", res2);
    if (res2.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(
            res1,
            ActiveModeItem.id,
            res2.data.data,
            currentDevice.id
          ); // 跳转
        }, 2000);
      }
    }
  };
  /*** 护理记录 END ***/

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

  /** 会自动关闭的护理错误提示 */
  showTips(ctx) {
    if (!ctx) return;
    if (showTipsTimer) clearTimeout(showTipsTimer);
    this.setState({
      errorTips: ctx,
    });
    showTipsTimer = setTimeout(() => {
      this.setState({
        errorTips: "",
      });
    }, 2000);
  }
  /** 不自动关闭的护理错误提示 */
  openTips(ctx) {
    if (!ctx) return;
    this.setState({
      errorTips: ctx,
    });
  }
  /** 关闭护理错误提示 */
  closeTips() {
    this.setState({
      errorTips: "",
    });
  }

  /** 结束护理弹窗 */
  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 = async (data, id, deviceid, currentDevice) => {
    let nursingData = JSON.parse(data.nursingData);
    // 跳转前置空定时器，防止重复提交
    if (currentTimeTimer) clearInterval(currentTimeTimer);
    if (
      [
        "face",
        "eyes",
        "nasolabialFold",
        "mandibularLine",
        "headLiftingPro",
      ].includes(nursingData.workMode)
    ) {
      let ids = Number(deviceid);
      // 获取echarts数据 这个是获取接口更新echarts页面
      let res2 = await InstrumentInfo.apiNursingLog.getStatiCDE(ids);

      let nursingDatas = JSON.parse(res2.data.data.nursingData);
      let obj = {
        modeName: res2.data.data.modeName,
        data: nursingDatas,
      };

      let report = true;
      go(
        "/recoding/pages/face_report_one/face_report_one?id=" +
          ids +
          "&report=" +
          report +
          "&obj=" +
          JSON.stringify(obj)
      );
    } else if ("moistureTest" === nursingData.workMode) {
      console.log("水分测试");
    } else {
      console.log("跳转11111111");

      let report = true;

      go(
        "/recoding/pages/face_report/face_report?id=" +
          deviceid +
          "&recordId=" +
          currentDevice +
          "&report=" +
          report
      );
    }
  };

  // 完成配对
  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 */

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

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

  // 获取并设置视频时间
  GetVideosTime = (event) => {
    console.log("获取并设置视频时间GetVideosTime", event?.detail?.duration);
    if (event?.detail?.duration) {
      let duration = Math.floor(event?.detail?.duration);
      let currentTime = s_to_ms(duration);
      this.setState({ currentTime, currentVideoTime: currentTime });
    }
  };

  VideoSrcLoad = (video: string = "") => {
    this.setState({
      currentVideoSrc: "",
    });
    setTimeout(() => {
      this.setState({
        currentVideoSrc: video,
      });
    }, 10);
  };
  switchVideoPlay = () => {
    setTimeout(() => {
      let videoRef = Taro.createVideoContext("myVideo", this);
      videoRef.play();
    }, 100);
  };
  switchVideoPause = () => {
    setTimeout(() => {
      let videoRef = Taro.createVideoContext("myVideo", this);
      videoRef.pause();
    }, 100);
  };

  render() {
    let {
      title,
      isConnectShow,
      GearData,
      waterStepList,
      waterStepIndex,
      isShowStepTips,
      isShowNurse,
      isStopNurse,
      ModeList,
      ModeType,
      ModeStepIndex,
      ActiveModeItem,
      currentWorkModeType,
      isSwitchActiveMode,
      ModeID,
      activeModeID,
      isShowCountdown,
      countdown,
      Electricity,
      errorTips,
      isEndCarePlan,
      currentTime,
      DeviceConnectStatus,
      isShowErrorTipsText,
      errorTipsText,
      isNotEnoughTime,
      isShowNursingSuccess,
      currentDevice,
      isConnectionBlutoot,
      isShowTipsSave,
      isFirstTipShow,
      nurseInfo,
      isRuningTest,
      isShowHistoryMsg,
      isModeLock,
      currentVideoSrc,
      currentGear,
      showEcharts,
      echartsData,
      isShowReReadRecordConnect,
      currentServiceData,
      series,
      isFullScreen,
    } = this.state;

    return (
      <Block>
        <PageMeta pageOrientation="landscape">
          <Navbar
            titleSlot={title}
            isBack
            isCustomBack
            customBack={this.customBack}
          />
          {!isFullScreen && (
            <View>
              <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}
                />

                <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>
                      <Video
                        className="video-or-image"
                        src={currentVideoSrc}
                        loop
                        id="myVideo"
                        objectFit="cover"
                        enablePlayGesture
                        showFullscreenBtn={false}
                        onLoadedMetaData={this.GetVideosTime}
                      />
                      {/* <button onClick={this.executePromises}>点击按钮</button> */}
                      {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="fr200-iot-device">
                      <View className="item">
                        <Text className="device-time">
                          倒计时：<Text className="time">{currentTime}</Text>
                        </Text>
                      </View>
                      <View className="line" />
                      <View className="item">
                        档位：<Text className="gear">{currentGear}</Text>档
                      </View>
                      <View className="line" />
                      <ElectricityView
                        Electricity={Electricity}
                        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}
                    />
                  )}
                  <button onClick={this.updata.bind(this)}>
                    模拟数据更新{" "}
                  </button>
                  {/* <button onClick={this.updata.bind(this)}>添加数据 </button> */}

                  <View className={classnames({ show: showEcharts })}>
                    <Echarts
                      series={series}
                      full={this.full.bind(this)}
                    ></Echarts>

                    <EchartsFullScean
                      series={series}
                      full={this.full}
                    ></EchartsFullScean>
                  </View>

                  {(ActiveModeItem.modeType === "maskPenetration" ||
                    ActiveModeItem.modeType === "essence") && (
                    <Gears
                      onEmitMinus={this.handleMinus}
                      onEmitAdd={this.handleAdd}
                      GearData={GearData}
                    ></Gears>
                  )}

                  {ActiveModeItem.modeType === "moistureTest" && (
                    <WaterTest
                      isRuningTest={isRuningTest}
                      stepList={waterStepList}
                      stepIndex={waterStepIndex}
                    ></WaterTest>
                  )}
                </View>

                <Footer
                  currentWorkModeType={currentWorkModeType}
                  isRuningTest={isRuningTest}
                  isStopNurse={isStopNurse}
                  onEmitStartNurse={this.onStartNurse}
                  onEmitSwitchChange={this.onSwitchChange}
                  onEmitEndPlan={this.onEndPlan}
                  onsuccess={this.onsuccess}
                />
              </View>
            </View>
          )}
          {isFullScreen && (
            <View>
              <button onClick={this.updata.bind(this)}>模拟数据更新 </button>

              <EchartsFullScean
                series={series}
                full={this.full}
              ></EchartsFullScean>
            </View>
          )}
        </PageMeta>
        <View>横屏了</View>
      </Block>
    );
  }
}

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