import { asyncDelay, exchangeNodePos, getSprNode, onHomeworkFinish, onHomeworkStart, playAudio } from "../script/util_hy05_pintu";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent_hy05_pintu";
import GameJigsaw, { imageZize, Item, Option } from "./Gamehy05_pintu";
import pg from "./pg_hy05_pintu";

const { ccclass, property } = cc._decorator;

@ccclass
export default class PuzzleJigsaw extends MyCocosSceneComponent {

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

    addPreloadAudio() {
        // TODO 根据自己的配置预加载音频资源
        let audios = [];
        function checkAudio(obj) {
            for (let idx in obj) {
                if (typeof obj[idx] == "object") {
                    checkAudio(obj[idx]);
                } else if (typeof obj[idx] == "string") {
                    if (obj[idx].indexOf(".mp3") > -1 && obj[idx].indexOf("http") > -1) audios.push(obj[idx]);
                }
            }
        }
        checkAudio(this.data)
        this._audioResList = audios;
    }

    addPreloadAnima() {

    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initEvent();
        this.initListener();
    }
    @property(cc.Node)
    layout_sort: cc.Node = null;

    @property(cc.Node)
    right_layout: cc.Node = null;

    @property(cc.Node)
    node_card: cc.Node = null;

    @property(cc.Node)
    sort_card: cc.Node = null;

    @property(cc.Node)
    img_bg: cc.Node = null;



    @property(cc.Node)
    btn_up: cc.Node = null;

    @property(cc.Node)
    btn_down: cc.Node = null;

