import { asyncDelay, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import { Item, Part, Game } from "./model/game";
import pg from "./pg";
import Ani from "./ani";
import {
    showFireworks,
} from '../script/utils';

const { ccclass, property } = cc._decorator;
enum STATE {
    WAITING,
    AUDIOING,
    GUIDING,
    AUDIOED,
    GAMING,
    GAMED
}
@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    addPreloadImage() {
        // TODO 根据自己的配置预加载图片资源
        this._imageResList.push({ url: this.data.pic_url });
        this._imageResList.push({ url: this.data.pic_url_2 });
    }

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

    addPreloadAnima() {

    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initEvent();
        this.updateState(0);
    }

    _cantouch = null;
    initData() {
        Game.getIns().init(this.data);
    }

    initView() {
    }

    initEvent() {
        let btn_start: cc.Node = pg.view.find(this, "btn_start");
        let btn_restart = pg.view.find(this, "btn_restart");
        let btn_stem: cc.Node = pg.view.find(this, "btn_stem");
        pg.view.touchOn(btn_start, this.onBtnStart, this);
        pg.view.touchOn(btn_restart, this.onBtnRestart, this);
        pg.view.touchOn(btn_stem, this.onBtnStem, this);
    }

    onBtnStart() {
        this.playLocalAudio("start");
        let btn_start: cc.Node = pg.view.find(this, "btn_start");
        //执行开始单个游戏开始
        cc.tween(btn_start).by(0.3, { x: 1500 }).call(() => {
            this.updateState(1);
        }).start();
    }
    onBtnRestart() {
        this.playLocalAudio("start");
        Game.getIns().current = 0;
        this.updateState(1);
    }
    nextPart() {
        Game.getIns().current++;
        this.updateState(1);
    }
    updateState(state) {
        switch (state) {
            case 0:
                this.updateWait();
                break;
            case 1:
                this.initPartData();
                this.updatePart();
                break;
        }
    }

    updateWait() {
        let btn_start: any = pg.view.find(this, "btn_start");
        let panel_gary = pg.view.find(this, "panel_gary");
        pg.view.visible(btn_start, true);
        pg.view.visible(panel_gary, true);
        this.updatePartPercent();
    }
    updateRestart() {
        let btn_restart = pg.view.find(this, "btn_restart");
        let panel_gary = pg.view.find(this, "panel_gary");
        btn_restart.active = true;
        panel_gary.active = true;
    }
    private part: Part;
    private playing: number;
    initPartData() {
        this.part = Game.getIns().part;
        this.playing = STATE.WAITING;
    }
    updatePart() {
        if (!this.part) {
            //出现重新开始的按钮
            this.showFireFlower().then(() => {
                this.updateRestart();
                onHomeworkFinish();
            });
            return;
        }
        pg.view.visible(pg.view.find(this, "btn_start"), false);
        pg.view.visible(pg.view.find(this, "btn_restart"), false);
        pg.view.visible(pg.view.find(this, "panel_gary"), false);
        let btn_stem: cc.Node = pg.view.find(this, "btn_stem");
        pg.view.visible(pg.view.find(btn_stem, "icon_hand"), true);
        this.updatePartPercent();
        this.updateBtnStem();
        this.updateList();
        this.updatePerson();
    }
    updateBtnStem(isPlay: boolean = false) {
        let btn_stem: cc.Node = pg.view.find(this, "btn_stem");
        let btn_stem_audio: cc.Node = pg.view.find(this, "btn_stem_ani");
        pg.view.visible(btn_stem, !isPlay);
        pg.view.visible(btn_stem_audio, isPlay);
    }
    private a;
    onBtnStem() {
        if (this.playing != STATE.WAITING) return;
        //播放音效，允许后续操作。
        this.playing = STATE.AUDIOING;
        let btn_stem: cc.Node = pg.view.find(this, "btn_stem");
        pg.view.visible(pg.view.find(btn_stem, "icon_hand"), false);
        this.updateBtnStem(true);
        pg.audio.playAudioByUrl(this.part.stemAudio).then(() => {
            if (!this.a) {
                this.a = true;
                this.playing = STATE.GUIDING;
                this.updatePersonGuide();
            } else {
                this.playing = STATE.AUDIOED;
            }
            this.updateBtnStem(false);
        })
    }
    updateList() {
        pg.view.visible(pg.view.find(this, "layout_items"), true)

        let layout_items = pg.view.find(this, "layout_items");
        let items = layout_items.children;
        items.sort((A, B) => {
            return A.x - B.x;
        })
        let list = this.part.list;
        for (let i = 0; i < items.length; i++) {
            let item = items[i];
            let data = list[i];
            if (!data) {
                item.active = false;
                continue;
            } else {
                this.updateShopItem(item, data);
            }
        }

        layout_items.y += 1000;
        cc.tween(layout_items).by(0.3, { y: -1000 }).start();
    }
    updateShopItem(item, data: Item) {
        item.active = true;

        let bg_board = pg.view.find(item, "bg_board");
        let bg_board_down = pg.view.find(item, "bg_board_down");
        let icon_arrow = pg.view.find(item, "icon_arrow");
        let img_pic = pg.view.find(item, "img_pic");
        let label_percent = pg.view.find(item, "label_percent");

        pg.view.visible(bg_board, true);
        pg.view.visible(bg_board_down, false);
        pg.view.visible(icon_arrow, false);
        if (data.type == "pic") {
            pg.view.visible(img_pic, true);
            pg.view.visible(label_percent, false);
            pg.view.setNetImg(img_pic, data.pic, { w: 350, h: 240 })
        } else {
            pg.view.visible(img_pic, false);
            pg.view.visible(label_percent, true);
            pg.view.setString(label_percent, data.text);
        }
        item.data = data;
    }
    updatePerson(noAni: boolean = false) {
        let img_person: cc.Node = pg.view.find(this, "img_person");
        img_person.active = true;
        img_person.x = 0;
        img_person.y = -300;
        img_person.scale = 1;

        img_person.on(cc.Node.EventType.TOUCH_MOVE, this.onImgPersonMove, this);
        img_person.on(cc.Node.EventType.TOUCH_END, this.onImgPersonEnd, this);

        if (!noAni) {
            img_person.y -= 1000;
            cc.tween(img_person).by(0.3, { y: 1000 }).start();
        }
    }
    updatePersonGuide() {
        let img_person: cc.Node = pg.view.find(this, "img_person");
        img_person.active = true;
        img_person.x = 0;
        img_person.y = -300;
        img_person.scale = 1;


        pg.view.visible(pg.view.find(img_person, "icon_hand"), true);
        cc.tween(img_person).by(0.7, { x: -600 }).by(0.7, { x: 600 }).call(() => {
            pg.view.visible(pg.view.find(img_person, "icon_hand"), false);
            this.playing = STATE.AUDIOED;
        }).start();
    }
    onImgPersonMove(e) {
        if (this.playing != STATE.AUDIOED) return;
        let currentTouch = e.currentTouch;
        let pos = currentTouch.getLocation();
        //移动效果
        let img_person: cc.Node = pg.view.find(this, "img_person");
        img_person.x = pos.x - (cc.winSize.width / 2);
        //对比刷新items
        let layout_items = pg.view.find(this, "layout_items");
        let items = layout_items.children;
        items.forEach(item => {
            pg.view.visible(pg.view.find(item, "icon_arrow"), false);
        })
        let item = this.getItemByX(img_person.x);
        pg.view.visible(pg.view.find(item, "icon_arrow"), true);
    }
    onImgPersonEnd(e) {
        if (this.playing != STATE.AUDIOED) return;
        let currentTouch = e.currentTouch;
        let pos = currentTouch.getLocation();
        let img_person: cc.Node = pg.view.find(this, "img_person");
        img_person.x = pos.x - (cc.winSize.width / 2);
        let item: any = this.getItemByX(img_person.x);
        if (item.data.right) {
            //处理正确
            this.itemRight(item);
        } else {
            //处理错误
            this.itemError(item);
        }
    }
    updateArrow(x) {
        //根据x来确定哪一个箭头显示
        let arrows = [-100, 0, 100, 200]
        let nowId = 0;
        let arrowX = arrows[nowId];
        let img_arrow: cc.Node;
        img_arrow.x = arrowX;
        img_arrow.active = true;
    }

    itemRight(item) {
        let img_person: cc.Node = pg.view.find(this, "img_person");
        this.playLocalAudio("sonw");
        cc.tween(img_person).to(1, {
            scale: 0.8, x: item.x, y: -0
        }).delay(0.05).call(() => {
            this.playLocalAudio("right");
            let layout_items = pg.view.find(this, "layout_items");
            layout_items.active = false;
        }).start();

        setTimeout(() => {
            let bg_board = pg.view.find(item, "bg_board");
            let bg_board_down = pg.view.find(item, "bg_board_down");
            let icon_arrow = pg.view.find(item, "icon_arrow");
            let img_pic = pg.view.find(item, "img_pic");
            let label_percent = pg.view.find(item, "label_percent");
            pg.view.visible(bg_board, false);
            pg.view.visible(bg_board_down, true);
            pg.view.visible(icon_arrow, false);
            pg.view.visible(img_pic, false);
            pg.view.visible(label_percent, false);
        }, 700);
        setTimeout(() => {
            this.nextPart();
        }, 1700);
    }
    itemError(item) {
        let bg_board = pg.view.find(item, "bg_board");
        let bg_board_down = pg.view.find(item, "bg_board_down");
        let icon_arrow = pg.view.find(item, "icon_arrow");
        let img_pic = pg.view.find(item, "img_pic");
        let label_percent = pg.view.find(item, "label_percent");
        let img_person: cc.Node = pg.view.find(this, "img_person");
        this.playLocalAudio("sonw");
        cc.tween(img_person).to(1, {
            scale: 0.8, x: item.x, y: -0
        }).delay(0.05).call(() => {
            this.playLocalAudio("error");
            Ani.shake(item)
            pg.view.visible(icon_arrow, false);
            setTimeout(() => {
                this.updatePerson(true);
            }, 100);
        }).start();
    }


    updatePartPercent() {
        let label_percent: cc.Node = pg.view.find(this, "panel_percent/label_percent");
        pg.view.setString(label_percent, `${Game.getIns().part.id + 1} / ${Game.getIns().list.length}`);
    }




    public getIdByX(x): number {
        let layout_items = pg.view.find(this, "layout_items");
        let items = layout_items.children;
        let arr = [];
        items.forEach(it => {
            arr.push(it.x + it.width / 2);
        })
        arr.sort();
        for (let i = 0; i < arr.length; i++) {
            if (x <= arr[i]) {
                return i;
            }
        }
        return 3;
    }
    public getItemByX(x): cc.Node {
        let layout_items = pg.view.find(this, "layout_items");
        let items = layout_items.children;
        items.sort((A, B) => {
            return A.x - B.x;
        })
        return items[this.getIdByX(x)];
    }













    showFireFlower() {
        return new Promise((resolve, reject) => {
            this.playLocalAudio("flower")
            showFireworks(
                this.node,
                pg.view.find(this, 'RibbonNodeBase').children,
                cc.v2(0, -600), cc.v2(0, 1000), 200, 200
            );
            showFireworks(
                this.node,
                pg.view.find(this, 'RibbonNodeBase').children,
                cc.v2(-600, -600), cc.v2(200, 1000), 200, 200
            );
            showFireworks(
                this.node,
                pg.view.find(this, 'RibbonNodeBase').children,
                cc.v2(600, -600), cc.v2(-200, 1000), 200, 200
            );
            setTimeout(() => {
                resolve('');
            }, 1500);
        });
    }
    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);
            });
        })
    }
}
