import {
    _decorator,
    Animation,
    animation,
    AudioClip,
    Button,
    Component,
    Input,
    input,
    instantiate,
    Label,
    lerp,
    Node,
    NodePool,
    Prefab,
    tween,
    UIOpacity,
    v3
} from "cc";
import Scene from '../../Module/Scene';
import { changeScene } from '../../Module/UIFast';
import { runMainPage } from './runMain/runMainPage';
import { getWebData, LOG_TYPE, sendLog, WebNetName } from '../Utils/WebNet/WebNet';
import store from '../store/store';
import { _asyncThrottle } from '../Utils/Utils';
import { AudioMgr } from '../../core_tgx/base/AudioMgr';
import Svga from '../../Component/Svga/Svga';
const { ccclass, property } = _decorator;

@ccclass('runGamePage')
export class runGamePage extends Scene {
    static bundle: string = "runGamePage";
    static skin: string = "runGamePage";
    //倒计时
    static TIME_COUNT = 60;

    @property(Node)
    backBtn: Node = null;

    @property(Node)
    scoreLab: Node = null;
    @property(Node)
    timeBox: Node = null;
    @property(Label)
    timeLab: Label = null;

    @property(Node)
    choseBox: Node = null;

    @property(Node)
    guideBox: Node = null;

    @property(Node)
    startCount: Node = null;

    @property(Node)
    gameBox: Node = null;

    @property(Prefab)
    guihuaball: Prefab = null;
    @property(Prefab)
    diaball: Prefab = null;
    @property(Prefab)
    goldball: Prefab = null;
    @property(Prefab)
    boomball: Prefab = null;
    @property(Prefab)
    ipball: Prefab = null;
    @property(Prefab)
    snakePre: Prefab = null;

    @property(AudioClip)
    getMusic: AudioClip = null

    @property(Node) propTip: Node = null;

    //没吃一个加减分
    addScore = 1;

    guihuaPool: NodePool;
    diaPool: NodePool;
    goldPool: NodePool;
    boomPool: NodePool;
    ipPool: NodePool;
    guideStep = 1

    propsList = ["guihua", "dia", "gold", "ip"]
    linePos = [-120, 0, 120]
    snakePos = [-260, 0, 260]
    startStatus = false

    player: Node;
    snakeLine = 1;
    isFirstChose = false;
    choseSnakeType = "normal"

    _score = 0;
    _time = runGamePage.TIME_COUNT;
    set score(add) {
        this._score = add
        if (this._score <= 0) {
            this._score = 0
        }
        this.scoreLab.getComponent(Label).string = this._score + ""
    }
    get score() {
        return this._score;
    }
    set time(timeinfo) {
        this._time = timeinfo
        this.timeLab.string = this._time + "s"
        if (this._time <= 0) {
            // 结束游戏
            this.unschedule(this.timeControl)
            this.endGame()
        }

    }
    get time() {
        return this._time;
    }

    protected onLoad() {
        this.propTip.active = false;
    }

