import { _decorator, BoxCollider, Camera, Component, EventTouch, find, geometry, Input, instantiate, Label, Node, NodePool, PhysicsSystem, Quat, RigidBody, Tween, tween, Vec3 } from 'cc';
import { UIBase } from '../Components/UIBase';
import { CarCarColorsComponent } from '../Components/CarCarColorsComponent';
import { CarColorsGlobalInstance } from '../CarColorsGlobalInstance';
import { CarColors, UINames } from '../CarColorsGlobalTypes';
import { GlobalData, ConfigKeys } from '../../../ScriptFrame/GlobalData';
import { PlatformManager } from '../../../ScriptFrame/Frame/platformManager';
import { AudioManager, AudioClipNames } from '../../../ScriptFrame/Frame/AudioManager';
const { ccclass, property } = _decorator;

@ccclass('GamePage')
export class GamePage extends UIBase {
    isAnimateObstacle: boolean = false

    isAnimateHelicopter: boolean = false
    isChooseHelicopterTarget: boolean = false

    smokePool: NodePool = new NodePool()
    
    show(opts?: any): void {
        super.show(opts)
        this.node.on(Input.EventType.TOUCH_START, this.touchStart, this)
        this.isAnimateObstacle = false
        this.node.getChildByName("leveltext").getComponent(Label).string = `第${GlobalData.instance.getConfigData(ConfigKeys.GameSaveData).level}关`
        if (this.smokePool.size() === 0){
            this.smokePool.put(instantiate(find("Scene/Smoke")))
            this.smokePool.put(instantiate(find("Scene/Smoke")))
            this.smokePool.put(instantiate(find("Scene/Smoke")))
        }
    }

    getSmoke(): Node{
        if(this.smokePool.size() > 0){
            return this.smokePool.get()
        }
        return instantiate(find("Scene/Smoke"))
    }

    putSmoke(smoke: Node){
        smoke.removeFromParent()
        smoke.active = false
        this.smokePool.put(smoke)
    }

    hide(): void {
        super.hide()
        this.node.off(Input.EventType.TOUCH_START, this.touchStart, this)
    }

    stopClick(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        if (!CarColorsGlobalInstance.instance.roleSysterm.isGaming) return
        CarColorsGlobalInstance.instance.roleSysterm.isGaming = false
        CarColorsGlobalInstance.instance.uiSysterm.showUI(UINames.StopPage)
        
    }
    refreshClick(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        if (!CarColorsGlobalInstance.instance.roleSysterm.isGaming) return
        CarColorsGlobalInstance.instance.roleSysterm.isGaming = false
        CarColorsGlobalInstance.instance.uiSysterm.showUI(UINames.RefreshPage)
        
    }
    sortClick(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        if (!CarColorsGlobalInstance.instance.roleSysterm.isGaming) return
        CarColorsGlobalInstance.instance.roleSysterm.isGaming = false
        CarColorsGlobalInstance.instance.uiSysterm.showUI(UINames.SortPage)
    }
    vipClick(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        if (!CarColorsGlobalInstance.instance.roleSysterm.isGaming) return
        if (find("Scene/Parkings").children[7].name !== "lock") {
            CarColorsGlobalInstance.instance.toastSysterm.showToast("VIP车位占用")
            return
        }
        CarColorsGlobalInstance.instance.roleSysterm.isGaming = false
        CarColorsGlobalInstance.instance.uiSysterm.showUI(UINames.VipPage)
    }

    shareUnlock(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        PlatformManager.instance.shareGame(()=>{
            const points = find("Scene/Parkings").children
            points[4].name = "empty"
            points[4].children[0].children[0].active = true
            points[4].children[0].children[1].active = false
            AudioManager.instance.playOneShot(AudioClipNames.upgrade)
        })
    }

