
const getQueryString = function (name) {
  const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  const r = window.location.search.substr(1).match(reg);
  if (r != null) {
    return unescape(r[2]);
  }
  return null;
};

const commonPostMessage = function (messageObj) {
  const obj = {...messageObj, urlParams: window.location.search, origin: "template"}
  window.parent.postMessage(obj, '*');
};

const postMessageCallbackQueue = {};
const commonPostMessageWithCallback = function (messageObj, callback) {
  if(postMessageCallbackQueue[messageObj.action]){
    console.error(`action为${messageObj.action}的事件正在执行，请更换action名称或等待事件执行完成后再发起`);
    return;
  }
  postMessageCallbackQueue[messageObj.action] = true;
  const onMessage = (e) => {
    let msgData = e.data;
    if(msgData.origin==="template"){
      return;
    } 
    if(msgData && msgData.action === messageObj.action){
      postMessageCallbackQueue[messageObj.action] = false;
      window.removeEventListener("message", onMessage);
      callback && callback(msgData.data);
    }
  };
  window.addEventListener("message", onMessage);
  commonPostMessage(messageObj);
};

const conlog = function(...args) {
  const course_id = getQueryString("course_id");
  console.log(`|=${course_id}=| `, ...args);
}
const conwarn = function(...args) {
  const course_id = getQueryString("course_id");
  console.warn(`|=${course_id}=| `, ...args);
}

//约定两种角色，stu:学生   tea:老师
const realAir = {
  uploadUrl: null,
  uploadData: null,
  getDataCallback: null,
  setDataCallback: null,
  getAspectCallback: null,
  getUploadCallback: null,
  pageLoaded: false,
  isCourseInScreen: false,

  onCourseInScreen: null,
  hideAirClassLoading: function(templateName,loadData){
    // 隐藏页面加载时候的loading
    if (deleteHistory && typeof (deleteHistory) == 'function') {
      deleteHistory();
    }
    commonPostMessage({ action: "course-ready", data: {template:templateName,loadData:loadData}});
    window.air.pageLoaded = true; 

    var cc = window.cc;
    if (cc && cc.director && cc.director._scene) {
      try {
        const canvas = cc.find("Canvas");
        canvas.on("mousemove", function () {});
        cc.director._scene.on("mousemove", function () {
          commonPostMessage({ action: "mousemove" });
        });
        cc.director._scene.on("touchmove", function () {
          commonPostMessage({ action: "mousemove" });
        });

        if (cc.systemEvent && cc.SystemEvent) {
          cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event) => {
            switch (event.keyCode) {
              case cc.KEY.left:
                commonPostMessage({ action: "ArrowLeft" });
                break;
              case cc.KEY.right:
                commonPostMessage({ action: "ArrowRight" });
                break;
            }
          });
        }
      } catch (e) {
        conlog("====cc.director._scene绑定事件===="+e);
      }
    }
  },

  airClassInfo: {
    user:{
      uuid: 'example',
      classRole: getQueryString("role"),
      nick_name: 'example'
    },
    supportRecord: false, // 是否支持录音
  }
};

const uploadCallbackQueue = [];

try{
  window.air = new Proxy(realAir, {
    set: function (target, key, value, receiver) {
      if (key=="getUploadCallback") {
				uploadCallbackQueue.push(value);
			}
      return Reflect.set(target, key, value, receiver); 
    },
    get: function (target, key, receiver) {
			return Reflect.get(target, key, receiver);
    },
    deleteProperty: function(target, key){
			return Reflect.deleteProperty(target, key);
		}
  });
}catch(e){
  conwarn("浏览器不支持ES6新特性Proxy/Reflect，请使用谷歌浏览器！");
}

function deleteHistory() {
  const disableBack = () => {
    window.history.pushState(null, "", document.URL);
    window.addEventListener("popstate", () => {
      window.history.pushState(null, "", document.URL);
    });
  }
  disableBack();
  window.addEventListener("load", disableBack);
}
deleteHistory();

