import { _decorator, BoxCollider2D, CircleCollider2D, Collider2D, Component, Contact2DType, Director, director, instantiate, IPhysics2DContact, Label, math, Node, ParticleSystem2D, PolygonCollider2D, Prefab, Rect, RigidBody, RigidBody2D, Sprite, tween, Tween, UITransform, Vec2, Vec3, View } from 'cc';
import { wall } from './wall';
import { box } from './box';
import { coin } from './coin';
import { tools } from '../tools';
import { game } from './game';
import { car_item_data, DirType, model_content_item_data } from '../data';
import { config } from '../config';
import { imageCacheManager } from '../manager/imageCacheManager';
import { userDataManager } from '../manager/userDataManager';
import { audioManager } from '../manager/audioManager';
import { buff_manager } from './buff/buff_manager';
import { hp_bar } from './hp_bar';
import { GameManager } from '../GameManager';
import { buff_active_effect_item } from './buff/buff_active_effect_item';
import { dataManager } from '../manager/dataManager';
const { ccclass, property } = _decorator;

@ccclass('car')
export class car extends Component {
    private offsetY:number = 0;
    private origin_pos_y:number = -300;
    private map:Node = null;
    private mDir:Vec3 = Vec3.ZERO;
    private mOldDir:Vec3 = Vec3.ZERO;
    private mGameOldDir:Vec3 = Vec3.ZERO;
    private mDis:number = 0;
    private isAction:boolean = false;
    private speed:number = 700;
    @property(CircleCollider2D) car_collider:CircleCollider2D = null;
    @property(Node) lab_hp:Node = null;
    private hp:number = 0
    private scores:number = 0
    private over_cb = null;
    private update_scores_cb = null;
    private game_manager:game = null;
    private buff_xi_status:boolean = false;
    private buff_dun_status:boolean = false;
    private buff_xing_status:boolean = false;
    private speed_bei:number = 1;
    @property(Number) move_speed_y:Number = 700;
    @property(Number) move_speed_x:Number = 700;
    @property(Boolean) is_open_jiaozheng:Boolean = true;
    private carDir:DirType = DirType.NONE
    private canvas_width:number = 1080;
    private isStopY:boolean = false
    private isStartGame:Boolean = false
    @property(Node) spr:Node = null
    @property(Node) hp_bar:Node = null
    @property(Prefab) buff_active_effect_pf:Prefab = null
    @property(ParticleSystem2D) smoke_particle:ParticleSystem2D = null
    private mIsReLife:boolean = false
    private mCarData:car_item_data = null
    public init(m:Node,cb,cb1,g:game,isReLife:boolean = false){
        this.mIsReLife = isReLife
        this.spr.getComponent(Sprite).spriteFrame = imageCacheManager.getGameCarImageById(userDataManager.user_car_list.default_car_id)
        this.spr.getComponent(buff_manager).init()
        this.origin_pos_y = this.node.position.y
        this.game_manager = g
        this.over_cb = cb
        this.update_scores_cb = cb1
        this.map = m;
        this.isAction = false;
        this.mOldDir = this.node.position
        this.buff_xi_status = false;
        this.buff_dun_status = false;
        this.buff_xing_status = false;
        this.isStopY = false;
        this.canvas_width = View.instance.getVisibleSize().width
        if(userDataManager.user_car_list.default_car_id==1){
            audioManager.Instance().playSound(config.AUDIO.zi_xing_che_qi_bu)
        }else{
            audioManager.Instance().playSound(config.AUDIO.car_qi_dong)
        }
     
        this.mCarData = dataManager.getUserCarInfo(userDataManager.user_car_list.default_car_id)

        // let cd = this.node.getComponent(BoxCollider2D)
        // cd.off(Contact2DType.BEGIN_CONTACT)
        // cd.on(Contact2DType.BEGIN_CONTACT,this.onColliderCoin.bind(this))

        // cd.off(Contact2DType.END_CONTACT)
        // cd.on(Contact2DType.END_CONTACT,this.onColliderCoin.bind(this))

        // cd.off(Contact2DType.PRE_SOLVE)
        // cd.on(Contact2DType.PRE_SOLVE,this.onColliderWall.bind(this))
        // this.car_collider.off(Contact2DType.BEGIN_CONTACT)
        // this.car_collider.on(Contact2DType.BEGIN_CONTACT,this.onColliderCoin.bind(this))

        // this.car_collider.off(Contact2DType.END_CONTACT)
        // this.car_collider.on(Contact2DType.END_CONTACT,this.onColliderCoin.bind(this))

        // this.car_collider.off(Contact2DType.POST_SOLVE)
        // this.car_collider.on(Contact2DType.POST_SOLVE,(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)=>{
        //     // console.log("this.car_collider",otherCollider.node.name)
        //     if(otherCollider.node.name.endsWith("fku")){
        //         if(otherCollider.node.parent.getComponent(box)!=null){
        //             otherCollider.node.parent.getComponent(box).hurt(this.shake.bind(this),this.buff_dun_status)
        //         }
        //     }

        //     if(otherCollider.node.name.endsWith("wall")){
        //         // this.node.getComponent(RigidBody2D).linearVelocity  =  new Vec2(this.move_speed_x.valueOf(),this.move_speed_y.valueOf())
        //     }
        // },this)
        this.move_speed_y = tools.game_config.car_origin_speed
        this.hp = tools.game_config.car_init_num + this.mCarData.attribute.k_oil_number
        this.hp_bar.getComponent(hp_bar).updateHp(this.hp)
        // this.hp = 100000
        if(isReLife){

        }else{
            this.scores = 0
        }
        this.updateHp()
        this.updateScores()
        this.node.getComponent(RigidBody2D).gravityScale = -3
        this.node.getComponent(RigidBody2D).linearDamping = 1

        // this.schedule(this.check.bind(this),0.01)
        // circle.radius = tools.game_config.buff_xi_range
        // circle.radius = 400
        // circle.off(Contact2DType.BEGIN_CONTACT)
        // circle.on(Contact2DType.BEGIN_CONTACT,(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)=>{
        //     if(otherCollider.node.name.endsWith("coin")){
        //         if(otherCollider.node.getComponent(coin)!=null){
        //             otherCollider.node.getComponent(coin).moveToTarget(otherCollider.node.parent.getComponent(UITransform).convertToNodeSpaceAR(this.node.position))
        //             this.hp+=tools.randomCoin()
        //             this.updateHp()
        //         }
        //     }
        // })
        this.unschedule(this.addSpeed)
        this.schedule(this.addSpeed.bind(this),tools.game_config.car_add_speed_time)
    }

