// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
async function asyncPlayDragonBoneAnimation(
  node,
  animationName,
  time = 1,
  onFrameEvent = null
) {
  return new Promise((resolve, reject) => {
    node
      .getComponent(dragonBones.ArmatureDisplay)
      .once(dragonBones.EventObject.COMPLETE, () => {
        resolve(null);
      });

    node
      .getComponent(dragonBones.ArmatureDisplay)
      .on(dragonBones.EventObject.FRAME_EVENT, ({ name }) => {
        if (onFrameEvent && typeof onFrameEvent == "function") {
          onFrameEvent(name);
        }
      });

    node
      .getComponent(dragonBones.ArmatureDisplay)
      .playAnimation(animationName, time);
  });
}

function playAudioByUrl(audio_url, cb = null) {
  return new Promise((resolve, reject) => {
    if (audio_url) {
      cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
        const audioId = cc.audioEngine.play(audioClip, false, 0.8);
        resolve(audioId);
        if (cb) {
          cc.audioEngine.setFinishCallback(audioId, () => {
            cb();
          });
        }
      });
    } else {
      resolve(0);
      if (cb) {
        cb();
      }
    }
  });
}

cc.Class({
  extends: cc.Component,

  properties: {
    // foo: {
    //     // ATTRIBUTES:
    //     default: null,        // The default value will be used only when the component attaching
    //                           // to a node for the first time
    //     type: cc.SpriteFrame, // optional, default is typeof default
    //     serializable: true,   // optional, default is true
    // },
    // bar: {
    //     get () {
    //         return this._bar;
    //     },
    //     set (value) {
    //         this._bar = value;
    //     }
    // },
    audioBeforeTest: "",
    testTime: 10,
    recordWaitCount: 0,
  },

  // LIFE-CYCLE CALLBACKS:

  // onLoad () {},
  _timeoutID: null,
  isStop: null,
  start() {},
  init(audio_url, testTime) {
    this.audioBeforeTest = audio_url;
    this.testTime = testTime;
  },

  showVoice(node, testLetter) {
    this.isStop = false;
    return new Promise((resolve, reject) => {
      let voice = this.node;
      voice.active = true;

      let gray = voice.getChildByName("gray");
      let catBase = voice.getChildByName("catBase");
      let img = voice.getChildByName("img");
      let progress = voice.getChildByName("progress");
      let imgLight = voice.getChildByName("bg_light");
      let imgGood = voice.getChildByName("good");
      let imgTry = voice.getChildByName("try");

      progress.active = true;
      img.active = true;
      imgLight.active = false;
      imgGood.active = false;
      imgTry.active = false;
      catBase.active = true;

      //img需要clone对应的节点塞进去。
      img.removeAllChildren();
      let cloneNode = cc.instantiate(node);
      cloneNode.x = 0;
      cloneNode.y = 0;
      img.addChild(cloneNode);

      let progressBar = progress.getComponent(cc.ProgressBar);
      progressBar.progress = 1;
      let url = this.recordWaitCount == 0 ? this.audioBeforeTest : "";
      let cat = cc.find("cat", catBase);
      asyncPlayDragonBoneAnimation(cat, "begin", 0);
      // 录音前停止所有音频
      cc.audioEngine.stopAll();
      playAudioByUrl(url, () => {
        if(this.isStop) {
          return
        }
        asyncPlayDragonBoneAnimation(cat, "record", 0);
        cc.tween(progressBar)
          .to(this.testTime, { progress: 0 })
          .call(() => {})
          .start();

        console.log("startTest->" + testLetter);
        window.courseware && window.courseware.startTest(testLetter); //开始录音
        this._timeoutID = setTimeout(async () => {
          if (!window.courseware) {
            let testData = {
              dtLastResponse: "2021-09-17 13:36:26:109",
              refText: "I haven't found anything out about him yet.",
              recordId: "6144295213f0a2200000ed93",
              eof: 1,
              result: {
                pronunciation: 25,
                resource_version: "3.1.0",
                fluency: 60,
                rhythm: 90,
                kernel_version: "5.2.4",
                overall: 80, //25
                integrity: 100,
                duration: "6.779",
                rear_tone: "fall",
                speed: 96,
                words: [
                  {
                    phonemes: [
                      {
                        phoneme: "w",
                        pronunciation: 55,
                        span: {
                          end: 95,
                          start: 88,
                        },
                      },
                      {
                        phoneme: "ɛ",
                        pronunciation: 100,
                        span: {
                          end: 107,
                          start: 95,
                        },
                      },
                      {
                        phoneme: "r",
                        pronunciation: 99,
                        span: {
                          end: 123,
                          start: 107,
                        },
                      },
                    ],
                    phonics: [
                      {
                        overall: 85,
                        phoneme: ["w", "ɛ", "r"],
                        spell: "Where",
                      },
                    ],
                    scores: {
                      overall: 80,
                      pronunciation: 92,
                    },
                    span: {
                      end: 123,
                      start: 88,
                    },
                    word: "Where",
                  },
                  {
                    phonemes: [
                      {
                        phoneme: "w",
                        pronunciation: 55,
                        span: {
                          end: 95,
                          start: 88,
                        },
                      },
                      {
                        phoneme: "ɛ",
                        pronunciation: 100,
                        span: {
                          end: 107,
                          start: 95,
                        },
                      },
                      {
                        phoneme: "r",
                        pronunciation: 99,
                        span: {
                          end: 123,
                          start: 107,
                        },
                      },
                    ],
                    phonics: [
                      {
                        overall: 85,
                        phoneme: ["w", "ɛ", "r"],
                        spell: "Where",
                      },
                    ],
                    scores: {
                      overall: 10,
                      pronunciation: 92,
                    },
                    span: {
                      end: 123,
                      start: 88,
                    },
                    word: "Where",
                  },
                ],
              },
              tokenId: "6144295408558b08dd000001",
              applicationId: "154838659000009e",
            };
            this.recordWaitCount++;
            if (this.recrodEnd(testData)) {
              this.playLocalAudio("right");
              asyncPlayDragonBoneAnimation(cat, "right", 1);
              await this.showVoiceGood();
              this.hideVoice();
              return resolve(true);
            } else {
              this.playLocalAudio("wrong");
              asyncPlayDragonBoneAnimation(cat, "wrong", 1);
              await this.showVoiceTry();
              this.hideVoice();
              return resolve(false);
            }
          }
          // await pg.time.delay(5);
          window.courseware &&
            window.courseware.stopTest(async (data) => {
              this.recordWaitCount++;
              data = JSON.parse(data);
              if (this.recrodEnd(data)) {
                this.playLocalAudio("right");
                asyncPlayDragonBoneAnimation(cat, "right", 1);
                await this.showVoiceGood();
                this.hideVoice();
                return resolve(true);
              } else {
                this.playLocalAudio("wrong");
                asyncPlayDragonBoneAnimation(cat, "wrong", 1);
                await this.showVoiceTry();
                this.hideVoice();
                return resolve(false);
              }
            }); //结束录音
        }, this.testTime * 1000);
        console.log(this._timeoutID)
      });
    });
  },

  showVoiceGood() {
    return new Promise((resolve, reject) => {
      let voice = this.node;
      voice.active = true;
      let imgLight = voice.getChildByName("bg_light");
      let imgGood = voice.getChildByName("good");
      let imgTry = voice.getChildByName("try");
      imgLight.active = true;
      cc.Tween.stopAllByTarget(imgLight);
      cc.tween(imgLight).by(3, { angle: 360 }).repeatForever().start();
      imgGood.active = true;
      imgTry.active = false;
      
      this.scheduleOnce(() => {
        resolve("");
      }, 2);
    });
  },

  showVoiceTry() {
    return new Promise((resolve, reject) => {
      let voice = this.node;
      voice.active = true;
      let imgLight = voice.getChildByName("bg_light");
      let imgGood = voice.getChildByName("good");
      let imgTry = voice.getChildByName("try");
      imgLight.active = true;
      cc.Tween.stopAllByTarget(imgLight);
      cc.tween(imgLight).by(3, { angle: 360 }).repeatForever().start();
      imgGood.active = false;
      imgTry.active = true;
      this.scheduleOnce(() => {
        resolve("");
      }, 2);
    });
  },

  recrodEnd(data) {
    // return true;
    let score = data.result.overall;
    let isSuccess = this.checkWords(data);
    console.log("score->" + score);
    console.log("isSuccess->" + isSuccess);
    if (score >= 70 && isSuccess) {
      return true;
    } else {
      return false;
    }
  },

  checkWords(data) {
    const sentences = data.result.sentences;
    if (!sentences) return true;
    for (let i = 0; i < sentences.length; i++) {
      const details = sentences[i].details;
      const isSuccess = details.some((item) => item.overall <= 40);
      if (isSuccess) return false;
    }
    return true;
  },

  hideVoice() {
    let voice = this.node;
    voice.active = false;
  },

  stopTesting() {
    console.log(this._timeoutID)
    if(this._timeoutID) {
      clearTimeout(this._timeoutID);
    }
    this.isStop = true;
    this.hideVoice();
  },
    
  playLocalAudio(audioName) {
    const audio = cc
      .find(`audioClips/${audioName}`, this.node)
      .getComponent(cc.AudioSource);
    return new Promise((resolve, reject) => {
      const id = cc.audioEngine.playEffect(audio.clip, false);
      cc.audioEngine.setFinishCallback(id, () => {
        resolve(id);
      });
    });
  },

  onDestroy() {
    if(this._timeoutID) {
      clearTimeout(this._timeoutID);
    }
  },
  // update (dt) {},
});