if (window.self !== window.top) {

  window.addEventListener("load", () => {
    const zoom = getQueryString("zoom");
    if(zoom){
      document.body.style.zoom = parseFloat(zoom);
    }
  });
  
  //如果十秒还没初始化完则刷新页面
  //这么写的话form页面怎么解决，这块需要考虑好
  // setTimeout(function(){
  //   //这个地方后续上送一些必要的日志  todo

  //   if(!window.air.pageLoaded){
  //     window.location.reload();
  //   } 
  // }, 15000);

  window.addEventListener("message", function (e) {
    let msgData = e.data;
    if(msgData.type === "webpackWarnings" || msgData.type === "webpackOk") {
      return;
    }
    if(msgData.action==="airEvents"){
      return;
    } 
    if(msgData.origin==="template"){
      return;
    } 
    if (msgData.action === "getUpload") {
      window.air.uploadUrl = msgData.uploadUrl;
      window.air.uploadData = msgData.uploadData;
      for (let i = 0; i < uploadCallbackQueue.length; i++) {
        uploadCallbackQueue[i](msgData.uploadUrl, msgData.uploadData);
      }
      return;
    }
    if (msgData.action === "pauseCocos") {
      let cc = window.cc;
      if (cc && cc.game) {
        cc.game.pause();
        conlog('pause了');
      }
      return;
    }
    if (msgData.action === "resumeCocos") {
      let cc = window.cc;
      if (cc && cc.game) {
        cc.game.resume();
        conlog('resume了');
      }
      return;
    }
    if (msgData.action === "restartCocos") {
      let cc = window.cc;
      if (cc && cc.game) {
        // cc.audioEngine.stopAll();
        // cc.game.restart();
        conlog('restart了');
      }
      return;
    }
    if (msgData.action === "getAirClassInfo") {
      window.air.airClassInfo = JSON.parse(msgData.data); 
      return;
    }
    if (msgData.action === "courseOutScreen") {
      window.location.reload();
      return;
    }
    if (msgData.action === "courseInScreen") {
      if(!window.air.pageLoaded){
        conwarn(`页面还没有加载完就执行了courseInScreen事件，请排查产生原因`);
        return;
      }
      if(window.air.isCourseInScreen){
        conwarn(`courseInScreen事件执行了多次，请排查产生原因`);
        return;
      }
      conlog(`====courseInScreen事件已触发====`);
      window.air.isCourseInScreen = true;
      if(window.air.onCourseInScreen){
        window.air.onCourseInScreen(()=>{
          window.courseware.next();
        });
        return;
      }else{
        conwarn(`onCourseInScreen事件没有被实现，请确认事件的顺序在页面加载完成之前`);
      }
      return;
    }
   
    if (msgData.action === "getAspect") {
      let data = msgData.data;
      if (data) {
        data = JSON.parse(data); 
      } 
      window.air.getAspectCallback && window.air.getAspectCallback(data);
      return;
    }
    if (msgData.action === "setData") {
      window.air.setDataCallback && window.air.setDataCallback();
      return;
    }
    if (msgData.action === "getData") {
      try {
        const res = JSON.parse(msgData.data);
        if (res.msg !== "success") {
          conlog('数据加载失败！');
          return;
        }
        if (res.data && res.data != 'null') {
          window.air.callData = JSON.parse(res.data);
        }
        window.air.aspect = res.aspect;
        window.air.callDataFlag = true;
        return;
      } catch (e) {
        conlog('数据加载失败！');
      }
    }
  });
  commonPostMessage({ action: "getUpload" });

  commonPostMessage({ action: "getAirClassInfo" });

  document.onmousemove = function(e){
    commonPostMessage({ action: "mousemove", x: e.clientX, y: e.clientY});
  };
  document.ontouchmove = function(){
    commonPostMessage({ action: "mousemove" });
  };

  document.onkeydown = (event) => {
    switch(event.key) {
      case "ArrowLeft":
        commonPostMessage({ action: "ArrowLeft" });
        break;
      case "ArrowRight": 
        commonPostMessage({ action: "ArrowRight" });
        break;
    }
  }

  document.oncontextmenu = function(){
    return false;
  }

  window.onerror = function(msg,url,line,col,error){  
    //上报错误日志采集
    commonPostMessage({ action: "errorlog", data: error.stack }); 
  }; 
}