    public hideEffect(){
        this.spr.getComponent(buff_manager).init()
    }

    public getIsReLife(){
        return this.mIsReLife
    }

    addSpeed(){
        let speed = this.move_speed_y.valueOf()+(tools.game_config.car_add_speed_num)
        if(speed<tools.game_config.car_add_speed_max){
            this.move_speed_y=speed
        }
    }

    addSpeedNum(num:number){
        let speed =  this.move_speed_y.valueOf()+(num*0.01*this.move_speed_y.valueOf())
        if(speed<tools.game_config.car_add_speed_max){
            this.move_speed_y=speed
        }
    }

    onColliderCoin(coin_node:Node){
        if(coin_node.getComponent(coin)!=null){
            audioManager.Instance().playSound(config.AUDIO.qiyou)
            coin_node.getComponent(coin).removeSelf()
            this.hp+=coin_node.getComponent(coin).getAddHpNum()
            this.updateHp()

            let box_world=coin_node.parent.getComponent(UITransform).convertToWorldSpaceAR(coin_node.position)
            let p = this.node.parent.getComponent(UITransform).convertToNodeSpaceAR(box_world)
            this.getGame().showQiYouEffect(p)
        }
    }


    onColliderBox(box_node:Node){
        if(box_node.getComponent(box)!=null){
            audioManager.Instance().playSound(config.AUDIO.peng_zhuang)
            box_node.getComponent(box).hurt(this.shake.bind(this),this.buff_dun_status)
        }
    }
   
    
    public getIsOpenJZ():boolean{
        return this.is_open_jiaozheng.valueOf()
    }

