import { _decorator, Component, Node, Prefab, instantiate, Vec3, tween, math, Game, UITransform, Tween, Label, UIOpacity} from 'cc';
import { Item } from './Item';
import { GameConstant } from './GameConstant';
import { GameScene } from './GameScene';
const { ccclass, property } = _decorator;

@ccclass('GameRollNode')
export class GameRollNode extends Component {
    @property(Prefab)
    item: Prefab = null;

    @property(Node)
    slotRollView: Node = null;

    @property(Node)
    rollSpine: Node = null;

    @property(Node)
    endNode: Node = null;

    @property(Node)
    winDetail: Node = null;

    @property(Node)
    winDetailIcons: Node = null;
    
    @property(Node)
    winDetailLabel: Node = null;

    public rollNodes = [];
    public rollNodeIcons = [];
    public resultRollNodes = [];
    public resultRollIcons = [];
    public resultValues = [];
    public resultIcons = [];
    public resultWildTimes = [];

    public tempValueIsHaveScatter = [];
    public rollBgIsScroll = [];
    public rollBgisStop = [];
    public isScroll = false;
    public startRollTime = 0;
    public isFast = false;
    public freeIconCount = 0;
    public isFastStop = false;
    public fastIndex = 0;
    public bGameEnd = true;
    public delayTime = 0;
    public bQuick = false;
    public hasSpecial = false;
    public isInScatterGame = false;