window.courseware = (function () {
  let obj = {
    airEvents: {},
    eventQueue: [],
    eventLock: false,
    next: () => {
      let exe = obj.eventQueue.splice(0,1); 
      if(exe.length>0){
        obj.eventLock = true;
        let evtName = exe[0].evtName;
        let data = exe[0].data; 
        if(obj.airEvents[evtName]){
          conlog(`evtName==${evtName}的方法被执行`);
          obj.airEvents[evtName](data, obj.next);
        } else {
          conwarn(`airclass教室交互事件 ${evtName} 没有被捕获，请确认监听事件的先后顺序`);
          obj.next();
        }
      }else{
        obj.eventLock = false;
      } 
    }
  };
  if (window.self !== window.top) {
    window.addEventListener("message", function (e) {
      let msgData = e.data;
      if(msgData.origin==="template"){
        return;
      } 
      if(msgData.action!=="airEvents"){
        return;
      } 
      let evtName = msgData.evt; 
      let res = msgData.data;
      conlog(`收到了airEvents事件，事件名称：${evtName}, 数据：${res}`);
      if (res&&evtName!='userchange') {
        //userchange事件传过来的值不需要转换
        res = JSON.parse(res); 
      }
      if(!window.air.pageLoaded){
        //如果页面还没有加载完成
        obj.eventQueue.push({"evtName": evtName, data: res});
        conlog(`页面还未加载完，进入事件队列，队列已有：${obj.eventQueue.length}`);
      }else{ 
        if (obj.eventQueue.length === 0 && !obj.eventLock) {
          //如果没有消息积压并且事件锁未锁定
          obj.eventLock = true; 
          if(obj.airEvents[evtName]){
            conlog(`evtName==${evtName}的方法被执行`);
            obj.airEvents[evtName](res, obj.next); 
          } else {
            conwarn(`airclass教室交互事件 ${evtName} 没有被捕获，请确认监听事件的先后顺序`);
            obj.next();
          }
        } else {
          obj.eventQueue.push({"evtName": evtName, data: res});
          conlog(`队列有前面的事件，所以压入队列，evtName==${evtName}`);
          conlog(`前面未执行的事件还有 ${obj.eventQueue.length} 个`);
          const eventNames = obj.eventQueue.map(item => item.evtName);
          conlog(`事件名分别是 ${eventNames.join(",")} `);
        }
      } 
    }); 
    obj.getData = function (callback, key = '') {
      commonPostMessage({ action: "getData", data: window.location.search });
      window.air.callDataFlag = false;
      const liuintval = setInterval(()=>{
        if(window.air.callDataFlag){
          clearInterval(liuintval);
          setTimeout(() => {
            conlog("执行回调，回调数据为：");
            conlog("data", JSON.stringify(window.air.callData));
            conlog("aspect", JSON.stringify(window.air.aspect));
            callback(window.air.callData, window.air.aspect);
          }, 100);
        }
      }, 100);
    };
    obj.setData = function (data, callback, key = '') {
      let str = JSON.stringify(data);
      commonPostMessage({ action: "setData", data: str, urlParams: window.location.search });
      window.air.setDataCallback = callback;
    };
    obj.uploadUrl = function () {
      return window.air.uploadUrl;
    };
    obj.uploadData = function () {
      return window.air.uploadData;
    };
    obj.storeAspect = function(data, key = ''){
      let str = JSON.stringify(data);
      commonPostMessage({ action: "storeAspect", data: str }); 
    };
    obj.storePageAspect = function(data, key = ''){
      let str = JSON.stringify(data);
      commonPostMessage({ action: "storePageAspect", data: str }); 
    };
    obj.nextPage = function(){
      const index = getQueryString("index");
      commonPostMessage({ action: "callJumpPage", data: parseInt(index)+1 }); 
    };
    obj.beforePage = function(){
      const index = getQueryString("index");
      commonPostMessage({ action: "callJumpPage", data: parseInt(index)-1 }); 
    };
    obj.jumpPage = function(page){
      commonPostMessage({ action: "callJumpPage", data: page }); 
    };
    obj.beganRecording = function(){
      commonPostMessage({ action: "beganRecording" }); 
    };
    obj.endRecording = function(callback){
      commonPostMessageWithCallback({ action: "endRecording" }, callback);
    };
    obj.speakPoints = function(audioUrl, evalText, callback){
      const obj = {audioUrl, evalText};
      commonPostMessageWithCallback({ action: "speakPoints", data: JSON.stringify(obj) }, callback);
    };
    obj.startRecord = function(testText){
      console.log("======startRecord=====");
      commonPostMessage({ action: "startRecord", data: testText  });
    };
    obj.stopRecord = function(_isgradepapers, _callback){
      console.log("======stopRecord=====");
      let callback = _callback;
      let isgradepapers;
      if(_isgradepapers && typeof _isgradepapers === "function") {
        callback = _isgradepapers;
        isgradepapers = 1;
      } else {
        isgradepapers = _isgradepapers;
      }
      if(!callback){
        // 不传回调函数就表示取消评测
        commonPostMessage({ action: "stopRecord", iscancle: 1 });
      }else{
        commonPostMessageWithCallback({ action: "stopRecord", iscancle: 0, isgradepapers }, callback);
      }
    };

    obj.greadPapersForText = function(params, callback){
      let str = "";
      if( typeof(params) === "object"){
        str = JSON.stringify(params);
      }else{
        str = params;
      }
      console.log("======greadPapersForText=====", params);
      commonPostMessageWithCallback({ action: "greadPapersForText", data: str }, callback);
    }
    obj.startTest = function(testText){
      commonPostMessage({ action: "startTest", data: testText });
    };
    obj.stopTest = function(callback){
      if(!callback){
        // 不传回调函数就表示取消评测
        commonPostMessage({ action: "stopTest", iscancle: 1 });
      }else{
        commonPostMessageWithCallback({ action: "stopTest", iscancle: 0 }, callback);
      }
    };
    obj.sendAnswer = function(id, answer, isRight, startTime){
      commonPostMessage({ action: "sendAnswer", data: JSON.stringify({ id, answer, isRight, startTime }) });
    };
    obj.gameEnd = function(){
      commonPostMessage({ action: "gameEnd" });
    };
    obj.getAspect = function(callback, key = ''){
      commonPostMessage({ action: "getAspect" });
      window.air.getAspectCallback = callback;
    };
    obj.getTemplates = function(callback){
      commonPostMessageWithCallback({ action: "getTemplates" }, callback);
    };
    obj.getTemplateUrl = function(templateName, callback){
      commonPostMessageWithCallback({ action: "getTemplateUrl", data: templateName}, callback);
    };
    obj.sendEvent = function(evtName,data,key = ''){
      conlog("sendEvent=========="+evtName);
      conlog(data);
      if(evtName==="reconnect"){
        conwarn("reconnect是内置的断线重连事件名称，请勿使用此名称作为事件名");
        return;
      }
      if(evtName==="userchange"){
        conwarn("userchange是内置的用户变更事件名称，请勿使用此名称作为事件名");
        return;
      }
      if(evtName==="course-in-screen"){
        conwarn("course-in-screen是内置的页面状态变更事件名称，请勿使用此名称作为事件名");
        return;
      }
      let str = null;
      if(data){
        str = JSON.stringify(data);
      } 
      commonPostMessage({ action: "airEvents",evt: evtName, data: str }); 
    };
    obj.onEvent = function(evtName,callback){  
      obj.airEvents[evtName] = callback; 
    };
    obj.removeEvent = function(evtName){
      if(obj.airEvents[evtName]){ 
        delete obj.airEvents[evtName];
      }  
    };
    obj.sendErrorLog = function (error) { 
      commonPostMessage({ action: "errorlog", data: error.stack }); 
    }; 
  } else {
    // 自动触发一个页面进入的事件
    const intv = setInterval(()=>{
      if(window.air.onCourseInScreen){
        clearInterval(intv);
        setTimeout(() => {
          window.air.onCourseInScreen(()=>{
            conlog("==onCourseInScreen==事件执行成功");
          });
        }, 100);
      }
    }, 100);

    obj.getData = function (callback, key = '') {
      let data = localStorage.getItem("courseware_data_" + key);
      if (data) {
        data = JSON.parse(data);
      }
      let aspect = localStorage.getItem("courseware_aspect_" + key);
      if (aspect) {
        aspect = JSON.parse(aspect);
      }
      callback && callback(data, aspect);
    };
    obj.setData = function (data, callback, key = '') {
      conlog("******local********");
      localStorage.setItem("courseware_data_" + key, JSON.stringify(data));
      callback && callback();
    };
    obj.uploadUrl = function () {
      var protocolStr = document.location.protocol;
      return `${protocolStr}//staging-teach.ireadabc.com/fileUpload`;
    };
    obj.uploadData = function () {
      return {};
    };
    obj.storeAspect = function(data, key = ''){
      localStorage.setItem("courseware_aspect_" + key, JSON.stringify(data));
    };
    obj.storePageAspect = function(data, key = ''){
      localStorage.setItem("courseware_page_aspect_" + key, JSON.stringify(data));
    };
    obj.getAspect = function(callback, key = ''){
      let data = localStorage.getItem("courseware_aspect_" + key);
      if (data) {
        data = JSON.parse(data);
      }
      callback && callback(data);
    };
    obj.nextPage = function(){
      conlog("******nextPage********");
    };
    obj.beforePage = function(){
      conlog("******beforePage********");
    };
    obj.jumpPage = function(page){
      conlog("******jumpPage********", page);
    };
    obj.beganRecording = function(){
      conlog("******beganRecording********");
    };
    obj.endRecording = function(callback){
      conlog("******endRecording********");
      callback&&callback("");
    };
    obj.speakPoints = function(audioUrl, evalText, callback){
      conlog("******speakPoints********");
      callback&&callback("");
    };
    obj.startRecord = function(){
      conlog("******startRecord********");
    };
    obj.stopRecord = function(callback){
      conlog("******stopRecord********");
      callback&&callback("");
    };
    obj.greadPapersForText = function(params, callback){
      conlog("******greadPapersForText********");
      callback&&callback("");
    }
    obj.startTest = function(testText){
      conlog("******startTest********");
    };
    obj.stopTest = function(callback){
      conlog("******stopTest********");
      callback&&callback("");
    };
    obj.sendAnswer = function(answer, isRight, startTime){
      conlog("******sendAnswer********");
    };
    obj.gameEnd = function(){
      conlog("******gameEnd********");
    };
    obj.getTemplates = function(callback){
      callback&&callback("");
    };
    obj.getTemplateUrl = function(templateName, callback){
      const obj = {
        play_url: "",
        form_url: "",
      };
      callback&&callback(JSON.stringify(obj));
    };
    obj.sendEvent = function(evtName, data, key = ''){ 
      if(evtName==="reconnect"){
        conwarn("reconnect是内置的断线重连事件名称，请勿使用此名称作为事件名");
        return;
      }
      if(evtName==="userchange"){
        conwarn("userchange是内置的用户变更事件名称，请勿使用此名称作为事件名");
        return;
      }
      if(evtName==="course-in-screen"){
        conwarn("course-in-screen是内置的页面状态变更事件名称，请勿使用此名称作为事件名");
        return;
      }
      localStorage.setItem("courseware_aspect_"+key, data?JSON.stringify(data): null);
      if(obj.airEvents[evtName]){ 
        obj.airEvents[evtName](data);
      } 
    };
    obj.onEvent = function(evtName,callback){
      obj.airEvents[evtName] = callback;
    };
    obj.removeEvent = function(evtName){
      if(obj.airEvents[evtName]){ 
        delete obj.airEvents[evtName];
      }  
    };
    obj.sendErrorLog = function (error) { 
      
    };
  }  
  return obj;
})();