    videoUnlock1(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        PlatformManager.instance.showVideoAd(()=>{
            const points = find("Scene/Parkings").children
            points[5].name = "empty"
            points[5].children[0].children[0].active = true
            points[5].children[0].children[1].active = false
            AudioManager.instance.playOneShot(AudioClipNames.upgrade)
        },()=>{
            CarColorsGlobalInstance.instance.toastSysterm.showToast("视频播放未完成！")
        })
    }
    videoUnlock2(){
        AudioManager.instance.playOneShot(AudioClipNames.button_ok)
        PlatformManager.instance.showVideoAd(()=>{
            const points = find("Scene/Parkings").children
            points[6].name = "empty"
            points[6].children[0].children[0].active = true
            points[6].children[0].children[1].active = false
            AudioManager.instance.playOneShot(AudioClipNames.upgrade)
        },()=>{
            CarColorsGlobalInstance.instance.toastSysterm.showToast("视频播放未完成！")
        })
    }

    getEmptyParkPoint():Node{
        const points = find("Scene/Parkings").children
        for(let i = 0; i < points.length; i++){
            if (points[i].name === "empty"){
                return points[i]
            }
        }
        return null
    }

    touchStart(event: EventTouch){
        if (this.isAnimateObstacle) return
        if (this.isAnimateHelicopter) return
        let ray = new geometry.Ray();
        find("Main Camera").getComponent(Camera).screenPointToRay(event.getLocationX(), event.getLocationY(), ray);
        // 以下参数可选
        let mask = 1<<2; // 停车位分组
        let maxDistance = 100000;
        let queryTrigger = true;

        // 点中停车位
        if (!this.isChooseHelicopterTarget && PhysicsSystem.instance.raycastClosest(ray, mask, maxDistance, queryTrigger)){
            const parkPoint = PhysicsSystem.instance.raycastClosestResult.collider.node.parent.parent
            console.log(parkPoint)
            if (parkPoint.getSiblingIndex() === 4){
                this.shareUnlock()
            }else if (parkPoint.getSiblingIndex() === 5){
                this.videoUnlock1()
            }if (parkPoint.getSiblingIndex() === 6){
                this.videoUnlock2()
            }
            return
        }

        mask = 1<<1; // 汽车分组
        // 点中汽车
        if (PhysicsSystem.instance.raycastClosest(ray, mask, maxDistance, queryTrigger)) {
            PlatformManager.instance.startVibrate()
            const car = PhysicsSystem.instance.raycastClosestResult.collider.node

            // 直升机挪车到VIP位置
            if (this.isChooseHelicopterTarget){
                this.node.getChildByName("chooseTip").active = false
                this.isChooseHelicopterTarget = false
                this.isAnimateHelicopter = true
                this.helicopterTween(car)
                return
            }
            const halfLen = car.getComponent(CarCarColorsComponent).halfLen
            const pos = car.getWorldPosition()
            const forward = car.forward.clone().multiplyScalar(-1)
            // 检测前方第一个碰撞体
            ray = new geometry.Ray(pos.x, pos.y, pos.z, forward.x, forward.y, forward.z)
            mask = (1<<1) + (1<<4)
            if (PhysicsSystem.instance.raycastClosest(ray, mask, maxDistance, queryTrigger)){
                const collider = PhysicsSystem.instance.raycastClosestResult.collider
                const carMovePos = pos.clone().add(forward.clone().multiplyScalar(PhysicsSystem.instance.raycastClosestResult.distance - halfLen))
                // 碰到车
                if (collider.getGroup() === 1<<1){
                    this.isAnimateObstacle = true
                    tween(car).to(0.1, {
                        worldPosition: carMovePos
                    })
                    // .delay(0.1)
                    .to(0.1, {
                        worldPosition: pos
                    })
                    .call(()=>{
                        this.isAnimateObstacle = false
                    })
                    .start()

                    // 被撞的车
                    const colliderCar = collider.node
                    // 旋转轴
                    const rotAxis = car.forward.clone()
                    Vec3.rotateY(rotAxis,rotAxis, new Vec3(0,0,0),1.57)
                    // 被撞车辆原本的旋转四元数
                    const wRotation = colliderCar.getWorldRotation().clone()
                    // 计算被撞车辆倾斜后旋转四元数
                    const targetRotation = new Quat()
                    Quat.rotateAround(targetRotation, wRotation.clone(), rotAxis.clone(), -0.5)

                    // 播放摇晃动画
                    tween(colliderCar)
                    .delay(0.1)
                    .to(0.05, {
                        worldRotation: targetRotation
                    })
                    .to(0.05, {
                        worldRotation: wRotation
                    })
                    .start()
                    AudioManager.instance.playOneShot(AudioClipNames.crash)
                }
                // 碰到路
                else{
                    // 获取停车位
                    const point = this.getEmptyParkPoint()
                    if (point === null) {
                        // console.log("没有车位了")
                        CarColorsGlobalInstance.instance.toastSysterm.showToast("没有车位了")
                        return
                    }

                    const hitPoint = PhysicsSystem.instance.raycastClosestResult.hitPoint.clone()
                    car.getComponent(BoxCollider).enabled = false
                    car.getComponent(RigidBody).enabled = false
                    const smoke = this.getSmoke()
                    car.addChild(smoke)
                    smoke.active = true
                    let tweenCar: Tween<Node> = tween(car)
                    // 顶部导航
                    if (collider.node.name === "physicRoodTop"){
                        this.hitPointTween(car, point, tweenCar, hitPoint)
                        this.topRoadTween(car, point, tweenCar)
                    }
                    // 左边导航
                    else if (collider.node.name === "physicRoodLeft"){
                        const targetPoint = find("Scene/physicRoodTop/leftPoint")
                        this.hitPointTween(car, targetPoint, tweenCar, hitPoint)
                        this.leftRoadTween(car, tweenCar)
                        this.topRoadTween(car, point, tweenCar)
                    }
                    // 右边导航
                    else if (collider.node.name === "physicRoodRight"){
                        const targetPoint = find("Scene/physicRoodTop/rightPoint")
                        this.hitPointTween(car, targetPoint, tweenCar, hitPoint)
                        this.rightRoadTween(car, tweenCar)
                        this.topRoadTween(car, point, tweenCar,)
                    }
                    // 底部导航
                    else if (collider.node.name === "physicRoodBottom"){
                        if (pos.x > 0){
                            const targetPoint = find("Scene/physicRoodBottom/rightPoint")
                            this.hitPointTween(car, targetPoint, tweenCar, hitPoint)
                            this.bottomRoadTween(car, targetPoint, tweenCar)
                            this.rightRoadTween(car, tweenCar)

                        }else{
                            const targetPoint = find("Scene/physicRoodBottom/leftPoint")
                            this.hitPointTween(car, targetPoint, tweenCar, hitPoint)
                            this.bottomRoadTween(car, targetPoint, tweenCar)
                            this.leftRoadTween(car, tweenCar)
                        }
                        this.topRoadTween(car, point, tweenCar,)
                    }
                    point.name = "inuse"
                    tweenCar.call(()=>{
                        car.setParent(point, true)
                        // CarColorsGlobalInstance.instance.roleSysterm.moveToCar()
                        car.getChildByName("arrow").active = false
                        car.children[0].children[0].children[0].active = false
                        car.setScale(1.15,1.15,1.15)
                        this.putSmoke(smoke)
                    })
                    .start()
                }
            }
        }
    }

