import { asyncDelay, onHomeworkFinish, RandomInt } from "../script/util_hy07_tiankong";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent_hy07_tiankong";
import Game, { FISH_OUT, GAME_STATE, Option } from "./tool/Game_hy07_tiankong";
import pg from "./tool/pg_hy07_tiankong";

const { ccclass, property } = cc._decorator;

export function getDegree(p1, p2) {
    let vector = p2.sub(p1);
    let degree = Math.atan(vector.y / vector.x) / Math.PI * 180;
    if (vector.x >= 0) {
        if (vector.y < 0) {
            degree += 360;
        }
    } else {
        if (vector.y > 0) {
            degree += 180;
        } else {
            degree = 180 + degree;
        }
    }
    return -(-degree + 90);//角度计算方法
}
let win: any = window;
let courseware = win.courseware;
enum GUN_STATE {
    WAIT = 1,
    SHUT_MIDDLE,
    SHUT_LEFT,
    SHUT_RIGHT
}
enum FISH_STATE {
    NORMAL = 1,
    BREAK,
    FALL,
}
enum TIPS_STATE {
    GOOD = 1,
    TRY,
    COM,
}
@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    addPreloadImage() {
        // TODO 根据自己的配置预加载图片资源
        this._imageResList.push(...this.data.questions.map(question => {
            return { url: question.image };
        }));
    }

    addPreloadAudio() {
        // TODO 根据自己的配置预加载音频资源
        this._audioResList.push({ url: this.data.questionTextAudio });
        this._audioResList.push({ url: this.data.bgAudio });
        this._audioResList.push(...this.data.questions.map(question => {
            return { url: question.audio };
        }));
    }

    addPreloadAnima() {

    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initListener();
    }
    protected onDestroy(): void {
        pg.event.clear();
    }

    @property(cc.Node)
    layout_game: cc.Node = null;
    @property(cc.Node)
    layout_up: cc.Node = null;
    @property(cc.Node)
    layout_down: cc.Node = null;
    @property(cc.Node)
    item1: cc.Node = null;
    @property(cc.Node)
    item2: cc.Node = null;
    @property(cc.Node)
    item3: cc.Node = null;
    @property(cc.Node)
    item4: cc.Node = null;

    private tryData: Array<Option>;
    private timeSecond;
    private assessCount;
    private isClick = true;
    private coin;
    initData() {
        Game.getIns().init(this.data);
        Game.getIns().reset();
        this.tryData = [];
        // 所有全局变量 默认都是null 
        this.timeSecond = 0;
        this.assessCount = 0;
        this.coin = 0;
        this.isClick = true;
    }
    private audioId: any;

    async initView() {
        cc.audioEngine.stopAllEffects();
        this.gameStart();
    }


    private initListener() {

        pg.event.on("layer_record_score", (score) => {
        });

        pg.event.on('npc_voice_play_voice_end', () => {

        })
        pg.event.emit('npc_layer_back_init', this.data)


        pg.event.on('layer_right_show_excellent_end', () => {
            this.coin += 3;
            pg.event.emit('layer_coin_show_coin', 3)   //1 2 3硬币数量
        })
        pg.event.on('layer_ending_touch_replay', () => {
            this.replay();
        })
        pg.event.on('layer_coin_show_coin_end', () => {
            let over = Game.getIns().addPage();
            if (!over) {
                // pg.event.emit('layer_ending_show', { coin: this.coin })
                this.sendData(this.coin).then(() => {
                    const midd = cc.find('middleLayer');
                    if (!midd) return this.log("no middleLayer");
                    let middleLayer = midd.getComponent('middleLayer');
                    middleLayer.saveGolds(this.coin); // 保存金币数量；num 是获得金币的数量，数字类型；
                    middleLayer.goNextPage();  // 跳转到下一页
                })
            } else {
                this.gameStart();
            }

        })
        pg.event.on("camdy_action_end", (node) => {
            node.active = false;
            let pic_light = cc.find("pic_light", node.parent);
            if (pic_light) pic_light.active = false;
        });
    }

    sendData(score) {
        return new Promise(res => {
            let upData: any = {
                word_count: this.data.word_count || 0,
                sentence_count: this.data.sentence_count || 0,
                zi_count: this.data.zi_count || 0,
                score: score || 0,
            };
            let recordList = pg.hw.getRecord();
            if (recordList && recordList.length > 0) {
                upData.recordList = recordList
            }
            const middleLayer = cc.find('middleLayer').getComponent('middleLayer');
            console.log('upload->' + JSON.stringify(upData))
            middleLayer.onHomeworkFinish(upData, () => {
                res('');
            })
        })
    }

    replay() {
        this.initData();
        this.initView();
    }

    private playOpAudio() {
        let question = Game.getIns().getCurrentPage();
        if (question.audioUrl != "") {
            pg.audio.playAudioByUrl(question.audioUrl).then(async () => {
                await asyncDelay(0.5);
                pg.event.emit("layer_right_show_excellent");
            })
        } else {
            pg.event.emit("layer_right_show_excellent");
        }

    }
    private gameOver() {
        Game.getIns().state = GAME_STATE.OVER;
        let data: any = {};
        data.total = Game.getIns().total;
        data.right = Game.getIns().player.right;
        data.scores = Game.getIns().player.voices;
        data.stone = Math.floor(10 * data.right / data.total);
        this.log("total: " + data.total + "      right: " + data.right + "   stone: " + data.stone);
        onHomeworkFinish(data)
    }

    gameStart() {
        Game.getIns().state = GAME_STATE.RUNNING;
        this.showQuestion();
    }
    private wordItams: cc.Node[];
    private async showQuestion() {

        this.playLocalAudio("show");
        this.wordItams = [];
        let data = Game.getIns().getCurrentPage();

        let isBig = data.wordArr.length > 5;
        let count = data.count;
        this.layout_up.removeAllChildren();
        this.layout_up.getComponent(cc.Layout).enabled = true;

        data.wordArr.forEach(async (dt) => {
            let item = isBig ? cc.instantiate(this.item4) : cc.instantiate(this.item3);
            let word = cc.find("word", item);
            let box1 = cc.find("box1", item);
            let box = cc.find("box", item);
            // let xian = cc.find("xian", item);
            word.getComponent(cc.Label).string = dt.text.split(" ").join("");
            item.active = true;
            item.parent = this.layout_up;
            item.data = dt.text.split(" ").join("");
            this.wordItams.push(item);
            if (isBig) {
                await asyncDelay(0);
                word.color = new cc.Color(0, 0, 0);
                item.width = word.width + 30;
            }
            if (dt.block) {
                // if (xian) xian.active = true;
                word.getComponent(cc.Label).string = "";
            } else {
                if (box1) box1.active = true;
                if (box) box.active = false;
            }
        })
        this.layout_up.active = true;
        this.layout_up.getComponent(cc.Layout).updateLayout();



        data.wordArr.sort(function () {
            return (0.5 - Math.random());
        });

        this.layout_down.removeAllChildren();
        data.wordArr.forEach((dt, idx) => {
            if (!dt.block) return;
            let item = count > 5 ? cc.instantiate(this.item2) : cc.instantiate(this.item1);
            if (count > 5) {
                if (idx % 2 == 1) item.y = -600;
                else item.y = -500;
            } else {
                item.y = -500;
            }
            this.iniItem(item, dt.text)
        })


        if (data.wordArr.length == 5) {
            this.layout_up.getComponent(cc.Layout).spacingX = 10;
            // this.layout_down.getComponent(cc.Layout).spacingX = 50;
        } else if (data.wordArr.length < 5) {
            this.layout_up.getComponent(cc.Layout).spacingX = 60;
            // this.layout_down.getComponent(cc.Layout).spacingX = 70;
        } else {
            // this.layout_down.getComponent(cc.Layout).spacingX = -100;
            this.layout_up.getComponent(cc.Layout).spacingX = 10;
        }
        // this.layout_up.getComponent(cc.Sprite).enabled = data.wordArr.length > 5;

        this.layout_down.getComponent(cc.Layout).spacingX = count == 5 ? 10 : count < 5 ? 60 : -100;
        this.layout_down.children.forEach((ch, idx) => {
            let time = count > 5 ? idx % 2 == 1 ? 0.5 : 0.1 : 0.1;
            let y = count > 5 ? idx % 2 == 1 ? -160 : 90 : 90;
            cc.tween(ch).delay(time).to(0.5, { y: y })
                .call(() => {
                    let card = cc.find("card", ch);
                    let data = card.data;
                    data.parentPos = ch.getPosition();
                    this.itemAction(ch);
                })
                .start();

        })
        this.layout_down.getComponent(cc.Layout).updateLayout();
        this.layout_up.getComponent(cc.Layout).updateLayout();
        let box_up = cc.find("box_up", this.layout_game);

        await asyncDelay(0.03);
        box_up.active = isBig;
        this.isClick = true;
        if (isBig && this.layout_up.width < this.layout_down.width) {
            this.layout_up.getComponent(cc.Layout).enabled = false;
            this.layout_up.width = this.layout_down.width;
        }
        box_up.width = this.layout_up.width;
    }
    private iniItem(item, text) {
        let card = cc.find("card", item);
        let word = cc.find("word", card);
        word.getComponent(cc.Label).string = text;


        let data: any = {};
        data.text = text.split(" ").join("");
        data.parent = card.parent;
        data.startPos = card.getPosition();
        card.data = data;

        item.active = true;
        item.parent = this.layout_down;

        card.off(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        card.off(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        card.off(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);

        card.on(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        card.on(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        card.on(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
    }

    private itemAction(node) {
        let time = RandomInt(0.5, 2);
        cc.tween(node).repeatForever(cc.tween().by(1 + time, { y: 15 }).by(1 + time, { y: -15 })).start();
    }
    private setTouchPos(e) {
        let location = e.getLocation();
        let size = cc.view.getCanvasSize();
        let scale = (size.width / size.height) / (1920 / 1080);
        if (scale > 1) {
            let width = size.width / size.height * 1080;
            let pos = location.sub(cc.v2(width / 2, 1080 / 2))
            e.target.setPosition(pos)
        } else {
            let height = size.height / size.width * 1920;
            let pos = location.sub(cc.v2(1920 / 2, height / 2))
            e.target.setPosition(pos)
        }
    }

    onItemTouchStart(e) {
        if (!this.isClick) return;
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        // this.floatAction(target.parent);
        //已经成功的方块要拒绝掉
        // if (this.checkSuccess(target, data)) return;
        target.parent = this.node;
        // target.setPosition(AP);
        this.setTouchPos(e);
    }
    onItemTouchMove(e) {
        if (!this.isClick) return;
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        this.setTouchPos(e);
    }
    async onItemTouchEnd(e) {
        if (!this.isClick) return;
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        let itemBg = this.wordItams.find((bg) => {
            // let dis = this.getDistances(target.getPosition(), bg.getPosition());
            let dis = this.getDistances(target, bg);
            // if (dis < 100 && bg.sortId == data.id) {
            if (dis < 150 && data.text == bg.data) {
                return bg;
            }
            return null;
        })
        target.parent = data.parent;
        target.setPosition(data.startPos);
        target.active = false;

        if (!itemBg) {
            this.playLocalAudio("error");
            target.active = true;
            // this.floatForeverAction(target.parent);
            return
        }
        if (data.text != itemBg.data) {
            this.playLocalAudio("error");
            target.parent = data.parent;
            target.active = true;
            return;
        }
        this.playLocalAudio("right");

        cc.Tween.stopAllByTarget(data.parent);
        // data.parent.setPosition(data.parentPos);


        let word = cc.find("word", itemBg);
        word.active = true;
        word.getComponent(cc.Label).string = data.text;
        let pic_light = cc.find("pic_light", itemBg);
        let layer_candy = cc.find("layer_candy", itemBg);
        pic_light.active = true;
        layer_candy.active = true;
        if (itemBg.name == "item3") {
            let box1 = cc.find("box1", itemBg);
            let box = cc.find("box", itemBg);
            box1.active = true;
            box.active = false;
        }
        if (this.checkIsEnd()) {
            if (Game.getIns().getCurrentPage().wordArr.length > 5) {
                cc.find("box_up", this.layout_game).active = true;
                cc.find("box_up", this.layout_game).width = this.layout_up.width;
                this.layout_up.getComponent(cc.Sprite).enabled = false;
                this.layout_up.children.forEach((ch) => {
                    let word = cc.find("word", ch);
                    word.color = new cc.Color(255, 255, 255);
                })
            }
            await asyncDelay(1);
            this.playOpAudio();
        }

    }
    private checkIsEnd() {
        let count = 0;
        this.layout_down.children.forEach((ch) => {
            let card = cc.find("card", ch);
            if (!card.active) count++;
        })
        return count >= this.layout_down.children.length;
    }


    private floatAction(target) {
        cc.Tween.stopAllByTarget(target);
        let data = target.data;
        target.x = data.x;
        target.y = data.y;
        let y1 = target.y - 20;
        let y2 = target.y;
        cc.tween(target).to(0.15, { y: y1 }).to(0.3, { y: y2 }).start();

    }


    //根据两点获取距离
    private getDistance(p1, p2) {
        let temp = p1.sub(p2);
        let dis = Math.abs(temp.mag());
        return dis;
    }
    private getDistances(p1, p2) {
        //转换世界坐标查看距离
        let ps2 = p2.convertToWorldSpaceAR(cc.v2(0, 0));
        let ps1 = p1.convertToWorldSpaceAR(cc.v2(0, 0));
        let temp = ps1.sub(ps2);
        let dis = Math.abs(temp.mag());
        return dis;
    }




    private roundEnd() {


    }


    update(dt) {

    }

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



    async showOneFirework(pos, parentNode, nodeList) {

        for (let i = 0; i < 3; i++) {
            this.showFirework(pos, parentNode, nodeList, 200, 200, 25);
            await asyncDelay(0.1);
        }
    }

    showFirework(pos, parentNode, nodeList, width = 200, height = 500, number = 30) {
        for (let i = 0; i < number; i++) {
            const quad = this.createQuads(pos, parentNode, nodeList);
            const targetX = RandomInt(width / 2, -width / 2);
            const targetY = RandomInt(height);

            cc.tween(quad)
                .by(0.5, { x: targetX })
                .by(3, { x: targetX * 2 })
                .start();

            cc.tween(quad)
                .by(0.5, { y: targetY }, { easing: 'quadOut' })
                .to(4, { y: -parentNode.height * 2 }, { easing: 'quadIn' })
                .removeSelf()
                .start();

            cc.tween(quad)
                .delay(1)
                .to(0.5 + 1 * Math.random(), { opacity: 0 })
                .start();
        }
    }

    createQuads(pos, parentNode, nodeList) {
        const quadBase = cc.instantiate(nodeList[RandomInt(nodeList.length)]);
        // console.log('nodeList', nodeList);
        // console.log('quadBase', quadBase);
        quadBase.x = pos.x;
        quadBase.y = pos.y + 30;
        quadBase.z = pos.z;
        quadBase.angle = RandomInt(180);
        quadBase.parent = parentNode;

        const quad = quadBase.getChildByName('quad');
        quad.x = 0;
        quad.y = 0;
        quad.angle = RandomInt(180);

        const paper = quad.getChildByName('paper');
        paper.scaleX = Math.random() * 0.8 + 0.2;
        paper.scaleY = Math.random() * 0.8 + 0.2;

        quadBase.scaleX = Math.random();
        cc.tween(quadBase)
            .to((1 - quadBase.scaleX) * 0.3, { scaleX: 1 })
            .call(() => {
                const time = Math.random() * 0.2;
                cc.tween(quadBase)
                    .to(0.1 + time, { scaleX: -1 })
                    .to(0.1 + time, { scaleX: 1 })
                    .union()
                    .repeatForever()
                    .start();
            })
            .start();


        return quadBase;
    }
}