    start() {
        this.time = runGamePage.TIME_COUNT;
        this.guihuaPool = new NodePool();
        this.diaPool = new NodePool();
        this.goldPool = new NodePool();
        this.boomPool = new NodePool()
        this.ipPool = new NodePool()
        this.backBtn.on(Button.EventType.CLICK, this.click_Back, this)
        let data = getWebData(WebNetName.tcs_Start).data
        if (data.boolFirstJoin) {
            // 进入新手引导
            // sendLog(LOG_TYPE.EXPOSURE, 37)
            this.guideBox.active = true;
            this.guideStep = 1;
            let i = 1;
            while (i <= 6) {
                this.guideBox.getChildByName("guide" + i).active = false
                i++;
            }
            this.guideBox.getChildByName("guide1").active = true
            this.guideBox.on(Button.EventType.CLICK, this.nextGuide, this)
        } else {
            this.showCount()
        }
    }
    async nextGuide() {
        this.guideStep++
        switch (this.guideStep) {
            case 1:
                this.guideBox.getChildByName("guide1").active = true
                break;

            case 2:
                // sendLog(LOG_TYPE.CLICK, 37)
                // sendLog(LOG_TYPE.EXPOSURE, 38)
                this.guideBox.getChildByName("guide1").active = false
                this.guideBox.getChildByName("guide2").active = true
                break;
            case 3:
                // sendLog(LOG_TYPE.CLICK, 38)
                // sendLog(LOG_TYPE.EXPOSURE, 39)
                this.guideBox.getChildByName("guide2").active = false
                this.guideBox.getChildByName("guide3").active = true
                break;
            case 4:
                // sendLog(LOG_TYPE.CLICK, 39)
                // sendLog(LOG_TYPE.EXPOSURE, 40)
                this.guideBox.getChildByName("guide3").active = false
                this.guideBox.getChildByName("guide4").active = true
                break;
            case 5:
                // sendLog(LOG_TYPE.CLICK, 40)
                // sendLog(LOG_TYPE.EXPOSURE, 41)
                this.guideBox.getChildByName("guide4").active = false
                this.guideBox.getChildByName("guide5").active = true
                break;
            case 6:
                // sendLog(LOG_TYPE.CLICK, 41)
                this.guideBox.getChildByName("guide5").active = false
                this.guideBox.getChildByName("guide6").active = true
                this.scoreLab.setSiblingIndex(this.guideBox.getSiblingIndex() + 1)
                this.timeBox.setSiblingIndex(this.guideBox.getSiblingIndex() + 1)
                break
            case 7:
                // 完成新手引导 开始游戏
                // sendLog(LOG_TYPE.CLICK, 41)
                this.guideEnd()
                break
        }
    }
    guideEnd = _asyncThrottle(async () => {
        // await store.startTCS()
        this.guideBox.active = false;
        this.showCount()
    })

    showCount() {
        // sendLog(LOG_TYPE.EXPOSURE, 42)
        this.player = instantiate(this.snakePre)
        this.gameBox.addChild(this.player)
        this.player.position = v3(0, -500)
        this.snakeLine = 1
        // 进入倒计时
        this.scoreLab.setSiblingIndex(this.startCount.getSiblingIndex() - 1)
        this.timeBox.setSiblingIndex(this.startCount.getSiblingIndex() - 1)
        this.startCount.active = true
        this.scheduleOnce(() => {
            this.startCount.active = false
            this.startGame()
        }, 3)
    }
    click_Back() {
        changeScene(runMainPage)
    }

    startGame() {
        this.moveSpeed = 1;
        this.allTime = 0;
        this.nowTime = 0
        this.startStatus = true
        this.player.getChildByName("snakePlayer").getComponent(Svga).play()
        this.creatBall("guihua", true, 0)
        this.creatBall("dia", true, 1)
        this.creatBall("gold", true, 2)
        this.boomNum = 0
        this.gameBox.on(Input.EventType.TOUCH_START, this.startMove, this)
        this.gameBox.on(Input.EventType.TOUCH_END, this.endMove, this)
        this.gameBox.on(Input.EventType.TOUCH_CANCEL, this.endMove, this)

    }
    choseType() {
        this.propTip.active = true;
        this.propTip.getComponent(UIOpacity).opacity = 0;
        tween(this.propTip.getComponent(UIOpacity))
            .to(0.288, { opacity: 255 })
            .delay(1.88)
            .to(0.288, { opacity: 0 })
            .call(() => {
                this.propTip.active = false;
            })
            .start();
        // 修改box展示
        if (this.isFirstChose) {
            this.isFirstChose = false
            this.choseBox.getChildByName("rungame_notc").active = false;
            this.choseBox.getChildByName("rungame_" + this.choseSnakeType + "c").active = true;
            // this.player.getChildByName("normal").active = false
            this.player.getChildByName(this.choseSnakeType).active = true
            this.countDown()
            this.nowFrame = 40
        }
        // 开始倒计时
    }

