import { asyncDelay, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import pg from "./pg";
import map from "./map";

const { ccclass, property } = cc._decorator;

const CELLTYPE = {
    SPEAK: 1,
    MOVE_ADD: 2,
    ROLL_AGAIN: 3,
    DELAY_TIME: 4,
    JUMP_ROLL: 5,
    WIN: 100,
}
@ccclass
export default class NewClass extends MyCocosSceneComponent {
    addPreloadImage() {
        this.log("test addPreloadImage")
        // TODO 根据自己的配置预加载图片资源
        this.data && this._imageResList.push({ url: this.data.pic_url });
        this.data && this._imageResList.push({ url: this.data.pic_url_2 });
    }

    addPreloadAudio() {
        this.log("test addPreloadAudio")
        // TODO 根据自己的配置预加载音频资源
        this.data && this._audioResList.push({ url: this.data.audio_url });
    }

    addPreloadAnima() {
        this.log("test addPreloadAnima")

    }

    onLoadEnd() {
        this.log("test onLoadEnd")
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initEvent();
    }
    protected onDestroy(): void {
        cc.Tween.stopAll();
        this.unscheduleAllCallbacks();
        pg.event.off("game_start")
        pg.event.off("speak_success");
        pg.event.off("speak_fail");
    }

    _cantouch = null;
    initData() {
        this.log("test initData")
        // 所有全局变量 默认都是null 
        this._cantouch = true;
    }
    initView() {
        this.log("test initView")
        this.initTouzi();
        this.initChess();
    }
    initEvent() {
        this.log("test initEvent")
        pg.event.on("game_start", () => { this.onGameStart() })

        pg.event.on("speak_success", () => { this.onSpeakScueess() });
        pg.event.on("speak_fail", () => { this.onSpeakFail() });
    }
    //-----------------------------流程------------------------------
    private playerPoint: number;//
    private robotPoint: number;//
    private turnRobot: boolean;//当前是谁操作
    onGameStart() {
        this.log("test onGameStart")
        this.playerPoint = 0;
        this.robotPoint = 0;
        this.turnRobot = Math.random() < 0.5;
        this.initChess();
        this.scheduleOnce(this.startTouzi, 2.1);
    }
    onSpeakScueess() {
        //执行后续的动作。
        this.turnNext();
    }
    onSpeakFail() {
        //回退到最后一个位置
        let cell = map[this.playerPoint];
        this.jumpChess(cell, this.lastPointId).then(() => {

            this.turnNext();
        })
    }
    turnNext() {
        this.turnRobot = !this.turnRobot;
        this.startTouzi();
    }
    //-----------------------------CHESS-------------------------------
    private chessPlayer: cc.Node;
    private chessRobot: cc.Node;
    initChess() {
        //初始化棋子
        this.chessPlayer = pg.view.find(this, "chess/chess_player");
        this.chessRobot = pg.view.find(this, "chess/chess_robot");
        let point = map[0];
        this.chessPlayer.x = Number(point.yellow_x);
        this.chessPlayer.y = Number(point.yellow_y);
        this.chessRobot.x = Number(point.blue_x);
        this.chessRobot.y = Number(point.blue_y);
    }
    getMovePoints(now, runNum) {
        let points = [];
        for (let i = now; i <= now + runNum; i++) {
            let point = map[i];
            if (!point) break;
            points.push(point);
        }
        return points;
    }
    moveChess(runNum) {
        return new Promise((resolve, reject) => {
            this.runNum = runNum;
            if (this.turnRobot) {
                let points = this.getMovePoints(this.robotPoint, runNum);
                console.log(points);
                this.chessRobot.getComponent("chess").run(points).then(() => {
                    this.robotPoint += (points.length - 1);
                    resolve('');
                })
            } else {
                let points = this.getMovePoints(this.playerPoint, runNum);
                console.log(points);
                this.chessPlayer.getComponent("chess").run(points).then(() => {
                    this.playerPoint += (points.length - 1);
                    resolve('');
                })
            }
        });
    }
    jumpChess(cell, jumpId) {
        return new Promise((resolve, reject) => {
            let jumpCell = map[jumpId - 1];
            let points = [cell, jumpCell];
            if (this.turnRobot) {
                this.chessRobot.getComponent("chess").run(points).then(() => {
                    this.robotPoint = Number(jumpCell.id) - 1;
                    resolve('');
                })
            } else {
                this.chessPlayer.getComponent("chess").run(points).then(() => {
                    this.playerPoint = Number(jumpCell.id) - 1;
                    resolve('');
                })
            }
        });
    }
    private runNum: number;
    checkCell() {
        if (this.turnRobot) {
            let cell = map[this.robotPoint];
            let val = cell.value;
            let type = Number(cell.type);
            switch (type) {
                case CELLTYPE.MOVE_ADD:
                    this.moveChess(Number(val)).then(() => {
                        this.checkCell();
                    })
                    break;
                case CELLTYPE.ROLL_AGAIN:
                    this.turnRobot = !this.turnRobot;
                    this.turnNext();
                    break;
                case CELLTYPE.JUMP_ROLL:
                    this.jumpChess(cell, Number(val)).then(() => {
                        this.checkCell();
                    })
                    break;
                case CELLTYPE.WIN:
                    this.gameOver();
                    break;
                default:
                    this.turnNext();
                    break;
            }
            return
        }
        this.scheduleOnce(() => {
            let cell = map[this.playerPoint];
            let val = cell.value;
            let type = Number(cell.type);
            switch (type) {
                case CELLTYPE.SPEAK:
                    pg.event.emit("speak_open", cell)
                    break;
                case CELLTYPE.DELAY_TIME:
                    this.scheduleOnce(this.turnNext, 5);
                    break;
                case CELLTYPE.MOVE_ADD:
                    this.moveChess(Number(val)).then(() => {
                        this.checkCell();
                    })
                    break;
                case CELLTYPE.ROLL_AGAIN:
                    this.turnRobot = !this.turnRobot;
                    this.turnNext();
                    break;
                case CELLTYPE.JUMP_ROLL:
                    this.jumpChess(cell, Number(val)).then(() => {
                        this.checkCell();
                    })
                    break;
                case CELLTYPE.WIN:
                    this.gameOver();
                    break;
                default:
                    this.turnNext();
                    break;
            }
        }, 0.1)
    }
    //-----------------------------TOUZI-------------------------------
    initTouzi() {
        let touzi_ani = pg.view.find(this, "touzi_ani");
        let btn_stop = pg.view.find(touzi_ani, "btn_stop");
        pg.view.touchOn(btn_stop, this.onTouchStop, this);
    }
    onTouchStop() {
        if (this.turnRobot) return;
        this.stopTouzi();
    }
    lastPointId: number;
    stopTouzi() {
        pg.audio.stopAudio(this.touziAudio);
        let touzi_ani = pg.view.find(this, "touzi_ani");
        let icon = pg.view.find(touzi_ani, "icon");
        let touzi = icon.getComponent("touzi");
        let hand = pg.view.find(touzi_ani, "hand");
        let btn_stop = pg.view.find(touzi_ani, "btn_stop");
        pg.view.visible(btn_stop, false);
        this.lastPointId = this.playerPoint + 1;
        let runNum = 1;
        let rand = Math.random();
        if (this.turnRobot) {
            runNum = 1 + Math.floor(rand * 5);
        } else {
            runNum = 1 + Math.floor(rand * 6);
        }
        pg.view.visible(hand, false);
        this.unschedule(this.handVisible);
        touzi.stopAni(runNum).then(() => {
            pg.view.visible(touzi_ani, false);
            pg.event.emit("player_point_update", { isRobot: this.turnRobot, num: runNum });
            this.moveChess(runNum).then(() => {
                this.checkCell();
            })
        })
    }
    private touziAudio: number;
    startTouzi() {
        this.log("test startTouzi")
        let touzi_ani = pg.view.find(this, "touzi_ani");
        let icon = pg.view.find(touzi_ani, "icon");
        let touzi = icon.getComponent("touzi");
        let hand = pg.view.find(touzi_ani, "hand");
        let btn_stop = pg.view.find(touzi_ani, "btn_stop");
        pg.view.visible(touzi_ani, true);
        touzi.startAni();
        if (this.turnRobot) {
            this.scheduleOnce(this.stopTouzi, 1);
        } else {
            pg.view.visible(btn_stop, true);
            this.scheduleOnce(this.handVisible, 5);
        }
        pg.hw.playLocalAudio("touzi", true).then((id: number) => {
            this.touziAudio = id;
        })
    }
    handVisible() {
        let touzi_ani = pg.view.find(this, "touzi_ani");
        let hand = pg.view.find(touzi_ani, "hand");
        pg.view.visible(hand, true);
    }

    //----------------------------OVER-------------------
    gameOver() {
        let state = pg.view.find(this, "state");
        let bg_win = pg.view.find(state, "bg_win");
        let bg_lose = pg.view.find(state, "bg_lose");
        pg.view.visible(state, true);
        if (this.playerPoint > this.robotPoint) {
            pg.view.visible(bg_win, true);
            pg.view.visible(bg_lose, false);
            pg.hw.playLocalAudio("flower");
        } else {
            pg.view.visible(bg_win, false);
            pg.view.visible(bg_lose, true);
        }
        this.scheduleOnce(() => {
            pg.view.visible(bg_win, false);
            pg.view.visible(bg_lose, false);
            pg.event.emit("game_over");
        }, 5)
        // onHomeworkFinish最后需要添加作业完成
        onHomeworkFinish();
    }
    //-----------------------------TOOL-------------------------------
    playLocalAudio(audioName) {
        const audio = cc.find(`Canvas/res/audio/${audioName}`).getComponent(cc.AudioSource);
        return new Promise((resolve, reject) => {
            const id = cc.audioEngine.playEffect(audio.clip, false);
            cc.audioEngine.setFinishCallback(id, () => {
                resolve(id);
            });
        })
    }
}
