const { ccclass, property } = cc._decorator;
import { initAir } from "./air";

@ccclass
export default class middleLayer extends cc.Component {
  onLoad() {
    console.log("onLoad middleLayer");
    initAir(this);
    this.reWriteAir();
  }

  reWriteAir() {
    console.log("reWriteAir..");
    (<any>window).courseware.getData = (callback) => {
    //   this.getData(callback);
      callback(this.COURSE_DATA);
    };
    // if (!(<any>window).air) {
    //   (<any>window).air = {};
    // }
    // (<any>window).air.hideAirClassLoading = () => {
    //   if ((<any>window).air.onCourseInScreen) {
    //     (<any>window).air.onCourseInScreen(() => {
    //       console.log("***成功调用onCourseInScreen***");
    //       (<any>window).air.onCourseInScreen = null;
    //       this.hidePreloadWaiting();
    //     });
    //   } else {
    //     this.hidePreloadWaiting();
    //   }
    // }
  }

  COURSE_DATA = null;
  setCourseData(data) {
    this.COURSE_DATA = data;
  }

  log(value) {
    console.log(value);
  }

  syllabus_id;
  getData(callBack) {
    const uri = "api/syllabus/v1/getdata";
    const data = {
      syllabusid: this.syllabus_id,
    };
    console.log("data = " + JSON.stringify(data));
    this.callNetworkApiGet(uri, data, (res) => {
        callBack(JSON.parse(res.data));
    });
  }

  role;
  baseUrl;
  homework_id;
  token;
  onHomeworkFinish(callBack) {
    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: 0,
    };
    console.log("data = " + JSON.stringify(data));
    this.callNetworkApiPost(uri, data, callBack);

    if (this.homework_id == -1) {
      return;
    }