    public getGame(){
        return this.game_manager
    }

    public getXiStatus(){
        return this.buff_xi_status
    }

    private updateScores(){
        if(this.update_scores_cb!=null){
            this.update_scores_cb(this.scores)
        }
    }

    private updateHp(){
        this.lab_hp.getComponent(Label).string = this.hp+""
        this.hp_bar.getComponent(hp_bar).updateHp(this.hp)
    }
    public getScores(){
        return this.scores
    }

    private shake(data:model_content_item_data,isKill:boolean,scores:number){
        // Tween.stopAllByTarget(this.node)
        let new_hp = this.hp;
        // this.isAction = true;
        if(isKill){
          this.scores += ( scores*(this.buff_xing_status?2:1) )
        }else{
            this.scores+=( 1*(this.buff_xing_status?2:1) );
            new_hp = this.hp-1;
        }
        this.hp = new_hp;
        this.updateHp()
        // this.move_speed_y = 0
        this.isStopY  = true
        this.updateScores()
        // this.node.getComponent(RigidBody2D).sleep()
        GameManager.vibrateShort()
        // this.node.position = new Vec3(this.node.position.x, this.node.position.y-8)
        // this.node.getComponent(RigidBody2D).linearVelocity = new Vec2(0,-2.5)

        // director.once(Director.EVENT_AFTER_DRAW,()=>{
        //     // this.move_speed_y = 0
        // })
        // tween(this.node).delay(0.1).call(()=>{
     
        //     // this.isAction = false;
        //     // this.node.position = new Vec3(this.node.position.x, this.node.position.y+8)
        //     // this.node.getComponent(RigidBody2D).wakeUp()

        //     // this.node.getComponent(RigidBody2D).linearVelocity   = new Vec2(this.move_speed_x.valueOf(),30)
        // }).start()
        Tween.stopAllByTarget(this.lab_hp)
        tween(this.lab_hp).delay(0.05).call(()=>{ this.isStopY = false}).start()
        if(this.hp<0){
            if(this.isStartGame){
                Tween.stopAllByTarget(this.node)
                this.stopGame()
                // this.node.getComponent(RigidBody2D).gravityScale = 0
                // this.node.getComponent(RigidBody2D).linearDamping = 0
                this.over_cb()
            }
        }else{
            if(data!=null){
                if(data.buff_type!=-1){
                    let buff_info = this.game_manager.getBuffShowView()
                    let buff_active_node = instantiate(this.buff_active_effect_pf)
                    buff_active_node.parent = buff_info.node.parent
    
                    // console.log("data.buff_type::",data.buff_type)
                    let box_p = buff_info.node.parent.getComponent(UITransform).convertToNodeSpaceAR(data.pos)
                    switch (data.buff_type) {
                        case config.buff_type.dun:
                            // console.log("获取buff 盾")
                            {
                                let dis_node = buff_info.getBuffDun();
                                let world = dis_node.parent.getComponent(UITransform).convertToWorldSpaceAR(dis_node.position)
                                let p = buff_info.node.parent.getComponent(UITransform).convertToNodeSpaceAR(world)
                                buff_active_node.getComponent(buff_active_effect_item).show(config.SHOW_BUFF_STATUS.DUN,p,box_p,()=>{
                                    this.buff_dun()
                                })
                            }
                         
                        break;
                        case config.buff_type.xing:
                            // console.log("获取buff 星")
                            {
                                let dis_node = buff_info.getBuffXing();
                                let world = dis_node.parent.getComponent(UITransform).convertToWorldSpaceAR(dis_node.position)
                                let p = buff_info.node.parent.getComponent(UITransform).convertToNodeSpaceAR(world)
                                buff_active_node.getComponent(buff_active_effect_item).show(config.SHOW_BUFF_STATUS.XING,p,box_p,()=>{
                                    this.buff_xing()
                                })
                            }
                        
                        break;
                        case config.buff_type.xi:
                            // console.log("获取buff 吸")
                            {
                                let dis_node = buff_info.getBuffXi();
                                let world = dis_node.parent.getComponent(UITransform).convertToWorldSpaceAR(dis_node.position)
                                let p = buff_info.node.parent.getComponent(UITransform).convertToNodeSpaceAR(world)
                                buff_active_node.getComponent(buff_active_effect_item).show(config.SHOW_BUFF_STATUS.XI,p,box_p,()=>{
                                    this.buff_xi()
                                })
                            }
                        break;
                    }
                }
            }
        }
    }