    helicopterTween(car: Node){
        const parkPoint = find("Scene/Parkings").children[7]
        parkPoint.name = "inuse"
        parkPoint.children[0].children[0].active = true
        parkPoint.children[0].children[1].active = false
        const helicopter = find("Scene/helicopterPoint/helicopter");
        helicopter.active = true
        const carPos = car.getWorldPosition()
        helicopter.forward = carPos.clone().subtract(helicopter.getWorldPosition()).normalize()
        
        AudioManager.instance.playBgm(AudioClipNames.helico)
        tween(helicopter).to(1, {
            worldPosition: carPos.clone().add3f(0,3,0)
        })
        .call(()=>{
            car.setParent(helicopter, true)
            car.setRotationFromEuler(0,180,0)
            const forward = helicopter.forward.clone()
            const targetforward = parkPoint.getWorldPosition().subtract(helicopter.getWorldPosition())
            tween(forward).to(0.5, {x:targetforward.x, y:targetforward.y, z:targetforward.z}, {onUpdate:()=>{
                helicopter.forward = forward
            }}).start()
        })
        .delay(0.5)
        .to(1, {
            worldPosition: parkPoint.children[0].getWorldPosition().add3f(0,3,0)
        })
        .call(()=>{
            car.forward = new Vec3(-1.2,0,2)
            car.setParent(parkPoint, true)
            CarColorsGlobalInstance.instance.roleSysterm.isGaming = true
            this.isAnimateHelicopter = false
            car.getChildByName("arrow").active = false
            car.children[0].children[0].children[0].active = false
            car.setScale(1.15,1.15,1.15)

            const forward = helicopter.forward.clone()
            const targetforward = helicopter.getPosition().multiplyScalar(-1)
            tween(forward).to(0.2, {x:targetforward.x, y:targetforward.x, z:targetforward.x}, {onUpdate:()=>{
                helicopter.forward = forward
            }}).start()
        })
        .to(1, {
            position:new Vec3(0,0,0)
        })
        .call(()=>{
            AudioManager.instance.playBgm(AudioClipNames.bgm)
            helicopter.active = false
        })
        .start()
    }

