const { ccclass, property } = cc._decorator;
import { initAir } from "./air_testzg001";
import { asyncDelay, playAudio } from "./util_testzg001";


// 全局类型声明
declare const global: any;

@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;
  async onHomeworkFinish(callBack) {



    console.log("~~~ show end effect");
    this.showWellDone();


    // 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;
  }

  async showWellDone()  {
    
    const img = cc.find("middleLayer/res/img/well_done");
    const wellDone = cc.instantiate(img);
    wellDone.parent = cc.find("Canvas");
    wellDone.zIndex = 9999;
    wellDone.active = true;

    const canvas = cc.find("Canvas");
    const scaleRate = canvas.width / 3802;
    wellDone.scale = scaleRate * 0.9;
    wellDone.opacity = 0;
    
    playAudio(cc.find("middleLayer/res/audio/well_done").getComponent(cc.AudioSource).clip);
    
    await asyncDelay(0.1);

    cc.tween(wellDone)
      .to(0.3, { scale: scaleRate * 1.25},{ easing: 'cubicOut' })
      .to(0.2, { scale: scaleRate * 0.95 },{ easing: 'sineInOut' })
      .to(0.2, { scale: scaleRate },{ easing: 'sineInOut' })
      .start();

    cc.tween(wellDone)
      .to(0.5, { opacity: 255 },{ easing: 'sineInOut' })
      .start();


    await asyncDelay(2);

    cc.tween(wellDone)
      .to(0.7, { opacity: 0, scale: scaleRate * 0.8 },{ easing: 'cubicIn' })
      .start();
  }

  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);

    global.middleLayer = cc.find('middleLayer').getComponent('middleLayer');

    // 添加事件监听
    // 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();

    // 隐藏资源占用信息
    cc.debug.setDisplayStats(false);

    // 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.android.sceneName}`;
      } else {
        sceneName = conf.android.sceneName;
        version = "";
        bondleUrl = `${templateBaseUrl}/web_desktop`;
      }
      this.loadBundle(sceneName, version, bondleUrl, callback);
    });
  }

  curBundle;
  async loadBundle(sceneName, version, bondleUrl, callback = null) {

		this.assetList = [];
		this.textureList = [];
		this.atlasList = [];
		this.nodeList = [];
		console.log('汪汪汪: getDragonDisplayAssetList');
		// this.getDragonDisplayAssetList(cc.find('Canvas'));

    cc.audioEngine.stopAll();
    cc.assetManager.loadBundle(
      bondleUrl,
      { version: version },
      async (err, bundle) => {
        if (err || !bundle) {
          console.error('[Bundle加载失败]', { bondleUrl, version, err });
          this.showLog(`Bundle加载失败: ${bondleUrl}`);
          callback && callback(err);
          return;
        }

        this.curBundle = bundle;

        bundle.loadScene(
          sceneName,
          null,
          (finish, total, item) => {
            const safeTotal = total || 1;
            const progress = Math.floor((finish / safeTotal) * 100);
            if (item && (item as any).url) {
              console.log('[场景加载进度]', { finish, total: safeTotal, url: (item as any).url });
            }
            this.setLoadingProgressBar(progress);
          },
          (err, scene) => {
            if (err || !scene) {
              console.error('[场景加载失败]', { sceneName, bondleUrl, err });
              this.showLog(`场景加载失败: ${sceneName}`);
              callback && callback(err);
              return;
            }
            try {
              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();

                const destroyer = cc.instantiate(cc.find('middleLayer/Destroyer'));
                destroyer.parent = cc.find('Canvas');
                destroyer.active = true;


                callback && callback();
              });
            } catch (e) {
              console.error('[运行场景异常]', e);
              this.showLog('运行场景异常');
              callback && callback(e);
            }
          }
        );
      }
    );
  }

  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组件重写，用于更新进度条
  }






  // ---------------兼容剑津模版 临时添加 ---------------
  setSRRecord(key, value) {
  }
  addSRAudioDuration(duration) {
  }
  setSRVideoDuration(duration) {
  }
  showSRResultByRecord(isShowScore = false) {
  }
  showSRResultByQuestion(isShowScore = false) {
  }
  showSRResult(score) {
  }
  setTotalQuestions(total) {
  }
  setQuestionResult(index, score) {
  }
  // -----------------------------------------------

  // --------------- 兼容虎跃模板 ---------------
  exitGame() {
  }


  // --------------- 资源管理 ---------------
  nodeList: cc.Node[] = [];
	atlasList: any[] = [];
  assetList: any[] = [];
  textureList: cc.Texture2D[] = [];
  
  getDragonDisplayAssetList(node: cc.Node): void {
		const dragonDisplay = node.getComponent(dragonBones.ArmatureDisplay);
		if (dragonDisplay) {
			const atlas = dragonDisplay.dragonAtlasAsset;
			const asset = dragonDisplay.dragonAsset;

			if (atlas && atlas.texture) {
				if (atlas.texture.nativeUrl.includes('h5template')) {
					node.children.forEach((child: cc.Node) => {
						this.getDragonDisplayAssetList(child);
					});
					return;
				}

				// this.nodeList.push(node);
				this.atlasList.push(atlas);
				// this.assetList.push(asset);
				this.textureList.push(atlas.texture);
				console.log('汪汪汪: atlas.texture.nativeUrl = ' + atlas.texture.nativeUrl);
			}

      this.nodeList.push(node);
      // this.atlasList.push(atlas);
      if (asset) {
        this.assetList.push(asset);
      }
      // this.textureList.push(atlas.texture);
		}

		node.children.forEach((child: cc.Node) => {
			this.getDragonDisplayAssetList(child);
		});
	}

  clearDragonDisplayAssetList() {
		console.log('喵喵喵: clearDragonDisplayAssetList');
		console.log('喵喵喵: ' + this.nodeList.length);
		console.log('喵喵喵: ' + this.atlasList.length);
		console.log('喵喵喵: ' + this.assetList.length);
		console.log('喵喵喵: ' + this.textureList.length);



		[...this.atlasList, ...this.assetList].forEach(asset => {
			asset.decRef();
			cc.assetManager.releaseAsset(asset);
			asset.destroy();
		});

		this.nodeList.forEach(node => {
        node.active = false;
			node.removeFromParent();
		});

		this.textureList.forEach(texture => {
			texture.decRef();
		});

		console.log('clearDragonDisplayAssetList end ');

	};


  clearPrefabs(node) {
    node.children.forEach(child => {

      if (child) {
        if (child._prefab && child._prefab.asset) {
            let prefabAsset = child._prefab.asset;
            child.destroy();
            cc.assetManager.releaseAsset(prefabAsset);
            cc.log("释放 Prefab:", prefabAsset._name);
        }
        // 递归处理
        this.clearPrefabs(child);
      }
    });
  }

  clearGraphics(node) {
    node.children.forEach(child => {

      if (child) {
        // 如果节点有 Graphics 组件
        let graphics = child.getComponent(cc.Graphics);
        if (graphics) {
            graphics.node.destroy();
            cc.log("释放 Graphics 节点:", child.name);
        }

        // 递归处理子节点
        this.clearGraphics(child);
    
      }});
  }
  // -----------------------------------------------



  onExitGame() {



    this.hideCloseGameBtn();
    cc.audioEngine.stopAll();

    this.getDragonDisplayAssetList(cc.find('Canvas'));

    this.clearPrefabs(cc.find('Canvas'));
    this.clearGraphics(cc.find('Canvas'));

    // if原生环境，调用原生方法清理资源
    if (cc.sys.isNative) {
      this.callNativeFunction({ name: "clean", value: "" });
    }
      
  
    
    const scene = cc.director.getScene();
   


    cc.director.loadScene("gamecenter", () => {
      // const destroyer = cc.instantiate(cc.find('middleLayer/Destroyer'));
      // destroyer.parent = cc.find('Canvas');
      // destroyer.active = true;



      // if ( cc.assetManager.releaseUnusedAssets) {
      //   console.log('汪汪汪: releaseUnusedAssets');
      //   cc.assetManager.releaseUnusedAssets();
      // }
      
  

    if (this.curBundle) {
        
      this.curBundle.releaseUnusedAssets();

      cc.assetManager.removeBundle(this.curBundle);
      this.curBundle = null;

    }

    if (scene) {
      scene.destroy();
    }
    // 强制触发一次垃圾回收（主要是 js 对象）
    cc.sys.garbageCollect();

    });
  }
}
