import { asyncDelay, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import pg from "./tool/pg";
import { Block, BLOCK_TYPE, GameNGT14, Question, Option } from "./tool/Game";

const { ccclass, property } = cc._decorator;

@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.initListener();
        this.initStart()
        this.gameStart();
    }

    _cantouch = null;
    initData() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        GameNGT14.getIns().initData(this.data);
        GameNGT14.getIns().reset();
        let data = GameNGT14.getIns().getCurrent();
        console.log('gamestart', data)
        this.scheduleOnce(() => {
            pg.event.emit('mouse_14_num', GameNGT14.getIns().getLen())
        }, .03)
    }

    private layout_start: cc.Node;
    private layout_finish: cc.Node;
    initView() {
        this.layout_start = pg.view.find(this, 'layout_start')
        this.layout_finish = pg.view.find(this, 'layout_finish')
        this.initBlocks();
    }
    onDestory() {
        this.unscheduleAllCallbacks();
        pg.event.clear();
    }
    initListener() {

    }

    gameStart() {
        this.answerArr = [];
        this.answerNodes = [];
        this.updateQuestion();
        this.updateHightLight();
        this.updateWords();
    }
    nextQuestion() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        let data = GameNGT14.getIns().nextQuestion();
        if (!data) {
            //游戏结束
            this.scheduleOnce(() => {
                this.showFinal();
            }, 1)
        } else {
            this.gameStart();
        }
    }


    private showFinal() {
        this.playLocalAudio("finish");
        let layout_finish = cc.find("layout_finish", this.node);
        layout_finish.active = true;
        let finish_db = cc.find("finish_db", layout_finish);
        let btn_again = cc.find("btn_again", layout_finish);
        let btn_next = cc.find("btn_next", layout_finish);
        btn_again.on(cc.Node.EventType.TOUCH_END, this.onAgain, this);
        btn_next.on(cc.Node.EventType.TOUCH_END, this.onNext, this);
        finish_db.active = true;
        btn_again.active = false;
        btn_next.active = false;
        finish_db.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);
        this.playLocalAudio("finish").then(() => {
            this.scheduleOnce(() => {
                finish_db.active = false;
                btn_again.active = true;
                btn_next.active = true;
            }, .1)
        });
    }

    private initStart() {
        return new Promise((resolve, reject) => {
            this.layout_start.active = true;
            cc.find("layout_top/label_title", this.node).getComponent(cc.Label).string = GameNGT14.getIns().title;
            pg.event.emit("mouse_09_num", GameNGT14.getIns().total);
            let start_ske = cc.find("layout_start/start_ske", this.node);
            pg.load.loadDB(start_ske, { ske: GameNGT14.getIns().aniEnter.ske.url, tex: GameNGT14.getIns().aniEnter.tex.url, png: GameNGT14.getIns().aniEnter.png.url }).then((animationName) => {
                if (animationName && animationName != "") {
                    let db = start_ske.getComponent(dragonBones.ArmatureDisplay);
                    let anis = db.getAnimationNames(db.armatureName);
                    db.playAnimation(anis[0], 0);
                    cc.tween(start_ske).by(.5, { x: -500 }).call(() => {
                        pg.audio.playAudioByUrl(GameNGT14.getIns().startAudio).then(() => {
                            cc.tween(start_ske).delay(1).by(.5, { x: 500 }).call(() => {
                                this.layout_start.active = false;
                                // this.playLaba();
                                resolve('');
                            }).start();
                        });
                    }).start();
                } else {
                    this.layout_start.active = false;
                    resolve('');
                }
            })
        });
    }
    private resetGame() {
        cc.audioEngine.stopAllEffects();
        this.playLocalAudio("again");
        this.initData();
        this.initView();
        this.gameStart();
    }
    private onAgain() {
        this.layout_finish.active = false;
        this.resetGame();
    }
    private onNext() {
        const middleLayer = cc.find('middleLayer');
        if (middleLayer) {
            const mc = middleLayer.getComponent('middleLayer');
            // // 切换下一页
            mc.goNextPage();
        }
    }
    //----------------------------------------右上题目部分-----------------------------------
    private layout_question: cc.Node;
    updateQuestion() {
        let data = GameNGT14.getIns().getCurrent();
        this.layout_question = pg.view.find(this, 'layout_question');
        // 需要处理数据
        this.updateItem(this.layout_question, data);
    }

    getLayByOption(option: Option, base, { onlyImg, showCenter }) {
        if (onlyImg) {
            return cc.instantiate(pg.view.find(base, 'layout_full'))
        } else if (showCenter) {
            return cc.instantiate(pg.view.find(base, 'layout_center'))
        } else {
            return option.isDoubleLine() ? cc.instantiate(pg.view.find(base, 'layout_double')) : cc.instantiate(pg.view.find(base, 'layout_single'));
        }
    }
    getNodeByBlock(block: Block, base, { onlyImg }) {
        switch (block.type) {
            case BLOCK_TYPE.IMG:
                if (onlyImg) {
                    return cc.instantiate(pg.view.find(base, 'img_big'))
                } else {
                    return cc.instantiate(pg.view.find(base, 'img'))
                }
            case BLOCK_TYPE.TXT:
                if (onlyImg) {
                    return cc.instantiate(pg.view.find(base, 'label_big'))
                } else {
                    return cc.instantiate(pg.view.find(base, 'label'))
                }
            case BLOCK_TYPE.LINE:
                return cc.instantiate(pg.view.find(base, 'line'))
            case BLOCK_TYPE.TAG:
                return cc.instantiate(pg.view.find(base, 'tag'))
        }
    }
    updateItem(item, data: Question) {
        pg.view.visible(item, true);
        item.data = data;

        // let board = pg.view.find(item, 'board');
        let base = pg.view.find(item, 'base');
        // 确定基础layout
        let layout = pg.view.find(item, 'layout');
        layout.removeAllChildren();
        let list: Array<Option> = data.getList();
        list.forEach(option => {
            let blocks = option.getList();
            let showCenter = blocks.length == 1 && (blocks[0].type == BLOCK_TYPE.IMG);//|| blocks[0].type == BLOCK_TYPE.TXT
            let onlyImg = list.length == 1 && showCenter;
            //确定使用的单双行
            let lay = this.getLayByOption(option, base, { onlyImg, showCenter });
            pg.view.addChild(layout, lay);
            blocks.forEach(block => {
                //确定使用哪种节点
                let node = this.getNodeByBlock(block, base, { onlyImg });
                node.y = 0;
                pg.view.addChild(lay, node);
                this.updateNode(node, block)
            })
        })
        setTimeout(() => {
            let height = layout.height;
            item.height = height + 15;
        }, 0);
    }
    updateNode(item, block: Block) {
        item.data = block;
        switch (block.type) {
            case BLOCK_TYPE.IMG:
                this.updateImg(item, block)
                break
            case BLOCK_TYPE.TXT:
                this.updateLabel(item, block)
                break
            case BLOCK_TYPE.LINE:
                this.updateLine(item, block)
                break
            case BLOCK_TYPE.TAG:
                this.updateTag(item, block)
                break
        }
    }
    updateImg(item, block: Block) {
        pg.view.setNetImg(item, block.img, { w: item.width, h: item.height })
    }
    updateLine(item, block: Block) {
        item.width = block.line * 30;
        // pg.view.visible(pg.view.find(item, 'label/input_cursor'), false)
        // pg.view.touchOn(item, this.onTouchLine, this);
    }
    updateLabel(item, block: Block) {
        pg.view.setString(item, block.text)
    }
    updateTag(item, block: Block) {
    }
    //----------------------------------------左侧方块部分-----------------------------------
    private layout_blocks: cc.Node;
    initBlocks() {
        this.layout_blocks = pg.view.find(this, 'layout_blocks');
        this.layout_blocks.removeAllChildren()
        let block = pg.view.find(this, 'block');
        //动态创建，并给每一个打上编号
        let space = { x: 9 + 80, y: 10 + 80 }
        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 12; x++) {
                let node = cc.instantiate(block);
                let data = { x, y, val: '', rightVal: '' };
                node.data = data;
                node.x = -495 + space.x * x;
                node.y = 365 - space.y * y;
                node.active = !!GameNGT14.getIns().getBlockVal(x, y);
                this.layout_blocks.addChild(node);
            }
        }
    }
    getHightLightNodes() {
        let list = GameNGT14.getIns().getHightList();
        return this.layout_blocks.children.filter(node => {
            return list.some(li => li.compare(node.data))
        })
    }
    // 更新面板高亮
    updateHightLight() {
        let list = GameNGT14.getIns().getHightList();
        let first = null;
        this.layout_blocks.children.forEach(node => {
            let point = node.data;
            let li = list.find(li => li.compare(point))
            if (li) {
                point.rightVal = li.rightVal
                pg.view.visible(pg.view.find(node, 'img_undone'), false)
                pg.view.visible(pg.view.find(node, 'img_focus'), true)
                if (!point.val && !first) {
                    first = true;
                    pg.view.visible(pg.view.find(node, 'img_focus2'), true)
                }
            }
            // else {
            //     pg.view.visible(pg.view.find(node, 'img_undone'), true)
            //     pg.view.visible(pg.view.find(node, 'img_focus'), false)
            //     pg.view.visible(pg.view.find(node, 'img_focus2'), false)
            // }
        })
    }
    // 更新面板颜色
    updateBlockColor(nodes, nodeName) {
        nodes.forEach(node => {
            pg.view.visible(pg.view.find(node, 'img_undone'), false)
            pg.view.visible(pg.view.find(node, 'img_focus'), false)
            pg.view.visible(pg.view.find(node, 'img_keyboard_1'), false)
            pg.view.visible(pg.view.find(node, 'img_keyboard_2'), false)
            pg.view.visible(pg.view.find(node, 'img_keyboard_3'), false)
            pg.view.visible(pg.view.find(node, 'img_keyboard_4'), false)
            pg.view.visible(pg.view.find(node, 'img_keyboard_5'), false)
            pg.view.visible(pg.view.find(node, 'img_right'), false)
            pg.view.visible(pg.view.find(node, 'img_right_wrong'), false)
            pg.view.visible(pg.view.find(node, 'img_wrong'), false)
            pg.view.visible(pg.view.find(node, nodeName), true)
        })
    }

    // 更新当前面板颜色
    private answerArr: Array<{ nd, bg }>;
    private isRight() {
        let answer = GameNGT14.getIns().getCurrent().answer;
        let str = "";
        this.answerArr.sort((A, B) => A.nd.x - B.nd.x);
        this.answerArr.forEach(node => str += node.nd.data.word)
        return answer == str;
    }
    private answerNodes: Array<cc.Node>;
    updateCurrentNodeColor(node, data) {
        let label = node.getChildByName('label')
        pg.view.visible(label, true)
        pg.view.setString(label, data.word)
        for (let i = 1; i <= 5; i++) {
            pg.view.visible(pg.view.find(node, 'img_keyboard_' + i), data.color == i);
        }
        let block = node.data;
        block.val = data.word;
        this.answerNodes.push(node);
    }

    getBlockNodeByPos(x, y) {
        return this.layout_blocks.children.find(node => node.data.x == x && node.data.y == y)
    }
    //----------------------------------------右下角单词部分-----------------------------------

    private layout_words: cc.Node;
    updateWords() {
        let word = pg.view.find(this, 'word');
        this.layout_words = pg.view.find(this, 'layout_words');
        this.layout_words.removeAllChildren()
        let words = GameNGT14.getIns().getCurrent().getWords();
        let space = { x: 150, y: 150 }
        words.forEach((w, index) => {
            let node = cc.instantiate(word);
            let data = w;
            if (index < 5) {
                node.x = 280 + space.x * index
                node.y = -110
            } else if (index < 9) {
                node.x = 355 + space.x * (index - 5)
                node.y = -110 - space.y;
            } else {
                node.x = 280 + space.x * (index - 9)
                node.y = -110 - space.y * 2;
            }
            this.layout_words.addChild(node);
            data.pos = cc.v2(node)
            //入场动画
            node.x = node.x + 1000;
            cc.tween(node).delay(0.1 * index).by(0.5, { x: -1000 }).start();
            this.updateWord(node, data);
        });
    }
    updateWord(node, data) {
        node.data = data;
        node.rotation = data.rotation
        pg.view.setString(pg.view.find(node, 'label'), data.word);
        for (let i = 1; i <= 5; i++) {
            pg.view.visible(pg.view.find(node, 'img_keyboard_' + i), data.color == i);
        }
        node.on(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        node.on(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        node.on(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
        node.on(cc.Node.EventType.TOUCH_CANCEL, this.onItemTouchCancel, this);
    }
    private setTouchPos(e) {
        let item = e.target;
        let location = e.getLocation();
        cc.Tween.stopAllByTarget(item);
        let pos = location.sub(cc.v2(cc.winSize.width / 2, cc.winSize.height / 2));
        item.x = pos.x;
        item.y = pos.y;
    }
    private touching: any;
    onItemTouchStart(e) {
        if (this.touching) return;
        let target: cc.Node = e.target;
        let data: string = target.data;
        this.setTouchPos(e);
        this.touching = data;
        this.playLocalAudio('drop_start')
    }
    onItemTouchMove(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        if (!this.touching) return;
        if (this.touching != data) return;
        this.setTouchPos(e);
    }
    onItemTouchEnd(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        if (!this.touching ||
            this.touching != data
        ) {
            this.touching = null;
            target.x = target.data.pos.x;
            target.y = target.data.pos.y;
            target.scale = 1;
            this.answerArr = this.answerArr.filter(ans => {
                return ans.nd != target;
            })
            return;
        }
        // let rect = cc.rect(target.x, target.y, target.width, target.height);
        let rect = cc.rect(target.x, target.y, 1, 1);
        //坐标转换
        let collNode = null;
        this.layout_blocks.children.forEach(node => {
            // 开始做碰撞
            // 坐标转换
            let nodeWP = node.convertToWorldSpaceAR(cc.v2(-40, -40));
            let nodeNP = this.layout_words.convertToNodeSpaceAR(nodeWP);
            let nodeRect = cc.rect(nodeNP.x, nodeNP.y, node.width, node.height);
            if (rect.intersects(nodeRect)) {
                collNode = node;
            }
        })
        //是否碰撞
        if (!collNode || !collNode.data.rightVal || !!collNode.data.val) {
            this.touching = null;
            target.x = target.data.pos.x;
            target.y = target.data.pos.y;
            target.scale = 1;
            this.answerArr = this.answerArr.filter(ans => {
                return ans.nd != target;
            })
            return;
        }


        //是否正确
        this.playLocalAudio('move').then(() => { })
        let pos = target.parent.convertToNodeSpaceAR(collNode.convertToWorldSpaceAR(cc.v2(0, 0)));
        let scale = collNode.width / target.width;
        cc.tween(target).to(0.15, { scale: scale, rotation: 0, x: pos.x, y: pos.y }).call(() => {
            // block需要显示内容
            // target.active = false;

            this.touching = null;
            this.answerArr.push({ bg: collNode, nd: target });
            target.data.chosed = true;
            // 判断此行是否完成
            let lineFull = this.answerArr.length == GameNGT14.getIns().getCurrent().answer.length;
            if (lineFull) {
                this.answerArr.forEach(ans => {
                    ans.nd.off(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
                    ans.nd.off(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
                    ans.nd.off(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
                    ans.nd.off(cc.Node.EventType.TOUCH_CANCEL, this.onItemTouchCancel, this);
                    ans.nd.active = false;
                    this.updateCurrentNodeColor(ans.bg, ans.nd.data);
                })
                let nodes = this.getHightLightNodes();

                if (this.isRight()) {
                    //执行放大10%
                    nodes.forEach((node, index) => {
                        //执行星星动画
                        this.scheduleOnce(() => {
                            pg.view.visible(pg.view.find(node, 'star'), true)
                            cc.tween(node).by(0.2, { scale: 0.1 }).by(0.2, { scale: -0.1 }).start();
                            if (index == nodes.length - 1) {
                                this.scheduleOnce(() => {
                                    pg.event.emit("mouse_14_add");
                                    //执行颜色变right
                                    this.updateBlockColor(nodes, 'img_right')
                                    //播放right音效
                                    this.playLocalAudio('right').then(() => {
                                        pg.event.emit('mouse_05_add')
                                        //其他字母向下掉出
                                        let once = false;
                                        this.layout_words.children.forEach((node, index) => {
                                            cc.tween(node)
                                                .delay(0.05 * (this.layout_words.children.length - index))
                                                .by(0.3, { y: -1000 })
                                                .delay(0.8)
                                                .call(() => {
                                                    if (once) return;
                                                    once = true;
                                                    this.nextQuestion();
                                                })
                                                .start();
                                        })
                                    })
                                }, 0.3)
                            }
                        }, 0.1 * index)
                    })
                } else {
                    //执行颜色变error
                    this.updateBlockColor(nodes, 'img_wrong')
                    //播放error音频
                    this.playLocalAudio('error').then(() => {
                        //执行放大10%
                        nodes.forEach(node => {
                            cc.tween(node)
                                .by(0.2, { scale: 0.1 })
                                .by(0.2, { scale: -0.1 })
                                .call(() => {
                                })
                                .start();
                        })
                        this.scheduleOnce(() => {
                            nodes.forEach(node => {
                                //这里得换文字内容
                                let label = node.getChildByName('label')
                                pg.view.visible(label, true)
                                pg.view.setString(label, node.data.rightVal)
                            })
                            //执行颜色变right_wrong
                            this.updateBlockColor(nodes, 'img_right_wrong')
                            //播放音频right_wrong
                            this.playLocalAudio('right_wrong')
                            //播放灰色徽章
                            pg.event.emit("mouse_14_add_error");
                            //其他字母向下掉出
                            let once = false;
                            this.layout_words.children.forEach((node, index) => {
                                cc.tween(node)
                                    .delay(0.05 * (this.layout_words.children.length - index))
                                    .by(0.3, { y: -1000 })
                                    .delay(0.8)
                                    .call(() => {
                                        if (once) return;
                                        once = true;
                                        this.nextQuestion();
                                    })
                                    .start();
                            })
                        }, 1)
                    })
                }
            } else {
                // 下一个格子刷新聚焦
                this.updateHightLight();
            }
        }).start();
    }
    onItemTouchCancel() {

    }














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