import { asyncDelay, onHomeworkFinish } from "../script/util_hy04_pinci";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent_hy04_pinci";
import pg from "./pg_hy04_pinci";
import ImgVoice from "./ImgVoice_hy04_pinci";
import Candy from "./hy01_candy_hy04_pinci";
// 空格问题
// 尺寸大小问题

const { ccclass, property } = cc._decorator;
enum WORD_TYPE {
    TOUCH,
    LINE
}
const DefaultPos = {
    Word: cc.v2(0, -430),
    WordBg: cc.v2(0, -160)
}
@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 根据自己的配置预加载音频资源
        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) audios.push(obj[idx]);
                }
            }
        }
        checkAudio(this.data)
        this._audioResList = audios;
    }

    addPreloadAnima() {

    }

    async onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initEvent();
        this.showWordInit();
        pg.event.once('npc_voice_play_voice_end', () => {
            this.showWordStart();
        })
        pg.event.emit('npc_layer_back_init', this.data)

    }
    protected onDestroy(): void {
        pg.event.clear();
    }
    // 一轮单词数量
    @property(cc.Node)
    private upper_shadow: cc.Node = null;
    @property(cc.Node)
    private lower_shadow: cc.Node = null;
    @property(cc.Node)
    private lower_word: cc.Node = null;
    @property(cc.Node)
    private upper_word: cc.Node = null;
    @property(cc.Node)
    private word_area: cc.Node;

    _cantouch = null;
    private list: Array<{ type, text, right, imgage, duration, content, audio }>;
    private recordFlag: boolean;//录音模式
    // 单词列表
    private wordDataList: Array<any>;
    // 当前第几个
    private curIndex: number;
    initData() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        let data = this.data;
        this.recordFlag = data.recordFlag;
        this.list = data.questions[0].options;
        this.layers = [];
        this.curIndex = 0;

        this.wordDataList = data.questions.map(question => {
            let arr = question.letterList.map((letter, i) => {
                letter.group = i;
                return letter;
            })
            return {
                img: question.image,
                audio: question.audio,
                type: question.type,// img
                answerArr: arr,
                answerRand: arr.concat().sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5).sort(() => Math.random() - 0.5)
                    .sort(() => Math.random() - 0.5)
            }
        })
        console.log(data);
    }

    private layer_word: cc.Node;
    private layers: Array<cc.Node>;
    private res_audio: cc.Node;
    initView() {
        this.layer_word = pg.view.find(this, 'layer_word')
        this.res_audio = pg.view.find(this, "res/audio")
    }
    initEvent() {
    }
    resetView() {

    }

    replay() {
        this.initData();
        this.resetView();
        this.showWord();
    }
    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() {
        this.sendData(this.wordDataList.length * 3).then(() => {
            this.onDestroy();
            const middleLayer = cc.find('middleLayer');
            if (!middleLayer) return;
            const middleLayerComponent = middleLayer.getComponent('middleLayer');
            middleLayerComponent.saveGolds(this.wordDataList.length * 3); // 保存金币数量；num 是获得金币的数量，数字类型；
            middleLayerComponent.goNextPage();  // 跳转到下一页
        })
        // pg.event.once('layer_ending_touch_replay', () => {
        //     this.replay();
        // })
        // pg.event.emit('layer_ending_show', { coin: this.wordDataList.length * 3 })
    }

    private wordBgList: Array<cc.Node>;
    private wordList: Array<cc.Node>;
    private get CurrentWord(): any {
        // 默认播放当前音频
        // let audio_url = this.wordDataList[this.curIndex].audio
        // if (audio_url) pg.audio.playAudioByUrl(audio_url)
        return this.wordDataList[this.curIndex];
    }
    nextWord() {
        let success = true;
        for (let idx in this.successGroupIds) {
            if (!this.successGroupIds[idx]) success = false;
        }
        if (!success) return;
        this.scheduleOnce(() => {
            pg.event.once('layer_right_show_excellent_end', () => {
                pg.event.once('layer_coin_show_coin_end', () => {
                    this.curIndex++;
                    if (!this.CurrentWord) {
                        // alert("游戏结束画面暂无")
                        this.gameOver();
                    } else {
                        this.showWord();
                    }
                })  // 动画回调
                pg.event.emit('layer_coin_show_coin', 3)   //1 2 3硬币数量
            })
            pg.event.emit('layer_right_show_excellent')
        }, 0.2)
    }
    //单词的展示
    showWord() {
        this.wordBgList = [];
        this.wordList = [];
        this.successGroupIds = {};
        pg.view.removChildren(this.word_area)
        this.initWordBg();
        this.initWord();
        this.initQuestion();
        this.initQuestionVoice();
    }
    showWordInit() {
        this.wordBgList = [];
        this.wordList = [];
        this.successGroupIds = {};
        pg.view.removChildren(this.word_area)
        this.initWordBg();
        this.initWord();
        this.initQuestion();
    }
    showWordStart() {
        this.initQuestionVoice();
    }
    private layer_question: cc.Node;
    initQuestion() {
        this.layer_question = pg.view.find(this, 'layer_question');
        let img = pg.view.find(this.layer_question, 'img');
        img.active = true;
        pg.view.setNetImg(img, this.CurrentWord.img, { w: 730, h: 400 })

        let img_voice = pg.view.find(this.layer_question, 'img_voice');
        img_voice.active = this.CurrentWord.type != "img";
        if (img_voice.active) {
            pg.view.touchOn(img_voice, this.onTouchVoice, this);
        }
    }
    initQuestionVoice() {
        let img_voice = pg.view.find(this.layer_question, 'img_voice');
        if (img_voice.active) {
            this.onTouchVoice({ target: img_voice });
        }
    }
    private audioId;
    onTouchVoice(e) {
        let item = e.target;
        if (this.audioId) {
            item.getComponent(ImgVoice).playVoiceEnd();
            pg.audio.stopAudio(this.audioId)
            this.audioId = null;
        } else {
            item.getComponent(ImgVoice).playVoiceStart();
            pg.audio.playAudioByUrl(this.CurrentWord.audio, () => {
                item.getComponent(ImgVoice).playVoiceEnd();
                this.audioId = null;
            }, (audioId) => {
                this.audioId = audioId;
            })
        }
    }
    initWordBg() {
        let ansArr = this.CurrentWord.answerArr;
        let count = -1;
        // 长度大于一需要做拆分
        let scale = 1;
        ansArr.forEach((ansObj, i) => {
            let ans = ansObj.text;
            let group = ansObj.group;
            // 长度大于一需要做拆分

            let ansStrArr = ans.split('');
            ansStrArr.forEach((str, m) => {
                count++;
                let child = this.getWordBgNodeByStr(str, scale);
                child.data = { count: count, group: group, index: m, value: str }
                this.successGroupIds[`${i}`] = !str.trim();
                let pos = this.getWordBgPosByAns(ansArr.map(ans => ans.text), [str], child.data)
                child.x = pos.x;
                child.y = pos.y;
                this.wordBgList.push(child);
                pg.view.addChild(this.word_area, child)
            })
        });
    }
    getScale() {
        let ansArr = this.CurrentWord.answerRand;
        let scale = 1;
        let allWord = "";
        ansArr.forEach(ar => {
            allWord += ar.text
        })
        if (allWord.length > 8) {
            scale = 1 - (allWord.length - 8) * 0.1;
            scale = Math.max(scale, 0.5);
        }
        return scale;
    }
    initWord() {
        let ansArr = this.CurrentWord.answerRand;
        ansArr = ansArr.filter(ans => !!ans.text.trim());
        let itemPrefab = pg.view.find(this.layer_word, 'item');
        let count = -1;

        // 长度大于一需要做拆分
        this.word_area.scale = this.getScale();

        ansArr.forEach((ansObj) => {
            let ans = ansObj.text;
            ans = ans.trim();
            let group = ansObj.group;
            let ansStrArr = ans.split('');
            // 利用单一节点存储多字母
            // 依据字符长度做不同的处理
            let itemClone = pg.view.clone(itemPrefab)
            let { pos, width } = this.getItemPosWidthByAns(ansArr.map(ans => ans.text), ansStrArr, count + 1);
            itemClone.x = pos.x;
            itemClone.y = pos.y;
            itemClone.orgPos = cc.v2(pos);
            itemClone.active = true;
            itemClone.width = width;
            pg.view.addChild(this.word_area, itemClone);
            itemClone.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
            itemClone.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
            itemClone.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
            let arr = [];
            ansStrArr.forEach((str, m) => {
                count++;
                let child = this.getWordNodeByStr(str, 1);
                child.data = { group: group, index: m, count: count, value: str };
                let pos = this.getWordPosByAns(ansArr.map(ans => ans.text), [str], child.data);
                child.x = pos.x;
                child.y = pos.y;
                this.wordList.push(child)
                pg.view.addChild(this.word_area, child)
                arr.push(child)
            })
            itemClone.data = arr;
            // 计算ansStrArr的最终宽度
        });
    }


    getItemPosWidthByAns(ansArr, itemAnsArr, count) {
        //根据总长度计算出需要预留的空间大小
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.TOUCH, ansArr, DefaultPos.Word);
        let itemWidth = this.getItemWordWidth(WORD_TYPE.TOUCH, itemAnsArr);
        let leftWidth = this.getLeftWidthByCount(WORD_TYPE.TOUCH, ansArr, count);
        // 计算当前是第几个
        let pos = cc.v2(0, 0);
        pos.x = orgPos.x + leftWidth + itemWidth / 2;
        pos.y = orgPos.y;
        if (itemAnsArr.length > 0) {
            // pos.x += itemWidth / 2 - singleWordWidth / 2;
        }
        return { pos: pos, width: 200 };//itemWidth
    }
    getWordPosByAns(ansArr, itemAnsArr, data) {
        //根据总长度计算出需要预留的空间大小
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.TOUCH, ansArr, DefaultPos.Word);
        let itemWidth = this.getItemWordWidth(WORD_TYPE.TOUCH, itemAnsArr);
        let count = data.count;
        let leftWidth = this.getLeftWidthByCount(WORD_TYPE.TOUCH, ansArr, count);
        // 计算当前是第几个
        let pos = cc.v2(0, 0);
        pos.x = orgPos.x + leftWidth + itemWidth / 2;
        pos.y = orgPos.y;
        return pos;
    }
    getWordBgPosByAns(ansArr, itemAnsArr, data) {
        //根据总长度计算出需要预留的空间大小
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.LINE, ansArr, DefaultPos.WordBg);
        let itemWidth = this.getItemWordWidth(WORD_TYPE.LINE, itemAnsArr);
        // 计算当前是第几个
        let count = data.count;
        let leftWidth = this.getLeftWidthByCount(WORD_TYPE.LINE, ansArr, count);
        let pos = cc.v2(0, 0);
        pos.x = orgPos.x + leftWidth + itemWidth / 2;
        pos.y = orgPos.y;
        return pos;
    }






    getTotalWordOrgPos(type: WORD_TYPE, ansArr, defaultPos) {
        let wordStr = ansArr.join('')
        let totalWordWidth = 0;
        wordStr.split('').forEach((s) => {
            let w = this.getWordNodeWidth(type, s);
            totalWordWidth += w;
        })
        let orgPos = cc.v2(-totalWordWidth / 2 + defaultPos.x, defaultPos.y);
        return orgPos
    }
    getItemWordWidth(type: WORD_TYPE, ansArr) {
        let wordStr = ansArr.join('')
        let totalWordWidth = 0;
        wordStr.split('').forEach((s) => {
            let w = this.getWordNodeWidth(type, s);
            totalWordWidth += w;
        })
        return totalWordWidth;
    }
    getLeftWidthByCount(type: WORD_TYPE, ansArr, count) {
        let wordStr = ansArr.join('')
        let totalWordWidth = 0;
        wordStr.split('').forEach((s, i) => {
            let w = this.getWordNodeWidth(type, s);
            if (i >= count) return;
            totalWordWidth += w;
        })
        return totalWordWidth;
    }

    getWordNodeWidth(type, str) {
        // str = str.trim();
        // // if (!str) return 0;
        // const reg = /^[A-Z]+$/;
        // const lower = str;//str.toLowerCase()
        // if (type === WORD_TYPE.TOUCH) {
        //     let prefabNode = reg.test(str) ? pg.view.find(this.upper_word, `${lower}`) : pg.view.find(this.lower_word, `${lower}`)
        //     return prefabNode.width + 20;
        // } else {
        //     let prefabNode = reg.test(str) ? pg.view.find(this.upper_shadow, `${lower}`) : pg.view.find(this.lower_shadow, `${lower}`);
        //     return prefabNode.width + 30;
        // }
        return 170;
    }
    getWordNodeByStr(str, scale) {
        str = str.trim();
        const reg = /^[A-Z]+$/;
        const lower = str;//str.toLowerCase()
        let wordNode = pg.view.find(this.layer_word, 'word');
        let item = pg.view.clone(wordNode);
        let prefabNode = reg.test(str) ? pg.view.find(this.upper_word, `${lower}`) : pg.view.find(this.lower_word, `${lower}`)
        let child = pg.view.clone(prefabNode)
        child.x = 0;
        child.y = 0;
        child.width *= scale;
        child.height *= scale;
        child.active = true;
        let width = this.getItemWordWidth(WORD_TYPE.TOUCH, [str])
        item.x = 0;
        item.y = 0;
        item.width = width;
        item.width *= scale;
        item.height *= scale;
        item.active = true;
        item.getChildByName("icon").addChild(child);
        return item;
    }
    getWordBgNodeByStr(str, scale) {
        str = str.trim();
        const reg = /^[A-Z]+$/;
        const lower = str;//str.toLowerCase()
        let prefabNode = reg.test(str) ? pg.view.find(this.upper_shadow, `${lower}`) : pg.view.find(this.lower_shadow, `${lower}`);
        let child = pg.view.clone(prefabNode)
        child.opacity = 100;
        child.active = true
        child.x = 0;
        child.y = 0;
        child.width *= scale;
        child.height *= scale;
        return child;
    }
    getWordBgByGroup(group) {
        return this.wordBgList.filter(item => {
            return item.data.group == group
        })
    }
    collider(node) {
        // 每个字母
        let worldPos = cc.v2(node.x, node.y);

        let groups = {};
        this.wordBgList.forEach(word => {
            let group = `${word.data.group}`;
            if (group) {
                if (!groups[`${group}`]) groups[`${group}`] = []
                groups[`${group}`].push(word);
                groups[`${group}`].sort((A, B) => {
                    return A.x - B.x;
                })
            }
        })
        let groupId = null;
        for (let idx in groups) {
            let groupNodeList = groups[idx];
            let left = groupNodeList[0];
            let right = groupNodeList[groupNodeList.length - 1];
            let maxX = right.x + right.width / 2;
            let minX = left.x - left.width / 2;
            let maxY = left.y + left.width / 2;
            let minY = left.y - left.width / 2;
            if (worldPos.x < maxX && worldPos.x > minX && worldPos.y < maxY && worldPos.y > minY) {
                groupId = Number(idx);
            }
        }
        return groupId;
    }

    private currentItem: cc.Node;
    onTouchStart(event) {
        console.log('1')
        let node = event.target;
        this.currentItem = node;
        this.startCurrentItemAni();
    }
    onTouchMove(event) {
        let node = event.target;
        node.opacity = 255;
        let delta = event.touch.getDelta();
        let pos = cc.v2(delta);
        let scale = this.getScale();
        pos.x /= scale;
        pos.y /= scale;
        node.x += pos.x;
        node.y += pos.y;
        node.data.forEach(nd => {
            nd.x += pos.x;
            nd.y += pos.y;
        })
    }
    private successGroupIds;
    onTouchEnd(event) {
        let node = event.target;
        this.stopCurrentItemAni();
        this.currentItem = null;
        // 跟字母区域进行碰撞检测
        let groupId = this.collider(node);
        let colliderList = this.getWordBgByGroup(groupId);
        let colliderStr = '';
        if (colliderList) {
            colliderList.forEach(nd => {
                colliderStr += nd.data.value;
            })
        }
        let str = "";
        node.data.forEach(nd => {
            str += nd.data.value;
        })
        // 获取当前待碰撞区域
        if ((groupId || groupId == 0) && !this.successGroupIds[`${groupId}`] && (node.data[0].data.group == groupId || str == colliderStr)) {
            console.log(groupId)
            // 正确了 需要处理效果
            pg.audio.playLocalAudio(pg.view.find(this.res_audio, "right"))
            let nodes = node.data;
            let targets = this.getWordBgByGroup(groupId);
            nodes.forEach(item => {
                let dt = item.data;
                let target = targets.find(tr => tr.data.index == item.data.index);
                this.wordToWordBg(item, target);
            })
            this.successGroupIds[`${groupId}`] = true;
            node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
            node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
            node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
            this.nextWord();
        } else {
            pg.audio.playLocalAudio(pg.view.find(this.res_audio, "fail"))
            let subX = node.x - node.orgPos.x;
            let subY = node.y - node.orgPos.y;
            node.x -= subX;
            node.y -= subY;
            node.data.forEach(nd => {
                nd.x -= subX;
                nd.y -= subY;
            })
        }
    }
    wordToWordBg(node, target) {
        let light = pg.view.find(node, 'light');
        let candys = pg.view.find(node, 'candys');
        light.active = true;
        candys.getComponent(Candy).showAni().then(() => {
            cc.tween(light).to(1, { opacity: 0 }).start();
        })
        cc.tween(node).to(0.2, { x: target.x, y: target.y, scale: 0.85 })
            .call(() => {
                target.active = false;
            }).start();
    }
    startCurrentItemAni() {
        let childs = this.currentItem.data;
        childs.forEach(child => {
            cc.tween(child).to(0.15, { scaleX: 1.1, scaleY: 0.9 }).to(0.15, { scaleX: 1, scaleY: 1 }).delay(0.25).union().repeatForever().start();
        })
    }
    stopCurrentItemAni() {
        let childs = this.currentItem.data;
        childs.forEach(child => {
            cc.Tween.stopAllByTarget(child)
        })
    }

    getBgNodeByGroupIndex(group, index) {
        let groupNode = this.wordBgList.find(node => {
            return node.data.group == group && node.data.index == index;
        })
        return groupNode;
    }
    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);
            });
        })
    }
}
// 重构方案
// 1.所有坐标均为计算得到不适用group
// 2.关联内容，在touch的时候同步运动
// 3.图片的点击区域，需要套在一个item里面，item的宽度是固定的，用于处理间隔问题。
// 4.在同一坐标系下，所有的节点均可以直接运动到指定的位置。

// 方案2
// 目前方案不变。
// 增加补丁
// 1.显示字母手动计算 零散的分布
// 2.touchmove的时候获取关联字母
// 3.关联字母跟随目前的touch走。