    defaultTime = 0.0008;//0.016;
    nowTime = 0
    ballList = []
    moveSpeed = 0;
    allTime = 0
    nowFrame = 0;
    farmeLimt = 30
    boomNum = 0
    ipNum = 0
    update(deltaTime: number) {
        if (!this.startStatus) {
            return
        }
        this.nowTime += deltaTime
        this.allTime += deltaTime
        if (this.nowTime >= this.defaultTime) {
            if (!this.isFirstChose) {
                this.nowFrame++
                if (this.moveSpeed < 7) {
                    this.farmeLimt = 60
                } else if (this.moveSpeed < 10) {
                    this.farmeLimt = 50
                } else if (this.moveSpeed < 13) {
                    this.farmeLimt = 50
                } else {
                    this.farmeLimt = 50
                }
                if (this.nowFrame >= this.farmeLimt) {

                    let typeStr = this.propsList.slice();
                    typeStr.sort(function () {
                        return Math.random() - 0.5
                    })
                    if (this.moveSpeed > 15.1) {
                        typeStr = [this.choseSnakeType, this.choseSnakeType, this.choseSnakeType];
                    } else {
                        let num = Math.random() * 100
                        if (num > 80 && this.boomNum < 3 && this.moveSpeed > 10) {
                            this.boomNum++
                            let line = Math.floor(Math.random() * 3);
                            typeStr[line] = "boom"
                        }
                    }
                    for (let i = 0; i < 3; i++) {
                        this.creatBall(typeStr[i], false, i);
                    }

                    this.nowFrame -= this.farmeLimt
                }
            }
            this.ballMove();
            this.nowTime -= this.defaultTime
        }
        this.moveSpeed = lerp(7, 19, this.allTime / 120)

    }
    addOrCutAni() {
        if (this.player.getChildByName("add1").active) {
            let y1 = this.player.getChildByName("add1").position.y
            if (y1 > 390) {
                this.player.getChildByName("add1").active = false
            }
            y1++;
            this.player.getChildByName("add1").position = v3(-4, y1)
        }
        if (this.player.getChildByName("add10").active) {
            let y1 = this.player.getChildByName("add10").position.y
            if (y1 > 390) {
                this.player.getChildByName("add10").active = false
            }
            y1++;
            this.player.getChildByName("add10").position = v3(-4, y1)
        }
        if (this.player.getChildByName("cut1").active) {
            let y2 = this.player.getChildByName("cut1").position.y
            if (y2 > 390) {
                this.player.getChildByName("cut1").active = false
            }
            y2++;
            this.player.getChildByName("cut1").position = v3(0, y2)
        }
        if (this.player.getChildByName("cost5").active) {
            let y3 = this.player.getChildByName("cost5").position.y
            if (y3 > 390) {
                this.player.getChildByName("cost5").active = false
                this.player.getChildByName("boomsvga").active = false
            }
            y3++;
            this.player.getChildByName("cost5").position = v3(0, y3)
        }
    }
    ballMove() {
        this.addOrCutAni()
        let stillList = []
        for (let i = 0; i < this.ballList.length; i++) {
            const ry = -(this.ballList[i].position.y - 812) / 1624;
            const speed = this.moveSpeed;

            let y = this.ballList[i].position.y - speed
            let x = this.ballList[i].position.x
            let scale = this.ballList[i].scale.x + speed / 1450
            let propsLine = 1
            if (this.ballList[i].position.x == 0) {
                x = 0
                propsLine = 1
            } else if (this.ballList[i].position.x < 0) {
                x -= 255 * speed / 1450
                propsLine = 0
            } else {
                x += 255 * speed / 1450
                propsLine = 2
            }
            this.ballList[i].scale = v3(scale, scale)
            this.ballList[i].position = v3(x, y)
            // if (y <= -750) {
            if (y <= -360) {
                // 移除
                // let name = this.ballList[i].name.split("Ball")[0]
                let name = this.ballList[i].name.substring(0, this.ballList[i].name.length - 4)
                this[name + "Pool"].put(this.ballList[i])
            } else {
                if (y <= -200 && y >= -350 && propsLine == this.snakeLine) {
                    // 碰撞到了消除
                    AudioMgr.ins.playOneShot(this.getMusic, {})
                    if (this.isFirstChose) {
                        // 是否是初始状态
                        // 全部消除 并设置状态
                        this.choseSnakeType = this.ballList[i].name.split("Ball")[0]
                        this.choseType()
                        for (let n = 0; n < this.ballList.length; n++) {
                            let name = this.ballList[n].name.split("Ball")[0]
                            this[name + "Pool"].put(this.ballList[n])
                        }
                        this.ballList = []
                        return
                    } else {
                        let name = this.ballList[i].name.substring(0, this.ballList[i].name.length - 4)
                        this[name + "Pool"].put(this.ballList[i])
                        if (this.choseSnakeType == name) {
                            this.score += this.addScore
                            this.player.getChildByName("add1").position = v3(-4, 370)
                            this.player.getChildByName("add1").active = true
                            this.player.getChildByName("starSvga").active = true
                            this.player.getChildByName("starSvga").getComponent(Svga).play()
                        } else {
                            if (name == "ip") {
                                this.score += 10
                                this.player.getChildByName("add10").position = v3(0, 370)
                                this.player.getChildByName("add10").active = true
                                this.player.getChildByName("starSvga").active = true
                                this.player.getChildByName("starSvga").getComponent(Svga).play()
                            } else if (name == "boom") {
                                this.score -= 5
                                this.player.getChildByName("cost5").position = v3(0, 370)
                                this.player.getChildByName("cost5").active = true
                                this.player.getChildByName("boomsvga").active = true
                                this.player.getChildByName("boomsvga").getComponent(Svga).play()
                            } else {
                                this.score -= this.addScore
                                this.player.getChildByName("cut1").position = v3(0, 370)
                                this.player.getChildByName("cut1").active = true
                            }

                        }
                    }
                } else {
                    stillList.push(this.ballList[i])
                }
            }
        }
        this.ballList = stillList
    }
    creatBall(type, isFirst, line) {
        this.isFirstChose = isFirst
        let node;
        if (this[type + "Pool"]?.size() > 0) {
            node = this[type + "Pool"].get()
        } else {
            node = instantiate(this[type + "ball"])
            // node.addComponent(plateCtrl)
        }
        if (type != "boom" && type != "ip") {
            node.getChildByName("ball_" + type).active = true
            node.getChildByName("first_" + type).active = false
        }
        // if (isFirst) {
        //     node.getChildByName("ball_" + type).active = false
        //     node.getChildByName("first_" + type).active = true
        // } else {
        //     if (type == "boom") {

        //     } else {
        //         node.getChildByName("ball_" + type).active = true
        //         node.getChildByName("first_" + type).active = false
        //     }

        // }
        this.gameBox.addChild(node);
        // console.log(this.linePos[line])
        node.scale = v3(0.5, 0.5)
        node.position = v3(this.linePos[line], 380)
        this.ballList.push(node)
    }
    startX = 0
    startMove(e) {
        this.startX = e.touch.getLocation().x
    }
    canMove = true
    endMove(e) {
        let endX = e.touch.getLocation().x

        if (endX - this.startX > 50) {
            // 向右移动
            if (this.snakeLine < 2) {
                if (!this.canMove) {
                    return
                }
                this.canMove = false

                // this.player.position = v3(this.snakePos[this.snakeLine], -500)
                // this.snakeLine++

                tween(this.player)
                    .to(0.4, { position: v3(this.snakePos[this.snakeLine + 1], -500) })
                    .call(() => {
                        this.canMove = true
                    })
                    .start()
                let num = this.snakeLine
                this.snakeLine += 0.5
                this.scheduleOnce(() => {
                    this.snakeLine = ++num
                }, 0.2)
            }
        }
        if (this.startX - endX > 50) {
            // 向左移动
            if (this.snakeLine > 0) {
                if (!this.canMove) {
                    return
                }
                this.canMove = false
                // this.player.position = v3(this.snakePos[this.snakeLine], -500)
                // this.snakeLine--


                tween(this.player)
                    .to(0.4, { position: v3(this.snakePos[this.snakeLine - 1], -500) })
                    .call(() => {
                        this.canMove = true
                    })
                    .start()
                let num = this.snakeLine
                this.snakeLine -= 0.5
                this.scheduleOnce(() => {
                    // this.snakeLine--
                    this.snakeLine = --num
                }, 0.2)
            }
        }
    }

    timeControl: any;
    countDown() {
        this.unschedule(this.timeControl)
        if (this.time > 0) {
            this.time--
            this.timeControl = this.countDown.bind(this)
            this.scheduleOnce(this.timeControl, 1)
        }
    }


    endGame() {
        console.log("游戏结束")
        this.startStatus = false
        this.unschedule(this.timeControl)
        store.submitTCS(this.score)
    }

}


