import { asyncDelay, onHomeworkFinish } from "../script/util_hy04_pinci";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent_hy04_pinci";
import pg from "./pg_hy04_pinci";

const { ccclass, property } = cc._decorator;
enum WORD_TYPE {
    TOUCH,
    LINE
}
@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() {

    }

    async onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initListener();
        this.initEvent()
    }
    // 一轮单词数量
    private static Word_List_Len: number = 8;

    private word_area: cc.Node;
    private upper_shadow: cc.Node;
    private lower_shadow: cc.Node;
    private lower_word: cc.Node;
    private upper_word: cc.Node;

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

        this.wordDataList = data.questions.map(question => {
            return {
                img: question.image,
                audio: question.audio,
                type: question.type,// img
                answer: question.letterList.map(letter => letter.text)
            }
        })
        console.log(data);
    }

    private layer_record: cc.Node;
    private layer_word: cc.Node;
    private layers: Array<cc.Node>;
    initView() {
        this.layer_record = pg.view.find(this, 'layer_record')
        this.layer_word = pg.view.find(this, 'layer_word')

        this.word_area = pg.view.find(this.layer_word, "word_area");
        this.layer_back = pg.view.find(this, "layer_back");

        this.back_board = pg.view.find(this.layer_back, "board");


        this.upper_shadow = pg.view.find(this.layer_word, "upper_shadow");
        this.lower_shadow = pg.view.find(this.layer_word, "lower_shadow");
        this.upper_word = pg.view.find(this.layer_word, "upper_word");
        this.lower_word = pg.view.find(this.layer_word, "lower_word");


        this.showWord()
    }

    initListener() {

    }

    initEvent() {
        pg.view.touchOn(this.back_board, this.checkIsRight, this)
    }

    // 校验是否正确
    checkIsRight() {
        console.log(this.curIndex + 1 < SceneComponent.Word_List_Len);

        if ((this.curIndex + 1) < SceneComponent.Word_List_Len) {
            this.curIndex++
            this.showWord()
        }

    }



    private wordBgList: Array<cc.Node>;
    private wordList: Array<cc.Node>;
    private get CurrentWord(): any {
        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', () => {
                this.curIndex++;
                if (!this.CurrentWord) {
                    alert("游戏结束画面暂无")
                } else {
                    this.showWord();
                }
            })
            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();
    }
    private layer_question: cc.Node;
    initQuestion() {
        this.layer_question = pg.view.find(this, 'layer_question');
        let img = pg.view.find(this.layer_question, 'img');
        pg.view.setNetImg(img, this.CurrentWord.img, { w: 230, h: 230 })

        let img_voice = pg.view.find(this.layer_question, 'img_voice');
        img_voice.active = this.CurrentWord.type != "img";

        pg.view.touchOn(img_voice, this.onTouchVoice, this);
    }
    private audioId;
    onTouchVoice() {
        if (this.audioId) {
            pg.event.emit('img_voice_play_voice_end')
            pg.audio.stopAudio(this.audioId)
            this.audioId = null;
        } else {
            pg.event.emit('img_voice_play_voice_start')
            pg.audio.playAudioByUrl(this.CurrentWord.audio, () => {
                pg.event.emit('img_voice_play_voice_end')
                this.audioId = null;
            }, (audioId) => {
                this.audioId = audioId;
            })
        }
    }
    initWordBg() {
        let ansArr = this.CurrentWord.answer;
        let count = -1;
        ansArr.forEach((ans, i) => {
            // 长度大于一需要做拆分
            let ansStrArr = ans.split('');
            ansStrArr.forEach((str, m) => {
                count++;
                let child = this.getWordBgNodeByStr(str);
                child.data = { count: count, group: i, index: m }
                this.successGroupIds[`${i}`] = false;
                let pos = this.getWordBgPosByAns(ansArr, [str], child.data)
                child.x = pos.x;
                child.y = pos.y;
                this.wordBgList.push(child);
                pg.view.addChild(this.word_area, child)
            })
        });
    }
    initWord() {
        let ansArr = this.CurrentWord.answer;
        let itemPrefab = pg.view.find(this.layer_word, 'item');
        let count = -1;
        ansArr.forEach((ans, i) => {
            let ansStrArr = ans.split('');
            // 利用单一节点存储多字母
            // 依据字符长度做不同的处理
            let itemClone = pg.view.clone(itemPrefab)
            let { pos, width } = this.getItemPosWidthByAns(ansArr, 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);
                child.data = { group: i, index: m, count: count };
                let pos = this.getWordPosByAns(ansArr, [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 defaultPos = cc.v2(0, -300);
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.TOUCH, ansArr, defaultPos);
        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: itemWidth };
    }
    getWordPosByAns(ansArr, itemAnsArr, data) {
        //根据总长度计算出需要预留的空间大小
        let defaultPos = cc.v2(0, -300);
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.TOUCH, ansArr, defaultPos);
        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 defaultPos = cc.v2(0, 60);
        let orgPos = this.getTotalWordOrgPos(WORD_TYPE.LINE, ansArr, defaultPos);
        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) {
        const reg = /^[A-Z]+$/;
        const lower = str.toLowerCase()
        if (type === WORD_TYPE.TOUCH) {
            let prefabNode = reg.test(str) ? pg.view.find(this.upper_word, `${lower}2`) : pg.view.find(this.lower_word, `${lower}`)
            return prefabNode.width + 20;
        } else {
            let prefabNode = reg.test(str) ? pg.view.find(this.upper_shadow, `${lower}2_di`) : pg.view.find(this.lower_shadow, `${lower}_di`);
            return prefabNode.width + 30;
        }
    }
    getWordNodeByStr(str) {
        const reg = /^[A-Z]+$/;
        const lower = str.toLowerCase()
        let prefabNode = reg.test(str) ? pg.view.find(this.upper_word, `${lower}2`) : pg.view.find(this.lower_word, `${lower}`)
        let child = pg.view.clone(prefabNode)
        child.x = 0;
        child.y = 0;
        child.active = true;
        return child;
    }
    getWordBgNodeByStr(str) {
        const reg = /^[A-Z]+$/;
        const lower = str.toLowerCase()
        let prefabNode = reg.test(str) ? pg.view.find(this.upper_shadow, `${lower}2_di`) : pg.view.find(this.lower_shadow, `${lower}_di`);
        let child = pg.view.clone(prefabNode)
        child.active = true
        child.x = 0;
        child.y = 0;
        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();
        node.x += delta.x;
        node.y += delta.y;
        node.data.forEach(nd => {
            nd.x += delta.x;
            nd.y += delta.y;
        })
    }
    private successGroupIds;
    onTouchEnd(event) {
        let node = event.target;
        this.stopCurrentItemAni();
        this.currentItem = null;
        // 跟字母区域进行碰撞检测
        let groupId = this.collider(node);
        // 获取当前待碰撞区域
        if ((groupId || groupId == 0) && node.data[0].data.group == groupId) {
            console.log(groupId)
            // 正确了 需要处理效果
            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 {
            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) {
        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走。