    // 导航到碰撞点
    hitPointTween(car: Node, targetPoint: Node, tweenCar:Tween<Node>, hitPoint: Vec3 = null){
        const pointForward: Vec3 = hitPoint.clone().subtract(targetPoint.getWorldPosition()).normalize()
        tweenCar.to(0.2, {
            worldPosition: hitPoint
        })
        .call(()=>{
            AudioManager.instance.playOneShot(AudioClipNames.brake)
            const carforward = car.forward.clone()
            tween(carforward).to(0.1, {x:pointForward.x, y:pointForward.y,z:pointForward.z}, {onUpdate:()=>{
                car.forward = carforward
            }}).start()
        })
        .delay(0.1)
    }

    // 顶部导航
    topRoadTween(car: Node, targetPoint: Node, tweenCar:Tween<Node>){
        tweenCar.to(0.2, {
            worldPosition: targetPoint.getWorldPosition()
        })
        .call(()=>{
            AudioManager.instance.playOneShot(AudioClipNames.brake)
            const carforward = car.forward.clone()
            tween(carforward).to(0.1, {x:-1.2, y:0, z:2}, {onUpdate:()=>{
                car.forward = carforward
            }}).start()
        })
        .delay(0.1)
        .to(0.2, {
            worldPosition: targetPoint.children[0].getWorldPosition()
        })

    }
    // 左边导航
    leftRoadTween(car: Node, tweenCar:Tween<Node>){
        const targetPoint = find("Scene/physicRoodTop/leftPoint")
        tweenCar.to(0.2, {
            worldPosition: targetPoint.getWorldPosition()
        })
        .call(()=>{
            AudioManager.instance.playOneShot(AudioClipNames.brake)
            const carforward = car.forward.clone()
            tween(carforward).to(0.1, {x:-1, y:0, z:0}, {onUpdate:()=>{
                car.forward = carforward
            }}).start()
        })
        .delay(0.1)

    }
    // 右边导航
    rightRoadTween(car: Node, tweenCar:Tween<Node>){
        const targetPoint = find("Scene/physicRoodTop/rightPoint")
        tweenCar.to(0.2, {
            worldPosition: targetPoint.getWorldPosition()
        })
        .call(()=>{
            AudioManager.instance.playOneShot(AudioClipNames.brake)
            const carforward = car.forward.clone()
            tween(carforward).to(0.1, {x:1, y:0, z:0}, {onUpdate:()=>{
                car.forward = carforward
            }}).start()
        })
        .delay(0.1)

    }
    // 底部导航
    bottomRoadTween(car: Node, targetPoint: Node, tweenCar:Tween<Node>){
        tweenCar.to(0.2, {
            worldPosition: targetPoint.getWorldPosition()
        })
        .call(()=>{
            AudioManager.instance.playOneShot(AudioClipNames.brake)
            const carforward = car.forward.clone()
            tween(carforward).to(0.1, {x:0, y:0, z:1}, {onUpdate:()=>{
                car.forward = carforward
            }}).start()
        })
        .delay(0.1)

    }
}


