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

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

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

/**
 * @name 蓝牙控制函数
 * @description 响应功能需要直接修改私有函数，仅仅是蓝牙解耦，将从页面中抽离出来。
*/
export default class BluetoothContainer {
  bluetoothInfo: any;
  deviceToolKitInstance: any;
  that: any;
  counter: number = 0; // 初始化后，同步执行次数

  constructor(bluetoothInfo: any, deviceToolKitInstance: any, that: any) {
    this.bluetoothInfo = bluetoothInfo;
    this.deviceToolKitInstance = deviceToolKitInstance;
    this.that = that;
  }


  /** @name 设备响应：待机 */
  private syncStandby(jsonStatus) {
    if (BaseModeType.includes(jsonStatus.workMode)) {
      this.that.openTips("检测到您的设备没有紧贴肌肤，请紧贴肌肤");
    }
  }

  /** @name 设备响应：工作 */
  private syncWorking(jsonStatus) {
    // 脸部模式
    if (BaseModeType.includes(jsonStatus.workMode)) {
      this.that.closeTips();
    }
  }

  /** @name 设备响应：暂停 */
  private syncPause(jsonStatus) {
    if (BaseModeType.includes(jsonStatus.workMode)) {
      this.that.openTips(
        "检测到您的设备没有紧贴肌肤，请紧贴肌肤后重新尝试"
      );
    }
  }


  /** @name 查询信息响应 */
  private InfoQuery = {
    /** @name 设备响应：离线记录 */
    syncOfflineClockInInfo: function (jsonStatus) {
      console.log("离线记录", jsonStatus);
    },
    /** @name 设备响应：版本信息 */
    syncVersionInfo: function (jsonStatus) {
      console.log("版本信息", jsonStatus);
    },
    /** @name 设备响应：时间同步 */
    syncTimeSync: function (jsonStatus) {
      console.log("时间同步", jsonStatus);
    }
  }

  /** @name 设备响应：通用状态响应 */
  private syncCommonStatus(jsonStatus) {
    // 1.判断是否水分测试
    if (jsonStatus.workMode === "moistureTest") {
      if (jsonStatus.testStatus === "success") {
        let waterStepList = this.that.state.waterStepList;
        // 到达第几个step
        let waterStepIndex = this.that.state.waterStepIndex;

        // 代表5秒以后最后拿到的结果
        if (waterStepList[waterStepIndex].finish) {
          // 获取等级
          waterStepList[waterStepIndex].forehead =
            jsonStatus.waterLevel;
          // 检测完成
          if (waterStepIndex === 2) {
            this.that.setState({
              isRuningTest: 4,
            });
          } else {
            // 启动检测
            this.that.setState({
              isRuningTest: 1,
            });
          }
          // 一共有3条数据
          let num = waterStepIndex;
          if (waterStepIndex < 2) {
            num = waterStepIndex + 1;
            this.that.waterTestNext(num);
          }
          this.that.setState({
            waterStepIndex: num,
            waterStepList,
          });
        }
      } else {
        let waterStepList = this.that.state.waterStepList;
        let waterStepIndex = this.that.state.waterStepIndex;
        //  5秒后获取的结果
        if (waterStepList[waterStepIndex].finish) {
          // 获取失败后，把进度条清理0
          waterStepList[waterStepIndex].schedule = 0;
          waterStepList[waterStepIndex].finish = false;
          this.that.setState({
            waterStepList,
            isRuningTest: 3,
          });
        }
      }
    }

    // 2.判断工作状态是否与选中仪器一致
    if (jsonStatus?.workMode === this.that.state.ActiveModeItem?.modeType) {
      if (this.that.state.workMode !== jsonStatus?.workMode) {
        this.that.setState({
          workMode: jsonStatus?.workMode, // 仅当设备上报模式与小程序一致时，才允许改变小程序变量缓存
        });
      }
      // 判断设备是否在运行中(护理中)
      // 仅当设备模式与小程序是否一致，才允许更改设备运行时间
      if (this.that.isRuning) {
        if (
          this.that.state.DeviceConnectStatus === 1 &&
          jsonStatus.workStatus !== 'end'
        ) {
          // 水分测试手动检测时间，不自动计算倒计时
          if (jsonStatus?.workMode !== "moistureTest")
            this.that.updateDeviceSyncData(
              {
                totalWorkingMinutes: jsonStatus.totalWorkingMinutes,
                totalWorkingSeconds: jsonStatus.totalWorkingSeconds,
              },
              jsonStatus
            );
        }
      }
    }
  }

  /** @name 设备响应：控制指令响应 */
  private syncDeviceControl(jsonStatus) {
    console.log("设备控制响应", jsonStatus);
    if (jsonStatus.responseStatus == "OK") {
      console.log("发送控制指令成功");
      this.that.workJsonStatus = jsonStatus;
      this.that.workStatus = jsonStatus.workStatus;

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

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

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

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

      if (
        jsonStatus.workMode === 'working' &&
        this.that.isRuning
      ) {
        const { ActiveModeItem } = this.that.state;
        const item = ActiveModeItem;
        if (jsonStatus.workMode !== item?.modeType) {
          // clearTimeout(loadingTipsTimer);
          this.that.setState({
            isShowCountdown: false,
          });
        }
      }
    }
  }





  notifyBLECharacteristicValueChange() {
    notifyBLECharacteristicValueChange({
      deviceId: this.bluetoothInfo.deviceId,
      servicesuuid: this.bluetoothInfo.servicesuuid,
      characteristicsuuid1: this.bluetoothInfo.characteristicsuuid1,
      characteristicsuuid0: this.bluetoothInfo.characteristicsuuid0,
    }).then((res) => {
      Taro.onBLECharacteristicValueChange((value) => {
        const jsonStatus: any = this.deviceToolKitInstance.toJsonStatus(value.value);
        console.log("onBLECharacteristicValueChange 订阅改变：", jsonStatus);
        if (!jsonStatus || jsonStatus == null) {
          return;
        }
        this.that.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.that.switchBLEMatch(jsonStatus);
            break;
          //设备状态同步
          case "DeviceStatusSync":
            if (jsonStatus.battery) {
              // 防止抖动
              this.that.setState({
                Electricity: jsonStatus.battery,
              });
            }

            switch (jsonStatus.workStatus) {
              case "standby":
                //设备的待机状态 可能workMode字段为空

                this.syncStandby(jsonStatus)
                break;
              case "pause":
                this.syncPause(jsonStatus)
                break;
              case "working":
                this.syncWorking(jsonStatus)
                break;
              default:
                break;
            }

            this.syncCommonStatus(jsonStatus);
            break;
          //设备对控制指令的响应
          case "DeviceControl":
            this.syncDeviceControl(jsonStatus);
            break;
          // 设备对信息查询指令的响应
          case "InfoQuery":
            console.log("设备对信息查询指令的响应 InfoQuery", jsonStatus);
            switch (jsonStatus.infoQueryType) {
              // 离线记录
              case "offlineClockInInfo":
                this.InfoQuery.syncOfflineClockInInfo(jsonStatus);
                break;
              // 版本信息
              case "versionInfo":
                this.InfoQuery.syncVersionInfo(jsonStatus);
                break;
              // 时间同步
              case "timeSync":
                this.InfoQuery.syncTimeSync(jsonStatus);
                break;
              default:
                break;
            }
            break;
          default:
            break;
        }
      });


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

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