    public buff_xi(){
        this.addSpeedNum(tools.game_config.buff_xi_add_speed)
        // Tween.stopAllByTarget(this.game_manager.getBuffShowView().getBuffXi())
        // this.cancelScheduleBuffXi()
        // tween(this.game_manager.getBuffShowView().getBuffXi()).delay(tools.game_config.buff_xi).call(this.cancelScheduleBuffXi.bind(this)).start()
        this.game_manager.getBuffShowView().showBuffXi(this.cancelScheduleBuffXi.bind(this),tools.game_config.buff_xi+this.mCarData.attribute.n_magnet_cd)
        audioManager.Instance().playSound(config.AUDIO.buff_xi)
        this.spr.getComponent(buff_manager).updateStatus(config.SHOW_BUFF_STATUS.XI)
        this.buff_xi_status = true;
    }

    public cancelScheduleBuffXi(){
        if(this.buff_xi_status){
            this.spr.getComponent(buff_manager).cancelStatus(config.SHOW_BUFF_STATUS.XI)
            this.buff_xi_status = false
            this.game_manager.getBuffShowView().hideBuffXi()
        }
    }

    public buff_xing(){
        this.addSpeedNum(tools.game_config.buff_xi_add_speed)
        // Tween.stopAllByTarget(this.game_manager.getBuffShowView().getBuffXing())
        // this.cancelScheduleBuffXing()
        // tween(this.game_manager.getBuffShowView().getBuffXing()).delay(tools.game_config.buff_xing).call(this.cancelScheduleBuffXing.bind(this)).start()
        this.game_manager.getBuffShowView().showBuffXing(this.cancelScheduleBuffXing.bind(this),tools.game_config.buff_xing+this.mCarData.attribute.n_star_cd)
        audioManager.Instance().playSound(config.AUDIO.buff_xing)
        this.spr.getComponent(buff_manager).updateStatus(config.SHOW_BUFF_STATUS.XING)
        this.buff_xing_status = true;
    }

    public cancelScheduleBuffXing(){
        if(this.buff_xing_status ){
            this.spr.getComponent(buff_manager).cancelStatus(config.SHOW_BUFF_STATUS.XING)
            this.buff_xing_status = false
            this.game_manager.getBuffShowView().hideBuffXing()
        }
      
    }

    public buff_dun(time:number =null){
        this.addSpeedNum(tools.game_config.buff_dun_add_speed)
        // Tween.stopAllByTarget(this.game_manager.getBuffShowView().getBuffDun())
        // this.cancelScheduleBuffDun()
        // tween(this.game_manager.getBuffShowView().getBuffDun()).delay(tools.game_config.buff_dun).call(this.cancelScheduleBuffDun.bind(this)).start()
        // this.scheduleOnce(this.cancelScheduleBuffDun.bind(this),tools.game_config.buff_dun)
        this.game_manager.getBuffShowView().showBuffDun(this.cancelScheduleBuffDun.bind(this),time!=null?time:(tools.game_config.buff_dun+this.mCarData.attribute.n_shield_cd))  
        audioManager.Instance().playSound(config.AUDIO.buff_dun)
        this.spr.getComponent(buff_manager).updateStatus(config.SHOW_BUFF_STATUS.DUN)
        this.buff_dun_status = true;
    }


    public cancelScheduleBuffDun(){
        if(this.buff_dun_status){
            this.buff_dun_status = false
            this.game_manager.getBuffShowView().hideBuffDun()
            this.spr.getComponent(buff_manager).cancelStatus(config.SHOW_BUFF_STATUS.DUN)
        }
 
    }