    const btnBg = cc.find("middleLayer/btnBg");
    btnBg.active = true;
  }

  callNetworkApiGet(uri, data, callBack) {
    let queryStr = "?";
    for (const key in data) {
      if (Object.hasOwnProperty.call(data, key)) {
        const value = data[key];
        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);
        console.log(responseData);
        callBack(responseData);
      }
    };
    const url = `${this.BASE_URL}${uri}${queryStr}`;
    console.log("url = " + url);
    xhr.open("GET", url, true);
    xhr.send();
  }

  callNetworkApiPost(uri, data, callBack) {
    const xhr = new XMLHttpRequest();
    const url = `${this.BASE_URL}${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));
  }

  ENGINE_INFO;
  ORG_ID;
  DOMAIN;
  BASE_URL;
  ENV;
  getEngineInfo() {
    return new Promise<string>((resolve, reject) => {
      if (this.ENGINE_INFO) {
        resolve(JSON.stringify(this.ENGINE_INFO));
        return;
      }
      const loopEngineInfo = () => {
        this.scheduleOnce(() => {
          if (!(<any>window).air.engineInfo) {
            loopEngineInfo();
            return;
          }
          if (this.ENGINE_INFO) {
            resolve(JSON.stringify(this.ENGINE_INFO));
            return;
          }
          const engineInfo = JSON.parse((<any>window).air.engineInfo);
          if (engineInfo.isDev == 1) {
            engineInfo.domain = "https://staging-teach.cdn.ireadabc.com/";
            engineInfo.apiBase = "https://staging-openapi.iteachabc.com/";
            engineInfo.orgId = 513;
          } else {
            engineInfo.domain = "https://teach.cdn.ireadabc.com/";
            engineInfo.apiBase = "https://openapi.iteachabc.com/";
            engineInfo.orgId = 512;
          }
          this.ORG_ID = engineInfo[`orgId`];
          this.DOMAIN = engineInfo[`domain`];
          this.ENGINE_INFO = engineInfo;
          resolve(JSON.stringify(engineInfo));
        }, 0.05);
      };
      loopEngineInfo();
    });
  }

  async start() {
    console.log("on midlleLayer start");
    // 节点放到最上层
    this.node.zIndex = 9999;
    // 显示加载动画
    // this.showWaitingLetters();
    // 生命当前节点为常驻节点
    cc.game.addPersistRootNode(this.node);

    // 添加事件监听
    // this.initListener();
    // TODO 获取当前环境信息
    // this.baseUrl = "http://openapi.iteachabc.com"
    // this.loadOnlineBundle()

    let domain = "https://staging-teach.cdn.ireadabc.com/";
    let baseUrl = "https://staging-openapi.iteachabc.com/";
    let env = "0"; // 0: 测试环境 1: 生产环境
    let token = "unlogin";

    try {
      const jsonStr = this.callNativeFunction({
        name: "getEngineInfo",
        value: "",
      });
      const obj = JSON.parse(jsonStr);
      domain = obj.domain;
      baseUrl = obj.baseUrl;
      env = obj.env;
      token = obj.token;
    } catch (error) {
      console.log("error", error);
      console.error("getEngineInfo 获取信息失败");
    }

    console.log("domain", domain);
    console.log("baseUrl", baseUrl);
    console.log("env", env);
    console.log("token", token);

    this.DOMAIN = domain;
    this.BASE_URL = baseUrl;
    this.ENV = env;
    this.token = token;

    // this.showDebugInfo();

    if (!this.DOMAIN || !this.BASE_URL || !this.ENV || !this.token) {
      console.error("getEngineInfo 获取信息失败");
      return;
    }

    // 运行主场景
    this.runMainScene();

    
    // this.homework_id = homework_id;
    // this.syllabus_id = syllabus_id;
    // this.role = role;

    // cc.assetManager.loadBundle(bondleUrl, { version: version }, (err, bundle) => {
    //     if (err) {
    //         return console.error(err);
    //     }
    //     bundle.loadScene(sceneName, (err, scene) => {
    //         this.hideWaitingLetters();
    //         cc.director.runScene(scene);
    //     });
    // });
  }

  showDebugInfo() {
    const domain = cc.find("middleLayer/info/domain").getComponent(cc.Label);
    const baseUrl = cc.find("middleLayer/info/baseUrl").getComponent(cc.Label);
    const env = cc.find("middleLayer/info/env").getComponent(cc.Label);
    // const token = cc.find('middleLayer/info/token').getComponent(cc.Label);
    domain.string = `domain: ${this.DOMAIN}`;
    baseUrl.string = `baseUrl: ${this.BASE_URL}`;
    env.string = `env: ${this.ENV == "0" ? "test" : "prod"}`;
    // token.string = this.token;
  }

  /**
   * 运行子场景
   */
  runMainScene() {
    console.log("加载游戏中心场景...");
    cc.director.loadScene("gamecenter");
  }

  /**
   * 关闭游戏中心
   */
  closeGameCenter() {
    console.log("关闭游戏中心，加载空页面...");
    cc.director.loadScene("empty", () => {
      cc.game.removePersistRootNode(this.node);
      // 发送消息到Flutter
      if((window as any).FlutterChannel) {
        (window as any).FlutterChannel.postMessage('close_webview');
      } else {
        this.callNativeFunction({ name: "exit", value: "" });
      }
    });
  }

  initListener() {
    const exitBtn = this.node.getChildByName("ExitBtn");
    exitBtn.on("click", () => {
      const sprite = exitBtn.getChildByName("sprite");
      cc.tween(sprite)
        .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(() => {
          cc.game.removePersistRootNode(this.node);
          cc.director.loadScene("emptyScene", () => {
            this.callNativeFunction({ name: "exit", value: "" });
          });
        })
        .start();
    });

    const btnLast = cc.find("middleLayer/btnBg/btnLast");
    btnLast["canClick"] = true;
    btnLast.on("click", () => {
      if (!btnLast["canClick"]) {
        return;
      }
      btnLast["canClick"] = false;
      cc.tween(btnLast)
        .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(() => {
          btnLast["canClick"] = true;
          const paramStr = JSON.stringify({});
          if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
            return jsb.reflection.callStaticMethod(
              "CocosMng",
              "previousPage:",
              paramStr
            );
          } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
            return jsb.reflection.callStaticMethod(
              "com/iplayabc/cocos/AppActivity",
              "previousPage",
              "(Ljava/lang/String;)Ljava/lang/String;",
              paramStr
            );
          } else {
            console.error("非源生环境");
          }
        })
        .start();
    });

    const btnNext = cc.find("middleLayer/btnBg/btnNext");
    btnNext["canClick"] = true;
    btnNext.on("click", () => {
      if (!btnNext["canClick"]) {
        return;
      }
      btnNext["canClick"] = false;
      cc.tween(btnNext)
        .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(() => {
          btnNext["canClick"] = true;
          const paramStr = JSON.stringify({});
          if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
            return jsb.reflection.callStaticMethod(
              "CocosMng",
              "nextPage:",
              paramStr
            );
          } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
            return jsb.reflection.callStaticMethod(
              "com/iplayabc/cocos/AppActivity",
              "nextPage",
              "(Ljava/lang/String;)Ljava/lang/String;",
              paramStr
            );
          } else {
            console.error("非源生环境");
          }
        })
        .start();
    });
  }

  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 {
      throw "非源生环境";
    }
  }

  showWaitingLetters() {
    const colorList = this.getRainbowColorList();
    const layout = cc.find("middleLayer/layout");
    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;
  }

  logList = null;
  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);
  }

  getRainbowColorList() {
    return [
      cc.color(255, 0, 0),
      cc.color(255, 128, 0),
      cc.color(255, 255, 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),

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

  loadPageBundle(courseItem, callback = null) {
    console.log(" in loadPageBundle");
    let sceneName,
      version,
      bondleUrl = "";
    this.syllabus_id = courseItem.course_id;
    const templateBaseUrl = `${this.DOMAIN}h5template/${courseItem.template_name}/v${courseItem.last_version}`;
    this.getConfigInfo(templateBaseUrl, (conf) => {
      if (cc.sys.isNative && cc.sys.os == cc.sys.OS_IOS) {
        sceneName = conf.ios.sceneName;
        version = conf.ios.version;
        bondleUrl = `${templateBaseUrl}/ios/${conf.ios.sceneName}`;
      } else if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID) {
        sceneName = conf.android.sceneName;
        version = conf.android.version;
        bondleUrl = `${templateBaseUrl}/android/${conf.ios.sceneName}`;
      } else {
        sceneName = conf.android.sceneName;
        version = "";
        bondleUrl = `${templateBaseUrl}/web_desktop`;
      }
      this.loadBundle(sceneName, version, bondleUrl, callback);
    });
  }

  async loadBundle(sceneName, version, bondleUrl, callback = null) {
    cc.audioEngine.stopAll();
    cc.assetManager.loadBundle(
      bondleUrl,
      { version: version },
      async (err, bundle) => {
        bundle.loadScene(
          sceneName,
          null,
          (finish, total, item) => {
            this.setLoadingProgressBar(Math.floor(finish / total * 100));
          },
          (err, scene) => {
            cc.director.runScene(scene, null, () => {
              console.log("sceneName1 = " + sceneName);
              // const canvas = cc.find("Canvas");
              const middleLayer = cc.find("middleLayer");
              middleLayer.getComponent(cc.Widget).updateAlignment();
              // middleLayer.scale = canvas.width / middleLayer.width;
              this.showCloseGameBtn();
              callback && callback();
            });
          }
        );
      }
    );
  }

  getConfigInfo(url, callback) {
    const xhr = new XMLHttpRequest();
    let flag = false;
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4 && xhr.status >= 200 && xhr.status < 400) {
        flag = true;
        callback(JSON.parse(xhr.responseText));
      }
    };
    xhr.open("GET", `${url}/config.json`, true);
    xhr.send();

    // 五秒超时重试一次
    this.scheduleOnce(() => {
      if (flag) {
        return;
      }
      xhr.abort();
      this.getConfigInfo(url, callback);
    }, 5);
  }

  showCloseGameBtn() {
    console.log("showCloseGameBtn");
    const closeGameBtn = cc.find("middleLayer/back_btn");
    closeGameBtn.active = true;
  }

  hideCloseGameBtn() {
    const closeGameBtn = cc.find("middleLayer/back_btn");
    closeGameBtn.active = false;
  }

  // 设置加载进度条
  setLoadingProgressBar(progress: number) {
    console.log('middleLayer setLoadingProgressBar:', progress);
    // 这个方法会被gamecenter组件重写，用于更新进度条
  }

  onExitGame() {
    this.hideCloseGameBtn();
    cc.audioEngine.stopAll();
    cc.director.loadScene("gamecenter");
  }
}