    public rollResultData = {
        "m_desk_data": [[2,2,2,2,2,2],[2,2,2,2,2,2],[2,2,2,2,2,2],[2,2,2,2,2,2]],
        "m_wildTimes_data": [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]],
        "m_isSpecialGame": 0,
        "m_freeCount": 0,
        "m_freeCountAdd": 0,
        "m_betIndex": 0,
        "m_lottery_size": 0,
        "m_lCurScore":0,
        "m_line_icon": [[2,2,2,2,2,2],[2,2,2,2,2],[2,2,2,2],[2,2,2]],
        "m_line_size": [6,5,4,3],
        "m_line_icon_active": [[1,1,1,1,1,1],[1,1,1,1,1],[1,1,1,1],[1,1,1]],
        "m_line_times": [500,500,500,500],
        "m_line_index": [[0,1,2,3,4,5],[6,7,8,9,10,11],[12,13,14,15,16,17],[18,19,20,21,22,23]],
    };

    start() {
        
        for (let i = 0; i < GameConstant.MAX_COL; i++) {
            this.rollNodes[i] = this.slotRollView.getChildByName("roll" + i);
            this.resultRollNodes[i] = this.slotRollView.getChildByName("result_roll" + i);
        }

        let itemHeight = 190;
        let iconIndex = 0;
        for (let i = 0; i < this.rollNodes.length; i++) {
            this.rollNodeIcons[i] = [];
            this.resultValues[i] = [];
            this.resultRollIcons[i] = [];
            this.resultWildTimes[i] = [];
            for (let j = 0; j < GameConstant.COL_ITEM_LEN; j++) {
                let item = instantiate(this.item);
                item.position = new Vec3(0, (GameConstant.COL_ITEM_LEN / 2 - 0.5 - j) * itemHeight, 0);
                item.parent = this.rollNodes[i];
                this.rollNodeIcons[i][j] = item;
                let iconType = j >= 11 ? 2 : (2 + j);

                let resultItem = instantiate(this.item);
                resultItem.position = new Vec3(0, (GameConstant.COL_ITEM_LEN / 2 - 0.5 - j) * itemHeight, 0);
                resultItem.parent = this.resultRollNodes[i];
                resultItem.getComponent(Item).setIconType(GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE), true);
                // resultItem.active = false;
                this.resultRollIcons[i][j] = resultItem;

                if (j >= 4 && j < 8) {
                    // this.resultValues[i][j - 4] = iconIndex++ % 13;//GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE);
                    this.resultValues[i][j - 4] = this.rollResultData.m_desk_data[j - 4][i];
                    resultItem.getComponent(Item).setIconType(this.resultValues[i][j - 4], true);
                }

                if (resultItem.getComponent(Item).getIconType() == GameConstant.ICON_TYPE.SYMBOL_WILD) {
                    this.resultWildTimes[i][j] = GameConstant.WILD_TIMES[GameConstant.getRandomNumber(0, 3)];
                }
            }
        }

        for (let i = 0; i < GameConstant.MAX_COL; i++) {
            this.resultIcons[i] = [];
            for (let j = 0; j < GameConstant.MAX_ROW; j++) {
                let resultItem = instantiate(this.item);
                resultItem.position = new Vec3(this.rollNodes[i].position.x, (GameConstant.MAX_ROW / 2 - 0.5 - j) * itemHeight, 0);
                resultItem.parent = this.endNode;
                resultItem.getComponent(Item).setIconType(this.resultValues[i][j], true);//
                this.resultIcons[i][j] = resultItem;
            }
        }
        // this.slotRollView.parent.scale = new Vec3(0.1,0.1,0.1);
        this.endNode.active = true;
    }

    // 展示结果图标
    showResultIcons(i) {
        this.endNode.active = true;
        this.resultRollNodes[i].active = false;
        for (let j = 0; j < GameConstant.MAX_ROW; j++) {
            this.resultIcons[i][j].active = true;
        }
    }

    // 重置展示结果的图标状态
    resetResultIcons() {
        console.log("resetResultIcons");
        this.endNode.active = false;
        for (let i = 0; i < GameConstant.MAX_COL; i++) {
            for (let j = 0; j < GameConstant.MAX_ROW; j++) {
                this.resultIcons[i][j].getComponent(Item).showNormal();
                this.resultIcons[i][j].active = false;
            }
        }
    }

    // 设置图标为模糊图片
    resetRollingItemValue(i) {
        for(let j = 0; j < GameConstant.COL_ITEM_LEN; ++j) {
            var randType = GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE)
            this.rollNodeIcons[i][j].getComponent(Item).setIconType(randType, false);
            this.resultRollIcons[i][j].getComponent(Item).setIconType(randType, false);
        }
    }

    // 开始转动函数
    startRollActions() {
        this.bGameEnd = false;

        // 停止结果细节的节点动作，并隐藏节点
        Tween.stopAllByTarget(this.winDetail);//.getComponent(UIOpacity)
        this.winDetail.active = false;
        Tween.stopAllByTarget(this.node);

        // 重置结果图标的状态
        this.resetResultIcons();

        // 重置转动状态参数
        for(let i = 0; i < GameConstant.MAX_COL; ++i) {
            this.tempValueIsHaveScatter[i] = false;
            this.rollBgIsScroll[i] = false;
            this.rollBgisStop[i] = false;
        }

        // 开始滚动
        for(let i = 0; i < GameConstant.MAX_COL; ++i) {
            let rollbg = this.resultRollNodes[i];
            
            // 展示滚动层，停止滚动层动作
            rollbg.active = true;
            Tween.stopAllByTarget(rollbg);
            this.rollNodes[i].y = rollbg.y + rollbg.getComponent(UITransform).height;

            // 开始转动前的上提动作
            tween(rollbg)
                .delay(0.1 * i)
                .by(0.2, {y: 60})
                .by(0.05, {y: -15})
                // .by(0.2, {y: 40}, {easing: 'sineOut'})
                // .by(0.2, {y: -20}, {easing: 'sineIn'})
                .call(()=>{
                    this.rollNodes[i].y += 60;

                    if (i == 0) {
                        this.isScroll = true;
                    }
                    this.rollBgIsScroll[i] = true;
                })
                .delay(0.05)
                .call(()=>{
                    this.resetRollingItemValue(i);
                })
                .start();
        }

        this.startRollTime = new Date().getTime();
    }

    // 每列转动结束的函数
    rollEnds(i) {
        if(i == 0) {
            this.node.parent.getComponent(GameScene).onGameEnd();
        }

        // 如果有两列有进入小游戏的特殊图标则快速转动
        let fastDelayTime = 0
        if(this.freeIconCount >= 2 && (i >= 3 && i < 6) && !this.isFastStop) {
            if (this.fastIndex != i) {
                this.fastIndex = i;
                this.isFast = true;
                fastDelayTime = 2;
                this.rollBgIsScroll[i] = true;
                this.rollSpine.x = this.rollNodes[i].x;
                this.rollSpine.active = true;

                var delayPlaySoundTime = i >= 3 ? 1.0 : 0.5;
                tween(this.node)
                    .delay(delayPlaySoundTime)
                    .call(()=>{
                        // this.playEffect(i == 3 ? "fast_1" : "fast_2");
                    })
                    .delay(fastDelayTime - delayPlaySoundTime)
                    .call(()=>{
                        this.rollBgisStop[i] = true;
                        this.isFastStop = i == 5;
                    })
                    .start();
    
                return;
            } else {
                //
            }
        }

        // 都停止了就展示结果
        if(i > 5) {
            this.isFast = false;
            this.isScroll = false;
            this.rollSpine.active = false;

            let delayTime = 200;
            this.delayShowPrizes(delayTime);
            return;
        }
        
        let isAppearScatter = false;
        //先统计Scatter数量
        for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
            if(this.resultValues[i][j] == GameConstant.SPECIAL_ICON) {
                this.freeIconCount++;
                isAppearScatter = true;
            }
        }

        // 现逻辑
        let resultRollbg = this.resultRollNodes[i];
        let destY = 0;

        // 修改当前列结果展示图标
        for (let j = 0; j < GameConstant.MAX_ROW; j++) {
            this.rollNodeIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], false);
            this.resultRollIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
            this.resultIcons[i][j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
        }
        this.resultRollIcons[i][3].getComponent(Item).setIconType(this.resultRollIcons[i][3].getComponent(Item).getIconType(), true);
        this.resultRollIcons[i][8].getComponent(Item).setIconType(this.resultRollIcons[i][8].getComponent(Item).getIconType(), true);

        var downTime = this.isFast ? 1.0 : 1.2;
        var upTime = this.isFast ? 0.15 : 0.1;
        // 滚动层正常停止动作
        tween(resultRollbg)
            .call(()=>{
                if (i + 1 <= 5) {
                    this.rollBgisStop[i + 1] = true;
                }
            })
            .to(downTime, {y: destY - 40}, {easing: 'sineOut'})//, {easing: 'sineIn'}
            .call(()=>{

            })
            .to(upTime, {y: destY})//, {easing: 'sineOut'}
            .call(()=>{
                
            })
            .delay(0.1)
            .call(()=>{
                this.rollBgisStop[i] = false;
                this.showResultIcons(i);

                if (i == 5) {
                    // console.log("end rollEnds i = " + i)
                    this.rollEnds(i + 1);
                }
            })
            .start();

        let rollbg = this.rollNodes[i]
        let dest = -2220;
        // 相同滚动层一起位移
        tween(rollbg)
            .to(downTime, {y: dest}, {easing: 'sineOut'})
            .delay(0.5)
            .call(()=>{
                this.rollNodes[i].active = true;
                this.rollNodes[i].y = 2220;
            })
            .start();
    }

    // 快速停止列
    justEnd(i) {
        if(i >= GameConstant.MAX_COL) {
            return;
        }

        let resultRollbg = this.resultRollNodes[i];
        Tween.stopAllByTarget(resultRollbg);
        resultRollbg.y = 0;//270

        Tween.stopAllByTarget(this.rollNodes[i]);
        this.rollNodes[i].y = 2220;

        let destY = 0;
        for (let j = 0; j < GameConstant.MAX_ROW; j++) {
            this.rollNodeIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], false);
            this.resultRollIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
            this.resultIcons[i][j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
        }
        this.resultRollIcons[i][3].getComponent(Item).setIconType(this.resultRollIcons[i][3].getComponent(Item).getIconType(), true);
        this.resultRollIcons[i][8].getComponent(Item).setIconType(this.resultRollIcons[i][8].getComponent(Item).getIconType(), true);

        // 滚动层正常停止动作
        tween(resultRollbg)
            .to(0.2, {y: destY - 40})//, {easing: 'sineIn'}
            .to(0.05, {y: destY})//, {easing: 'sineOut'}
            .call(()=>{
                this.showResultIcons(i);
            })
            .start();
    }

    // 转动逻辑
    update(deltaTime: number) {
        if (!this.isScroll)
            return;

        for (let i = 0; i < GameConstant.MAX_COL; i++)
        {
            if (this.rollBgIsScroll[i]) {

                var interval = this.isFast ? GameConstant.ROLL_FAST_SPEED : GameConstant.ROLL_NORMAL_SPEED;
                this.rollNodes[i].y -= deltaTime * interval;
                this.resultRollNodes[i].y -= deltaTime * interval;

                if (this.rollNodes[i].y <= -2400) {
                    this.rollNodes[i].y = this.resultRollNodes[i].y + this.rollNodes[i].getComponent(UITransform).height;
                }

                if (this.resultRollNodes[i].y <= -2400) {
                    this.resultRollNodes[i].y = this.rollNodes[i].y + this.resultRollNodes[i].getComponent(UITransform).height;
                    if (this.rollBgisStop[i]) {
                        this.rollBgIsScroll[i] = false;
                        this.rollBgisStop[i] = false;

                        this.rollEnds(i);
                    }
                }
            }
        }
    }

    // 接收到结果数据之后设置客户端的结果数据
    setRollDatas(msg, bSpecialGame) {
        this.rollResultData = msg;
        for (let i = 0; i < GameConstant.MAX_ROW; i++) {
            for (let j = 0; j < GameConstant.MAX_COL; j++) {
                this.resultValues[j][i] = this.rollResultData.m_desk_data[i][j];
                this.resultWildTimes[j][i] = this.rollResultData.m_wildTimes_data[i][j];
            }
        }
        this.hasSpecial = this.rollResultData.m_isSpecialGame == 1;
        // console.log(this.resultValues);
    }

    // 展示结果函数
    openPrizes(justEnd, bQuick) {
        if(this.bGameEnd == true) {
            return;
        }

        let endTime = new Date().getTime();
        let leftTime = 0;//this._startRollTime - endTime + 500;
        this.delayTime = 0.2;

        if(justEnd) {
            this.delayTime = 0;
        }

        Tween.stopAllByTarget(this.node);
        this.bQuick = bQuick;
        this.freeIconCount = 0;

        //快速，并且前四排免费图标总数少于2
        if(justEnd) {
            // this.playEffect("skip");
            for(let i = 0; i < GameConstant.MAX_COL; ++i) {
                if (i == 0) this.isScroll = false;

                this.rollBgIsScroll[i] = false;
                this.rollBgisStop[i] = false;

                this.justEnd(i);
                if(i >= 5) {
                    this.delayShowPrizes(200);
                }
            }
            return;
        }

        tween(this.node)
            .delay(leftTime/1000)
            .call(()=>{
                this.rollBgisStop[0] = true;
            })
            .start()
    }

    // 转动结束之后的最终函数
    delayShowPrizes(delayTime) {
        let extraDelayTime = 0.5
        if(this.rollResultData.m_isSpecialGame == 1) {
            extraDelayTime = 2.2
        }
        
        // for (let i = 0; i < GameConstant.MAX_COL; i++) {
        //     console.log("delayShowPrizes this.rollBG[i].y = " + this.rollNodes[i].y + ", this.resultRollBg[i].y = " + this.resultRollNodes[i].y);
        // }

        tween(this.node)
            .delay(delayTime / 1000)
            .call(()=>{
                // this.beforeShowPrize();
            })
            .delay(0.3)
            .call(()=>{
                if (this.hasSpecial){
                    this.showPrizes();
                    this.showSpecialPrize();

                    this.node.parent.getComponent(GameScene).showGameWinScore();
                } else {
                    this.bGameEnd = true;

                    this.showPrizes();

                    this.node.parent.getComponent(GameScene).showGameWinScore();
                }
            })
            .delay(extraDelayTime)
            .call(()=>{
                this.node.parent.getComponent(GameScene).showGameEnd();
            })
            .start()
    }

    // beforeShowPrize() {
    //     for(let i = 0; i < GameConstant.MAX_COL; ++i) {
    //         for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
    //             if (this.resultIcons[i][j].getComponent(Item).getIconType() == GameConstant.SPECIAL_ICON)
    //                 continue;
    //             this.resultIcons[i][j].getComponent(Item).showNormal();
    //         }
    //     }
    // }

    // 展示图标动画
    showPrizes() {
        for(let i = 0; i < GameConstant.MAX_COL; ++i) {
            for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
                if (this.rollResultData.m_line_icon_active[j][i] > 0) {
                    this.resultIcons[i][j].getComponent(Item).showLightAni();
                }
            }
        }

        if (this.rollResultData.m_line_size.length > 0) {
            tween(this.node)
                .delay(2.5)
                .call(()=>{
                    this.showLines(0);
                })
                .start();
        }
    }

    // 每条线的动画展示和下面的中奖细节展示
    showLines(iIndex) {
        if(iIndex >= this.rollResultData.m_line_index.length) {
            this.showPrizes();
            return;
        }

        this.winDetail.active = !this.isInScatterGame;
        this.showWinDetail(iIndex);

        let count = this.rollResultData.m_line_index[iIndex];
        for (let i = 0; i < this.rollResultData.m_line_index[iIndex].length; i++) {
            var x = Math.floor(this.rollResultData.m_line_index[iIndex][i] / GameConstant.MAX_COL);
            var y = this.rollResultData.m_line_index[iIndex][i] % GameConstant.MAX_COL;
            this.resultIcons[y][x].getComponent(Item).showLightAni();
        }

        tween(this.node)
            .delay(2)
            .call(()=>{
                this.showLines(iIndex + 1);
            })
            .start();
    }

    // 展示中奖细节
    showWinDetail(iIndex) {
        let isPlaying = false;
        this.winDetailIcons.removeAllChildren();

        let iconWidth = 0;
        let normalIconW = 0;
        let leftIndex = this.rollResultData.m_line_icon[iIndex].length / 2;
        for(let k = 0; k < this.rollResultData.m_line_icon[iIndex].length; ++k) {
            let resultType = this.rollResultData.m_line_icon[iIndex][k];
            
            let icon = instantiate(this.item);
            var x = Math.floor(this.rollResultData.m_line_index[iIndex][k] / GameConstant.MAX_COL);
            var y = this.rollResultData.m_line_index[iIndex][k] % GameConstant.MAX_COL;

            icon.getComponent(Item).setIconType(resultType, true , this.resultWildTimes[y][x]);
            icon.scale = new Vec3(0.15, 0.15, 0.15);
            icon.parent = this.winDetailIcons;
            icon.active = true;

            normalIconW = (icon.getComponent(UITransform).width + 0) * icon.scale.x + 10;
            icon.x = normalIconW * (-(leftIndex - k) + 0.5) + 0;

            iconWidth += normalIconW;
        }

        this.winDetailLabel.x = iconWidth / 2;
        let singleLineBet = this.node.parent.getComponent(GameScene).getSingleLineBet();
        let score = this.rollResultData.m_line_times[iIndex] * singleLineBet;
        let str = GameConstant.formatNumber(score);

        this.winDetailLabel.getComponent(Label).string = str;
        this.winDetailLabel.getComponent(Label).updateRenderData(true);
        this.winDetail.getComponent(UIOpacity).opacity = 0;
        tween(this.winDetail.getComponent(UIOpacity))
            .call(()=>{
                let interval = (-this.winDetailLabel.getComponent(UITransform).width) / 2;
                this.winDetailIcons.x = interval;
                this.winDetailLabel.x = this.winDetailIcons.x + iconWidth / 2;
            })
            .to(0.3, {opacity: 255})
            .delay(1.5)
            .to(0.3, {opacity: 0})
            .start()
    }

    // 展示特殊图标
    showSpecialPrize() {
        console.log("showSpecialPrize");
        for(let i = 0; i < GameConstant.MAX_COL; ++i) {
            for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
                this.resultIcons[i][j].getComponent(Item).showSpecialAni();
            }
        }
    }
}