    public setMoveSpeedX(speed_x:number){
        // this.move_speed_x = speed_x
    }
    public startGame(){
        this.isStartGame = true
        this.smoke_particle.node.active = true
        if(this.mCarData.attribute.k_sprint_cd>0){
            this.k_sprint_cd()
        }
    }

    public k_sprint_cd(){
        this.buff_dun(this.mCarData.attribute.k_sprint_cd)
    }
    public stopGame(){
        this.smoke_particle.node.active = false
        this.isStartGame = false
    }
    check(){
    }
    protected update(dt: number): void {
        if(!this.isStartGame){
            return
        }
        if(this.map!=null&&this.hp>=0){
            let x = 0
            let y = this.isStopY?this.node.position.y:this.node.position.y+this.move_speed_y.valueOf()*dt;

            let self_pos = new Vec3(this.node.position.x,this.node.position.y)
            let dis = Math.abs(self_pos.x-this.mDir.x)
            if(dis>1){
                // console.log("dis",this.move_speed_x)
                x = self_pos.subtract(this.mDir).normalize().x*this.move_speed_x.valueOf()*dt*this.speed_bei;
            }

            x = this.node.position.x-x;
    
            let size = this.node.getComponent(UITransform).contentSize;
            let left = this.canvas_width*0.5*-1+size.width*0.5;
            let right = this.canvas_width*0.5-90*0.5;
            
            if(this.carDir==DirType.LEFT){

                let left_x = this.game_manager.getLeftObstacles(new Rect(this.node.position.x-size.width*0.5,this.node.position.y-size.height*0.5,size.width,size.height))
                // console.log("left_x",left_x)
                if(left_x!=null&&x<left_x){
                    x = left_x+5
                }

                if(x<=left){
                    x = left
                }
            }

            if(this.carDir==DirType.RIGHT){
                let right_x = this.game_manager.getRightObstacles(new Rect(this.node.position.x-size.width*0.5,this.node.position.y-size.height*0.5,size.width,size.height))
                // console.log("right_x",right_x)
                if(right_x!=null&&x>right_x){
                    x = right_x-5
                }
                if(x>=right){
                    x = right
                }
            }

            if(x<left||x>right){
                x = this.node.position.x
            }

            let rect = new Rect(x-size.width*0.5,y-size.height*0.5,size.width,size.height)
            // let rect = this.node.getComponent(UITransform).getBoundingBox()
            let list = this.game_manager.carCollider(rect)
            if(list.length>0){
                for (let index = 0; index < list.length; index++) {
                    const element = list[index];
                    if(element.collider_dir==config.collider_dir.top){
                        y = this.node.position.y
                        if(element.type==0){
                            this.onColliderBox(element.node)
                        }else if(element.type==1){
                            x-=element.moveOffset
                            // console.log("carCollider wall",element)
                        }
                    }else{
                        // x = this.node.position.x
                        
                        if(element.type==2){
                            this.onColliderCoin(element.node)
                        }else if(element.type==1||element.type==0){
                            if(element.moveOffset==0){
                                x = this.node.position.x
                            }
                        }
                    }
                }
            }

            // this._curRingPos_1.set(0, 0, 0);
            // Vec3.lerp(this._curRingPos_1, this.node.position, new Vec3(x,y), 50 * dt);

            // this.node.setPosition(this._curRingPos_1);

            if(this.carDir==DirType.LEFT){
                if(x<=left){
                    x = left
                }
            }
            if(this.carDir==DirType.RIGHT){
                if(x>=right){
                    x = right
                }
            }
            this.offsetY =Math.abs(this.origin_pos_y-y)
            let dir = new Vec3(0,-this.offsetY,this.map.position.z)
            this.map.position = dir
            this.node.setPosition(x,y)
        }
    }

    public setDir(dir:DirType){
        // if(this.carDir!=dir){
        //     this.node.getComponent(RigidBody2D).linearVelocity  =  new Vec2(0,this.move_speed_y.valueOf())
        // }
        this.carDir = dir
    }


