import { asyncCallNetworkApiGet, asyncDelay, buttonOnClick, jumpToCourseWare, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";

const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

  addPreloadImage() {
    return new Promise<void>((resolve, reject) => {
      this._imageResList.push({ url: this.data.havePic });
      this.data.pageArr.forEach(page => {
        this._imageResList.push({ url: page.bgItem.url });
        this._imageResList.push({ url: page.startBg });
      });

      const bgNode = cc.find('Canvas/bg');
      bgNode.color = cc.color(255, 255, 255);
      const startBg = this.data.pageArr[this.currentPageIdx].startBg;
      this.setNodeSpirteFrameByUrl(startBg, bgNode, resolve);
    })
  }

  async onLoadEnd() {
    await this.initData();
    this.updateView();
    this.initListener();

    if (this.step == 0) {
      await this.startStep1();
    } else {
      await asyncDelay(1);
    }
    this.updateView();
    await this.startStep2();
  }

  async startStep1() {
    await this.asyncPlayAudioByUrl(this.data.pageArr[this.currentPageIdx].startAudio);
    let testCount = 0;
    const circulate = async () => {
      await asyncDelay(0.3);
      const circle = cc.find('Canvas/step1/pad/circle');
      circle.active = true;
      const progress = cc.find('Canvas/step1/pad/circle/progress');
      const bar = progress.getComponent(cc.ProgressBar);
      bar.progress = 1;
      try {
        await Promise.race([
          this.asyncCountDown(progress, 3),
          this.checkPage()
        ]);
        this.step = 1;
      } catch (error) {
        this.showTips(`未检测到对应页面`);
        bar.progress = 1;
        circle.active = false;
        testCount ++;
        if (testCount < 10) {
          await circulate();
        } else {
          this.showTips(`检测超时`);
        }
      }
    }
    await circulate();

  }
  async startStep2() {
    console.log('this.currentPageIdx = ' + this.currentPageIdx);
    console.log('this.currentPartIdx = ' + this.currentPartIdx);

    this.asyncPlayAudioByUrl(this.data.pageArr[this.currentPageIdx].hotZoneItemArr[this.currentPartIdx].audio_url).then();
    await this.checkPart();

    const pageIdxMap = this.data.pageArr.map((page, pageIdx) => {
      return page.hotZoneItemArr.map(item => pageIdx);
    }).flat();


    const middleLayer = cc.find('middleLayer');
    if (middleLayer) {
      const middleLayerComponent = middleLayer.getComponent('middleLayer');
      middleLayerComponent.setData('NJ_game_select', {
        folderId: this.folderId,
        courseId: this.courseId,
        pageIdxMap: pageIdxMap,
        partLength: this.getPartLength(),
        step: this.step,
        currentPageIdx: this.currentPageIdx,
        currentPartIdx: this.currentPartIdx
      });
    }

    const realPartIndex = this.getPartToRowIndex();
    jumpToCourseWare(this.rows[realPartIndex].id);
  }

  getPartLength() {
    return this.data.pageArr.map(page => page.hotZoneItemArr).flat().length;
  }

  getPartToRowIndex() {
    let index = 0;
    for (let i=0; i<this.currentPageIdx; i++) {
      index += this.data.pageArr[i].hotZoneItemArr.length;
    }
    index += this.currentPartIdx;
    return index;
  }

  checkPage() {
    if (!window["courseware"] || cc.sys.isBrowser) {
      // 没有中间层的话，直接判断为检测成功
      return;
    }

    let checkSuccess = false;
    // 定时三秒检测
    const timeout = new Promise((resolve, reject) => {
      setTimeout(() => {
        if (!checkSuccess) {
          window["courseware"].closeOsmoFingerRead();
        }
        reject(new Error('checkpage timeout'));
      }, 2800)
    });
    const pageId = this.data.pageArr[this.currentPageIdx].pageIdx;
    const check = new Promise<void>((resolve, reject) => {
      window["air"].osmoFingerReadCallback = (result) => {
        const resultObj = JSON.parse(result);
        if (resultObj.page_id == pageId) {
          // 检测成功
          checkSuccess = true;
          window["courseware"].closeOsmoFingerRead();
          resolve();
        }
      };
      window["courseware"].openOsmoFingerRead({
        "page_id": pageId,
        "book_id": "opw1"
      })
    });
    return Promise.race([check, timeout]);
  }

  checkPart() {
    if (!window["courseware"] || cc.sys.isBrowser) {
      // 没有中间层的话，直接判断为检测成功
      return true;
    }

    const hotRect = this.data.pageArr[this.currentPageIdx].hotZoneItemArr[this.currentPartIdx].rect;
    const { width, height } = this.data.pageArr[this.currentPageIdx].bgItem.rect;
    const checkInRegion = (p) => {
      const rect = {
        x: hotRect.x / width,
        y: hotRect.y / height,
        width: hotRect.width / width,
        height: hotRect.height / height,
      }
      const w = p.x > rect.x && p.x < (rect.x + rect.width);
      const h = p.y > rect.y && p.y < (rect.y + rect.height);
      return w && h;
    };
    const pageId = this.data.pageArr[this.currentPageIdx].pageIdx;
    return new Promise<void>((resolve, reject) => {
      let testCount = 0;
      window["air"].osmoFingerReadCallback = (result) => {
        const resultObj = JSON.parse(result);
        const p = resultObj.finger_pos_in_page;
        if (p.x == -1 || p.y == -1) {
          testCount ++;
          if (testCount >= 5) {
            // 检测一直没成功，直接放行
            this.showTips(`检测超时`);
            window["courseware"].closeOsmoFingerRead();
            resolve();
          }
          return;
        }
        if (checkInRegion(p)) {
          // 检测成功
          window["courseware"].closeOsmoFingerRead();
          resolve();
        } else {
          testCount ++;
          if (testCount >= 5) {
            // 检测一直没成功，直接放行
            this.showTips(`检测超时`);
            window["courseware"].closeOsmoFingerRead();
            resolve();
          }
        }
      };
      window["courseware"].openOsmoFingerRead({
        "page_id": pageId,
        "book_id": "opw1"
      })
    });
  }

  folderId: any;
  rows: Array<any>;
  step = 0;
  currentPageIdx = 0;
  currentPartIdx = 0;
  courseId = 0;
  async initData() {
    const middleLayer = cc.find('middleLayer');
    let folderId = 20650;
    if (middleLayer) {
      const middleLayerComponent = middleLayer.getComponent('middleLayer');
      const tmpData = middleLayerComponent.getData('NJ_game_select');
      console.log('tmpData = ', tmpData);
      this.courseId = tmpData.courseId;
      this.currentPageIdx = tmpData.currentPageIdx || 0;
      this.currentPartIdx = tmpData.currentPartIdx || 0;
      this.step = tmpData.step || 0;
      folderId = tmpData.folderId;
      this.folderId = tmpData.folderId;

      middleLayerComponent.setData('NJ_game_select: partnerData', {
        skeJsonData: this.data.skeJsonData,
        texJsonData: this.data.texJsonData,
        texPngData: this.data.texPngData,
        havePic: this.data.havePic
      });
    }
    console.log('folderId = ' + folderId);

    const resStr = await asyncCallNetworkApiGet('/api/syllabus/v1/list', {
      pid: folderId
    });
    console.log('resStr = ' + resStr);
    const res = JSON.parse(resStr);
    this.rows = res.rows.filter(row => row.name != '指读索引');
  }

  asyncCountDown(node: cc.Node, time: number) {
    return new Promise<void>((resolve, reject) => {
      this.countDown(node, time, () => {
        resolve();
      });
    });
  }
  countDown(node: cc.Node, time: number, callback = null) {
    const progressComponent = node.getComponent(cc.ProgressBar);
    cc.tween(progressComponent)
      .to(time, { progress: 0 })
      .call(() => {
        callback && callback();
      })
      .start();
  }

  updateView() {
    const page = cc.find('Canvas/step1/pad/mask/page');
    const pageUrl = this.data.pageArr[this.currentPageIdx].bgItem.url;
    this.setNodeSpirteFrameByUrl(pageUrl, page, () => {
      page.scale = page.parent.height / page.height;
    });

    const step1 = cc.find('Canvas/step1');
    const step2 = cc.find('Canvas/step2');
    if (this.step == 0) {
      step1.active = true;
      step2.active = false;
    } else {
      step1.active = false;
      step2.active = true;
    }

    const pageData = this.data.pageArr[this.currentPageIdx];
    const bgRect = pageData.bgItem.rect;
    console.log(pageData);
    const partImg = cc.find('Canvas/step2/pad/mask/page');
    this.setNodeSpirteFrameByUrl(pageUrl, partImg, () => {
      const rect = pageData.hotZoneItemArr[this.currentPartIdx].rect;
      const x = ((rect.x + rect.width / 2) - bgRect.width / 2) * partImg.width / bgRect.width;
      const y = ((rect.y + rect.height / 2) - bgRect.height / 2) * partImg.height / bgRect.height;

      partImg.scale = Math.min(
        (partImg.parent.width / partImg.width) * (bgRect.width / rect.width),
        (partImg.parent.height / partImg.height) * (bgRect.height / rect.height)
      );
      partImg.x = x * partImg.scale;
      partImg.y = y * partImg.scale;

      console.log('partImg.scale = ' + partImg.scale);
      console.log('partImg.x = ' + partImg.x);
      console.log('partImg.y = ' + partImg.y);
    });

    const book_left = cc.find('Canvas/step1/book_left');
    const book_right = cc.find('Canvas/step1/book_right');
    if (this.currentPageIdx % 2 == 0) {
      book_left.active = true;
      book_right.active = false;
    } else {
      book_left.active = false;
      book_right.active = true;
    }

    const bgNode = cc.find('Canvas/bg');
    bgNode.color = cc.color(255, 255, 255);
    const startBg = this.data.pageArr[this.currentPageIdx].startBg;
    this.setNodeSpirteFrameByUrl(startBg, bgNode);
  }

  showTips(tips) {
    const middleLayer = cc.find('middleLayer');
    if (middleLayer) {
      const middleLayerComponent = middleLayer.getComponent('middleLayer');
      middleLayerComponent.showTips(tips);
    } else {
      console.log(tips);
    }
  }

  initListener() {
  }

  	//播放猫动画
	playCatDragon(name) {
    const animCom = cc.find(`Canvas/mao`).getComponent(dragonBones.ArmatureDisplay);
    animCom.playAnimation(name, -1);
  }
  
  asyncPlayAudioByUrl(url: string) {
    return new Promise((resolve, reject) => {
      this.playCatDragon("begin");
      this.playAudioByUrl(url, () => {
        this.playCatDragon("normal");
        resolve(null);
      });
    });
  }

  setNodeSpirteFrameByUrl(url: string, node: cc.Node, callBack = null) {
    cc.assetManager.loadRemote(url, (err, tex) => {
      node.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(tex);
      callBack && callBack();
    });
  }
}