    private coin: number;
    initData() {
        GameJigsaw.getIns().init(this.data);
        GameJigsaw.getIns().reset();
        this.cardBgs = [];
        this.coin = 0;
        this.roundOver = false;
    }
    initView() {

        this.flyAction();
        this.startGame();
    }
    initEvent() {

        pg.view.touchOn(this.btn_up, this.onScUp, this);
        pg.view.touchOn(this.btn_down, this.onScDown, this);

        pg.event.on("gameOver", () => { this.gameOver() })
        cc.find("rightSc", this.node).on("scroll-ended-with-threshold", this.scrollEnd, this);
    }
    private initListener() {

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

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

        })
        pg.event.on('layer_right_show_excellent_end', () => {
            this.coin += 3;
            pg.event.emit('layer_coin_show_coin', 3)   //1 2 3硬币数量
            this.roundOver = false;
        })
        pg.event.emit('npc_layer_back_init', this.data)


        pg.event.on('layer_ending_touch_replay', () => {
            this.replay();
        })
        pg.event.on('layer_coin_show_coin_end', () => {
            let over = GameJigsaw.getIns().addPage();
            if (!over) {
                this.gameOver();
            } else {
                this.nextPage();
            }
        })
    }
    replay() {
        this.initData();
        this.initView();
        this.initEvent();
    }
    protected update(dt: number): void {
        if (!this.node || !this.node.active) return;
        if (!this.btn_down || !this.btn_up) return;
        if (this.btn_down.active || this.btn_up.active) return;
        if (!this.right_layout || this.right_layout.height < 450) return;
        this.updataArrow();
    }
    private updataArrow() {
        let height = this.right_layout.height;
        this.btn_up.active = height > 450;
        this.btn_down.active = height > 450;
    }


    private scrollEnd(e) {
        let rightSc = cc.find("rightSc", this.node).getComponent(cc.ScrollView);
        let off = rightSc.getScrollOffset();
        let maxOff = rightSc.getMaxScrollOffset();
        this.btn_up.getComponent(cc.Button).interactable = off.y > 5;
        this.btn_down.getComponent(cc.Button).interactable = off.y < maxOff.y - 5;
    }
    private onScUp() {
        let rightSc = cc.find("rightSc", this.node).getComponent(cc.ScrollView);
        let off = rightSc.getScrollOffset();
        rightSc.scrollToOffset(cc.v2(0, off.y - 258), 0.5);
    }
    private onScDown() {
        let rightSc = cc.find("rightSc", this.node).getComponent(cc.ScrollView);
        let off = rightSc.getScrollOffset();
        rightSc.scrollToOffset(cc.v2(0, off.y + 258), 0.5);
    }


    //根据两点获取距离
    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 rectCollect(A, B) {
        let AP = A.convertToWorldSpaceAR(cc.v2(0, 0));
        let BP = B.convertToWorldSpaceAR(cc.v2(0, 0));
        if (Math.abs(AP.x - BP.x) < A.width + B.width
            && Math.abs(AP.y - BP.y) < A.height + B.height) return true;
        return false;
    }

    private currentCards: cc.Node[];
    //开始游戏
    startGame() {
        this.nextPage();
    }
    nextPage() {
        this.checked = false;
        this.cards = [];
        this.currentCards = [];
        this.cardBgs = [];
        let data = GameJigsaw.getIns().getCurrentPage();
        //自动创建卡片
        this.right_layout.active = true;
        this.createCrads(data);
        pg.view.setNetImg(this.img_bg, data.image, { w: imageZize.width, h: imageZize.height });
    }
    //创建卡片
    private cards: cc.Node[];
    private cardBgs: cc.Node[];
    createCrads(data: Item) {
        this.right_layout.removeAllChildren();
        // this.cleanLayoutSort();
        this.layout_sort.removeAllChildren();

        let count = 0;
        data.hotZoneItemArr.forEach((li, idx) => {
            let item = cc.instantiate(this.node_card);
            this.right_layout.addChild(item);
            li.count = count;
            this.initTopCard(item, li, idx);
            count++;
        })
        count = 0;
        let pos = data.pointsArr;
        pos.forEach((li, idx) => {
            let item = cc.instantiate(this.sort_card);
            this.layout_sort.addChild(item);
            // let rightBg0 = cc.find("rightBg1", item);
            // rightBg0.active = true;
            item.x = li.x;
            item.y = li.y;
            item.active = true;
            item.sortId = idx;
            item.isChecked = false;
            this.cardBgs.push(item);
        })
    }
    private initTopCard(item, data, idx) {
        let img = cc.find("img", item);
        pg.view.setNetImg(img, data.picUrl, { w: 118, h: 118 }, false);
        img.x = idx % 2 == 0 ? -107 : 107
        item.active = true;
        item.y = 0;
        item.x = 0;
        img.data = data;
        img.data.pos = img.getPosition();
        item.data = data;
        img.scale = 0.9;
        img.on(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        img.on(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        img.on(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
        img.on(cc.Node.EventType.TOUCH_CANCEL, this.onItemTouchCancel, this);
        // item.on(cc.Node.EventType.TOUCH_END, this.onItem, this);
    }

    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)
        }
    }
    checkSuccess(target, data) {
        let itemBg = this.cardBgs.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 < 100 && cc.find("n/img", bg)) {
                return bg;
            }
            return null;
        })
        return itemBg && itemBg.sortId == data.id
    }
    onItemTouchStart(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        if (this.checkSuccess(target, data)) return;
        target.parent = this.node;
        target.scale = 1;
        this.setTouchPos(e);
        target.startPos = target.getPosition();
        // this.playLocalAudio("move");
    }
    onItemTouchMove(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        if (this.checkSuccess(target, data)) return;
        this.setTouchPos(e);
    }
    onItemTouchEnd(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        if (this.getDistance(target.startPos, target.getPosition()) < 30) {//&& target.parent.name != "Canvas"
            // this.onItem(e);
            target.parent = this.right_layout.children[data.count];
            target.setPosition(data.pos);
            // this.playLocalAudio("big");
            target.scale = 0.9;
            return;
        }
        //已经成功的方块要拒绝掉
        if (this.checkSuccess(target, data)) return;
        let itemBg = this.cardBgs.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 < 100 && !cc.find("img", bg)) {
                return bg;
            }
            return null;
        })
        //检测是否在区域内
        let isIn = this.rectCollect(target, this.layout_sort);
        if (!itemBg && !isIn) {
            target.parent = this.right_layout.children[data.count];
            target.setPosition(data.pos);
            // this.playLocalAudio("error");
            target.scale = 0.9;
            return;
        }
        if (itemBg && itemBg.sortId == data.id) {
            // let rightBg0 = cc.find("rightBg0", itemBg);
            // let rightBg1 = cc.find("rightBg1", itemBg);
            // rightBg0.active = true;
            // rightBg1.active = true;
            itemBg.isChecked = true;
            // setTimeout(() => {
            //     rightBg0.active = false;
            //     rightBg1.active = false;
            // }, 1000);
            //执行
            target.parent = itemBg.getChildByName("n");
            //每一个设置都要设置成中心点？
            target.setPosition(0, 0);//-target.parent.height / 2
            target.setAnchorPoint(0.5, 0.5)
            itemBg.getChildByName("layer_candy").active = true;
            // setTimeout(() => {
            //     itemBg.getChildByName("layer_candy").active = false;
            // }, 1000);

            this.playLocalAudio("right").then(() => {
                if (this.checkRoundEnd()) {
                    this.checkGameOver();
                }
            });
        } else {
            this.playLocalAudio("error");
        }
    }
    onItemTouchCancel(e) {
        let target: cc.Node = e.target;
        let data = target.data;
        target.parent = this.right_layout.children[data.count];
        target.setPosition(data.pos);
        // this.playLocalAudio("error");
        target.scale = 0.9;
    }
    private cleanLayoutSort() {
        this.cardBgs.forEach((item) => {
            let img = cc.find("img", item);
            if (img) {
                img.parent = null;
                img.destroy();
            }
        })
    }
    private checkRoundEnd() {
        let count = 0;
        this.cardBgs.forEach((item) => {
            if (item.isChecked) count++;
        })
        return count == this.cardBgs.length;
    }
    checked: boolean;
    checkFull() {
        if (!this.currentCards) return;
        if (!this.cards) return;
        if (this.currentCards.length != this.cards.length) return false;
        return this.currentCards.every(card => !!card);
    }
    private roundOver;
    private checkGameOver() {
        if (this.roundOver) return;
        this.roundOver = true;
        let audio = GameJigsaw.getIns().getCurrentPage().audio;
        pg.audio.playAudioByUrl(audio).then(async () => {
            await asyncDelay(0.5);
            pg.event.emit("layer_right_show_excellent");
        });
    }

    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,
            };
            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('');
            })
        })
    }

    gameOver() {
        // pg.event.emit('layer_ending_show', { coin: this.coin })
        const midd = cc.find('middleLayer');
        if (!midd) return this.log("no middleLayer");
        this.sendData(this.coin).then(()=>{
            let middleLayer = midd.getComponent('middleLayer');
            middleLayer.saveGolds(this.coin); // 保存金币数量；num 是获得金币的数量，数字类型；
            middleLayer.goNextPage();  // 跳转到下一页
        })
    }



    private flyAction() {
        let image_aircraft = cc.find("bg/image_aircraft", this.node);
        image_aircraft.setPosition(1200, 300);

        cc.tween(image_aircraft).repeatForever(cc.tween(image_aircraft).to(10, { x: 0, y: 50 }).to(10, { x: -1200, y: 300 })
            .call(() => {
                image_aircraft.setPosition(1200, 300);
            })).start();

    }


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