    public setDisDir(dis:number){
        if(!this.isStartGame){
            return
        }
        if(Math.abs(dis) <1){
            return
        }
        this.speed_bei = Math.abs(dis / 8) 
        if(this.speed_bei>4){
            dis*=4
            Tween.stopAllByTarget(this.smoke_particle.node)
            tween(this.smoke_particle.node).delay(1).call(()=>{
                this.smoke_particle.stopSystem()
            }).start()
            this.smoke_particle.resetSystem()
            if(userDataManager.user_car_list.default_car_id==1){
                audioManager.Instance().playSound(config.AUDIO.zi_xing_che_sha_che)
            }else{
                audioManager.Instance().playSound(config.AUDIO.car_sha_che,0.1)
            }
        }
        if(this.carDir==DirType.LEFT){
            this.mDir = new Vec3(this.node.position.x-dis,this.node.position.y)
        }

        if(this.carDir==DirType.RIGHT){
            this.mDir = new Vec3(this.node.position.x+dis,this.node.position.y)
        }
    }
    public setDis(dis:number){
        this.setSpeed(new Vec3(dis))
        // this.mDis = dis
    }

    public getDis(){
        return this.mDis
    }

    public getCarDir(){
        return this.carDir
    }
    public setSpeed(dir:Vec3){
        // let dis = Math.abs(this.node.position.x - dir.x) 
        // if(dis>200){
        //     dis = 500
        // }
        // this.mDis = dis;

        let dis = Math.abs(this.mOldDir.x - dir.x) 
        // let is_char = false
        // if(this.carDir===DirType.LEFT){
        //     if(dir.x>this.node.position.x){
        //         is_char = true
        //     }
        // }else if(this.carDir===DirType.RIGHT){
        //     if(dir.x<this.node.position.x){
        //         is_char = true
        //     }
     
        // }
        // if(is_char){
        //     dis = Math.abs(this.mGameOldDir.x - dir.x)
        // }else{
        //     this.mGameOldDir = dir
        // }
      
        this.mOldDir = this.node.position
        // dis*=2
        // console.log("this.mDis",dis)
        this.mDis = dis;
        // if(this.mDir.x!=0){
        //     //与目标位置的距离进行速度算法 - 距离越长 速度越快
        //     if(!this.isAction){
        //         let dis = Math.abs(this.mOldDir.x - dir.x) 
        //         if(this.carDir===DirType.LEFT){
        //             if(dir.x>this.node.position.x){
        //                 dis = Math.abs(this.mGameOldDir.x - dir.x)
        //             }
        //         }else if(this.carDir===DirType.RIGHT){
        //             if(dir.x<this.node.position.x){
        //                 dis = Math.abs(this.mGameOldDir.x - dir.x)
        //             }
             
        //         }
            
        //         this.mDis = dis;
        //         // if(dis<=100){
        //         //     this.node.getComponent(RigidBody2D).linearVelocity  = new Vec2(10*x,30)
        //         // }else if(dis>100&&dis<=200){
        //         //     this.node.getComponent(RigidBody2D).linearVelocity  = new Vec2(20*x,30)
        //         // }else{
        //         //     this.node.getComponent(RigidBody2D).linearVelocity  = new Vec2(dis/200*35*x,25)
        //         // }
        //         // this.node.position = new Vec3(this.node.position.x+x*this.speed*dt,this.node.position.y,this.node.position.z)
        //     }
        // }else{
        //     if(this.node.getComponent(RigidBody2D).linearVelocity.x!=0){
        //         this.node.getComponent(RigidBody2D).linearVelocity  = new Vec2(0,this.move_speed_y.valueOf())
        //     }
        // }
 
    }
    // protected update(dt: number): void {
    //     this.node.position =  new Vec3(this.node.position.x,this.node.position.y+dt*500,this.node.position.z)
    //     this.map.position = new Vec3(this.map.position.x,this.map.position.y-dt*500,this.map.position.z)
    // }
}


