import { initAir } from "./air";

cc.Class({
  extends: cc.Component,
  properties: {},

  getData(callBack) {
    const uri = "courseware/v1/getdata";
    let syllabus_id = this.bundleInfoList[this.currentBundleIndex].syllabus_id;
    const data = {
      courseid: syllabus_id,
    };

    console.log("getData");

    this.callNetworkApiGet(uri, data, (data) => {
      console.log("data = " + JSON.stringify(data));
      cc.debug.setDisplayStats(false);
      callBack(JSON.parse(data.data));
    });
  },

  onHomeworkFinish(callBack) {
    console.log("onHomeworkFinish");
    return;
    if (this.role == "teacher") {
      return;
    }
    const uri = "app_source/v1/student/homework/finished";
    const data = {
      syllabus_id: this.syllabus_id,
      homework_id: this.homework_id,
      token: this.token,
      score: 100,
    };
    console.log("data = " + JSON.stringify(data));
    this.callNetworkApiPost(uri, data, callBack);
  },

  callNetworkApiGet(uri, data, callBack) {
    let queryStr = "";
    for (const key in data) {
      if (Object.hasOwnProperty.call(data, key)) {
        const value = data[key];
        if (queryStr == "") {
          queryStr += "?";
        }
        if (queryStr != "?") {
          queryStr += "&";
        }
        queryStr += `${key}=${value}`;
      }
    }
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 400) {
        const responseData = JSON.parse(xhr.responseText);
        callBack(responseData);
      }
    };
    const url = `${this.baseUrl}${uri}${queryStr}`;
    console.log("url = " + url);
    xhr.open("GET", url, true);
    xhr.send();
  },

  callNetworkApiPost(uri, data, callBack) {
    const xhr = new XMLHttpRequest();
    const url = `${this.baseUrl}${uri}`;
    xhr.open("POST", url, true);
    xhr.setRequestHeader("content-type", "application/json");
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4) {
        callBack(JSON.parse(xhr.responseText));
      }
    };
    xhr.send(JSON.stringify(data));
  },

  start() {
    initAir(this);
    this.reWriteAir();
    this.updateScale();

    window.courseware.getEngineInfo((dataStr) => {
      const engineInfo = JSON.parse(dataStr);
      console.log(engineInfo.isDev);
      let coursewareId;
      if (engineInfo.isDev == 1) {
        coursewareId = 21506;
        this.baseUrl = "http://staging-openapi.iteachabc.com/api/";
      } else {
        coursewareId = 38652;
        this.baseUrl = "http://openapi.iteachabc.com/api/";
      }

      this.node.zIndex = 9999;
      this.showWaitingLetters();

      cc.game.addPersistRootNode(this.node);

      this.initListener();

      window.g = null;
      this.getBundleInfoList(coursewareId);
    });
  },

  reWriteAir() {
    window.courseware.getData = (callback) => {
      let data = null;
      if (this.courseItem.data) {
        data = JSON.parse(this.courseItem.data);
      }
      this.log("===成功调用getData===" + this.courseItem.data);
      callback && callback(data);
    };
    window.courseware.nextPage = () => {
      this.goNextPage();
    };
    window.courseware.beforePage = () => {
      this.goPrePage();
    };
    window.courseware.sendAnswer = (answerObj) => {
      this.log("===成功调用sendAnswer===" + JSON.stringify(answerObj));
      this.callNetworkApiPost(
        `http://staging-teach.ireadabc.com`,
        `/api/oxford/courseware/v1/${this.courseItem.id}/saveanswer`,
        answerObj,
        (data) => {
          answerObj.callback && answerObj.callback(JSON.stringify(data.row));
        }
      );
    };
    window.courseware.getAnswer = (queryObj, callback) => {
      this.log("===成功调用getAnswer===" + JSON.stringify(queryObj));
      this.callNetworkApiGet(
        `http://staging-teach.ireadabc.com`,
        `/api/oxford/courseware/v1/${this.courseItem.id}/getanswer`,
        queryObj,
        (datastr) => {
          const data = JSON.parse(datastr);
          callback && callback(JSON.stringify(data.rows));
        }
      );
    };
  },

  asyncDelayLog(str) {
    console.log(str);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, 1);
    });
  },

  getBundleInfoList(coursewareId) {
    this.callNetworkApiGet(
      `courseware/v1/${coursewareId}/list`,
      null,
      (data) => {
        console.log("data = " + JSON.stringify(data));
        this.defaultBundleIdx = 0;
        this.bundleInfoList = data.rows.map((row) => {
          const bundleInfo = row.conf;
          bundleInfo.syllabus_id = row.id;
          bundleInfo.data = row.data;
          return bundleInfo;
        });
        this.jumpToBundleByIndex(this.defaultBundleIdx);
      }
    );
  },

  jumpToBundleByIndex(index) {
    this.currentBundleIndex = index;
    const currentBundleInfo = this.bundleInfoList[this.currentBundleIndex];

    const btnLeft = this.node.getChildByName("BtnLeft");
    const btnRight = this.node.getChildByName("BtnRight");
    btnLeft.active = true;
    btnRight.active = true;

    if (this.currentBundleIndex == 0) {
      btnLeft.active = false;
    }
    if (this.currentBundleIndex == this.bundleInfoList.length - 1) {
      btnRight.active = false;
    }

    this.token = currentBundleInfo.token;
    this.homework_id = currentBundleInfo.homework_id;
    this.syllabus_id = currentBundleInfo.syllabus_id;
    this.role = currentBundleInfo.role;

    // role
    // syllabus_id
    // homework_id
    // token

    this.courseItem = this.bundleInfoList[this.currentBundleIndex];

    this.loadBundleByConf(this.bundleInfoList[this.currentBundleIndex]);
  },

  initListener() {
    const exitBtn = this.node.getChildByName("ExitBtn");
    exitBtn.off("click");
    exitBtn.on("click", () => {
      cc.tween(exitBtn)
        .to(0.1, { scaleX: 0.9, scaleY: 1.1 })
        .to(0.1, { scaleX: 1.1, scaleY: 0.9 })
        .to(0.1, { scaleX: 1, scaleY: 1 })
        .call(() => {
          this.exit();
        })
        .start();
    });

    const btnLeft = this.node.getChildByName("BtnLeft");
    btnLeft.off("click");
    btnLeft.on("click", () => {
      if (btnLeft.cantClick) {
        return;
      }
      btnLeft.cantClick = true;
      cc.tween(btnLeft)
        .to(0.1, { scale: 1.1 })
        .to(0.1, { scale: 1.0 })
        .call(() => {
          btnLeft.cantClick = false;
          if (this.currentBundleIndex - 1 < 0) {
            return;
          }
          this.jumpToBundleByIndex(this.currentBundleIndex - 1);
        })
        .start();
    });

    const btnRight = this.node.getChildByName("BtnRight");
    btnRight.off("click");
    btnRight.on("click", () => {
      if (btnRight.cantClick) {
        return;
      }
      btnRight.cantClick = true;
      cc.tween(btnRight)
        .to(0.1, { scale: -1.1 })
        .to(0.1, { scale: -1.0 })
        .call(() => {
          btnRight.cantClick = false;
          if (this.currentBundleIndex + 1 >= this.bundleInfoList.length) {
            return;
          }
          console.log("btnRight clicked");
          this.jumpToBundleByIndex(this.currentBundleIndex + 1);
        })
        .start();
    });

    const btnClose = cc.find("middleLayer/ConsoleNode/BtnClose");
    const btnOpen = cc.find("middleLayer/ConsoleNode/BtnOpen");
    const consoleNode = cc.find("middleLayer/ConsoleNode/Console");
    const consoleBg = cc.find("middleLayer/ConsoleNode/bg");
    btnOpen.off("click");
    btnOpen.on("click", () => {
      btnClose.active = true;
      btnOpen.active = false;
      consoleNode.active = true;
      consoleBg.active = true;
    });

    btnClose.off("click");
    btnClose.on("click", () => {
      btnClose.active = false;
      btnOpen.active = true;
      consoleNode.active = false;
      consoleBg.active = false;
    });
  },

  log(str) {
    const logStr = `${new Date().toLocaleString()}: ${str}`;
    console.log(logStr);
    const content = cc.instantiate(cc.find("middleLayer/ConsoleNode/content"));
    content.active = true;
    const label = content.getChildByName("label");
    label.getComponent(cc.Label).string = logStr;
    const consoleContent = cc.find("middleLayer/ConsoleNode/Console/content");
    consoleContent.addChild(content);
    consoleContent.getComponent(cc.Layout).updateLayout();
  },

  callNativeFunction(param) {
    const paramStr = JSON.stringify(param);
    if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
      return jsb.reflection.callStaticMethod(
        "CocosMng",
        "cocosWithNativeProtocol:",
        paramStr
      );
    } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
      return jsb.reflection.callStaticMethod(
        "com/iplayabc/cocos/AppActivity",
        "cocosWithNativeProtocol",
        "(Ljava/lang/String;)Ljava/lang/String;",
        paramStr
      );
    } else {
      console.error("非源生环境");
    }
  },

  showWaitingLetters() {
    const waitingLayer = cc.find("middleLayer/waitingLayer");
    waitingLayer.active = true;
    const colorList = this.getRainbowColorList();
    const layout = cc.find("middleLayer/layout");
    layout.removeAllChildren();
    layout.active = true;
    const str = "Now Loading...";
    str.split("").forEach((word, idx) => {
      const node = new cc.Node();
      const label = node.addComponent(cc.Label);
      label.string = word;
      node.parent = layout;
      node.color = colorList[idx];
      cc.tween(node)
        .delay(idx / 4)
        .by(0.3, { y: 50 }, { easing: "sineOut" })
        .by(0.3, { y: -50 }, { easing: "sineIn" })
        .delay((str.length - idx) / 4)
        .union()
        .repeatForever()
        .start();
    });
    const totalWidth = layout.children.reduce((width, node, idx) => {
      return width + node.width;
    }, 0);
    layout.width = totalWidth;
  },

  hideWaitingLetters() {
    const layout = cc.find("middleLayer/layout");
    layout.active = false;
    const waitingLayer = cc.find("middleLayer/waitingLayer");
    waitingLayer.active = false;
  },

  showLog(str) {
    if (!this.logList) {
      this.logList = [];
    }
    this.logList.push(str);
    console.log(str);

    if (this.logList.length == 1) {
      this.showOneLog();
    }
  },

  showOneLog() {
    const str = this.logList[0];
    if (str === undefined) {
      return;
    }
    const node = new cc.Node();
    node.anchorX = 0.5;
    const label = node.addComponent(cc.RichText);
    label.string = `<outline color=black width=3>${str}</outline>`;
    label.maxWidth = this.node.width / 2;
    node.x = this.node.width / 4;
    node.y = -this.node.height / 2;
    node.parent = this.node;
    cc.tween(node).to(5, { y: this.node.height }).removeSelf().start();
    setTimeout(() => {
      this.logList.shift();
      this.showOneLog();
    }, 1000);
  },

  loadBundle(conf, callback) {
    this.showWaitingLetters();
    cc.assetManager.loadBundle(
      conf.bondleUrl,
      { version: conf.version },
      async (err, bundle) => {
        if (err) {
          return this.asyncDelayLog(err);
        }
        bundle.loadScene(conf.sceneName, (err, scene) => {
          if (err) {
            this.asyncDelayLog("err: ", err);
          }
          cc.audioEngine.stopAll();
          cc.director.runScene(scene, null, () => {
            console.log("sceneName = " + conf.sceneName);
            const canvas = cc.find("Canvas");
            const middleLayer = cc.find("middleLayer");

            window.courseware.freeAllOcMethod();

            this.hideWaitingLetters();
            this.updateScale();
            callback && callback();
          });
        });
      }
    );
  },

  loadBundleByConf(conf, callback) {
    if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
      this.loadBundle(conf.ios, callback);
    } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
      this.loadBundle(conf.android, callback);
    } else {
      this.loadBundle(conf.web_desktop, callback);
      console.error("非源生环境");
    }
  },

  reloadBundle() {
    this.loadBundleByConf(this.bundleInfoList[this.currentBundleIndex]);
  },

  updateScale() {
    console.log("updateScale");
    const canvas = cc.find("Canvas");
    const canvasComponent = canvas.getComponent(cc.Canvas);

    const canvasSize = cc.view.getCanvasSize();
    const designSize = cc.view.getDesignResolutionSize();

    if (canvasComponent.fitHeight && canvasComponent.fitWidth) {
      console.log("fit both");

      const scale = Math.max(
        designSize.width / canvasSize.width,
        designSize.height / canvasSize.height
      );

      const scaleHeight = this.node.height / canvasSize.height;
      this.node.width = canvasSize.width * scaleHeight;
      this.node.scale = scale / scaleHeight;

      const pos = this.node.parent.convertToNodeSpaceAR(
        canvas.convertToWorldSpaceAR(cc.v2(0, 0))
      );
      this.node.setPosition(pos);
      return;
    }

    if (canvasComponent.fitHeight && !canvasComponent.fitWidth) {
      console.log("fit height");

      const scale = designSize.height / canvasSize.height;
      const scaleHeight = this.node.height / canvasSize.height;
      this.node.width = canvasSize.width * scaleHeight;
      this.node.scale = scale / scaleHeight;
      this.node.x = (this.node.width * this.node.scale) / 2;
      this.node.y = (this.node.height * this.node.scale) / 2;
      return;
    }

    if (!canvasComponent.fitHeight && canvasComponent.fitWidth) {
      console.log("fit width");

      const scale = designSize.width / canvasSize.width;
      const scaleWidth = this.node.width / canvasSize.width;
      this.node.height = canvasSize.height * scaleWidth;
      this.node.scale = scale / scaleWidth;
      this.node.x = (this.node.width * this.node.scale) / 2;
      this.node.y = (this.node.height * this.node.scale) / 2;
      return;
    }

    if (!canvasComponent.fitHeight && !canvasComponent.fitWidth) {
      console.log("fit width");

      const scale = Math.min(
        designSize.width / canvasSize.width,
        designSize.height / canvasSize.height
      );

      const scaleHeight = this.node.height / canvasSize.height;
      this.node.width = canvasSize.width * scaleHeight;
      this.node.scale = scale / scaleHeight;

      const pos = this.node.parent.convertToNodeSpaceAR(
        canvas.convertToWorldSpaceAR(cc.v2(0, 0))
      );
      this.node.setPosition(pos);
      return;
    }
  },

  exit() {
    cc.game.removePersistRootNode(this.node);
    cc.director.loadScene("emptyScene", () => {
      this.callNativeFunction({ name: "exit", value: "" });
    });
  },

  getRainbowColorList() {
    return [
      cc.color(128, 0, 255),
      cc.color(255, 0, 255),
      cc.color(255, 0, 128),

      cc.color(0, 0, 0),

      cc.color(255, 0, 0),
      cc.color(255, 128, 0),
      cc.color(255, 255, 0),
      cc.color(128, 255, 0),
      cc.color(0, 255, 0),
      cc.color(0, 255, 128),
      cc.color(0, 255, 255),

      cc.color(0, 128, 255),
      cc.color(0, 0, 255),
      cc.color(128, 0, 255),
    ];
  },
});
