package;

import flixel.util.FlxTimer;
import flixel.FlxObject;
import flixel.math.FlxPoint;
import flixel.FlxG;
import flixel.FlxSprite;

class Player extends FlxSprite {
    // Add your player-specific properties and methods here

    public var maxSpeed:Float = 180;

    var inputDirection:FlxPoint = new FlxPoint(0, 0);

    public var shootTime:Float = 0.85;
    public var shootTimeMax:Float = 0.8;

    public var resurrectingTime:Float = 0.0;

    var falseResurrect:Float = 0.0;

    var iHealth:Float = 6;
    public var maxHealth:Float = 6;
    //public var maxEverHealth:Float = 15;

    public var hurting:Float = 0;  // if above 0 just took damage, will not move toward target
    public var hurtTime:Float = 0.4;

    public var resurrectArea:FlxSprite;
    var resurrectAreaVisibleTime:Float = 0.0;
    public var resurrectAreaSize:Int = 1;

    public var canResurrect:Float = 0.0;
    public var canResurrectTime:Float = 4.5;
    public var canResurrectInv:Float = 0.0;

    var useLeftHand:Bool = false;

    public var xp:Float = 0;
    public var xpNextLevel:Float = 10;
    public var xpLevel:Int = 1;
    public var xpLevels = [0, 1200, 2350, 3700, 5800, 8500, 11600, 15200, 19500, 24200, 28400, 32800, 38000, 43500, 48500, 55000, 65000, 75000, 88000, 98000, 110000, 134000];

    public function new(x:Float, y:Float) {
        super(x, y);
        loadGraphic("assets/images/player.png", true, 51, 57);
        antialiasing = false;

        animation.add("walk_s", [0, 5], 1, true);
        animation.add("walk", [6, 7], 1, true);
        animation.add("hurt", [4], 2, false);
        animation.add("res", [1], 1, true);
        animation.add("dead", [2, 3], 1, false);

        animation.play("walk_s");

        maxVelocity.x = maxSpeed;
        maxVelocity.y = maxSpeed;
        drag.x = maxSpeed * 3;
        drag.y = maxSpeed * 3;

        health = iHealth;

        width -= 30;
        offset.x = 15;

        height -= 39;
        offset.y = 30;

        resurrectArea = new FlxSprite(0, 0, "assets/images/summon_area_1.png");
        resurrectArea.visible = false;
        Reg.playstate.add(resurrectArea);
    }

    override public function update(elapsed:Float):Void {
        super.update(elapsed);

        if (health <= 0) {
            return;
        }

        if (xpLevel < 35) {
            if (xp > xpLevels[xpLevel]) {
                xpLevel++;
                Reg.playstate.xpBar.setRange(xpLevels[xpLevel - 1], xpLevels[xpLevel]);
                Reg.playstate.levelText.text = "Level " + xpLevel;
                //slows down game FlxG.camera.flash(0xaaffffff, 0.5, function() { if (health > 0) Reg.playstate.openSubState(new UpgradeWindow());});

                Reg.playstate.openSubState(new UpgradeWindow());
                return;
            }
        }

        inputDirection.set(0, 0);
        if (FlxG.keys.pressed.LEFT || FlxG.keys.pressed.A) {
            inputDirection.x--;
        }
        if (FlxG.keys.pressed.RIGHT || FlxG.keys.pressed.D) {
            inputDirection.x++;
        }
        if (FlxG.keys.pressed.UP || FlxG.keys.pressed.W) {
            inputDirection.y--;
        }
        if (FlxG.keys.pressed.DOWN || FlxG.keys.pressed.S) {
            inputDirection.y++;
        }
        inputDirection.normalize();

        acceleration.x = inputDirection.x * 4000;
        acceleration.y = inputDirection.y * 4000;

        if (resurrectingTime > 0.0) {
            resurrectingTime -= elapsed;


            acceleration.x = acceleration.y = 0.0;

            //velocity.x = velocity.y = 0.0;

            if (resurrectingTime <= 0.0) {
                resurrectingTime = 0.0;
                animation.play("walk");
                canResurrect = canResurrectTime;
                resurrectArea.visible = false;
            }
            else {
                animation.play("res");
            }
        }
        else if (animation.curAnim != null && animation.curAnim.name == "res") {
            falseResurrect -= elapsed;
            acceleration.x = acceleration.y = 0.0;

            if (falseResurrect <= 0.0) {
                falseResurrect = 0.0;
                if (canResurrect <= 0.0)
                    animation.play("walk_s");
                else
                    animation.play("walk");

                resurrectArea.visible = false;
            }
        }

        if (hurting > 0) {
            hurting -= elapsed;
            if (hurting <= 0.0) {
                hurting = 0.0;
                animation.play("walk");
            }
            else {
                if (hurting >= hurtTime - 0.15) {
                    animation.play("hurt");
                }
                else {
                    animation.play("walk");
                }
            }
        }

        if (resurrectAreaVisibleTime > 0.0) {
            resurrectAreaVisibleTime -= elapsed;
            if (resurrectAreaVisibleTime <= 0.0) {
                resurrectAreaVisibleTime = 0.0;
                resurrectArea.visible = false;
            }
        }


        if (canResurrect > 0.0) {
            canResurrect -= elapsed * 0.7;
            if (Reg.playstate.isNight) {
                canResurrect -= elapsed;
            }

            if (canResurrect <= 0.0) {
                canResurrect = 0.0;
                animation.play("walk_s");
            }
        }

        canResurrectInv = canResurrectTime - canResurrect;


        if ((FlxG.mouse.justPressed || FlxG.keys.justPressed.SPACE) && canResurrect <= 0.0) {
            if (resurrectingTime <= 0.0) {

                ///if (!Reg.playstate.isNight) {
                    //animation.play("res");
                    //falseResurrect = 0.14;
                ///}
                ///else {
                    resurrectArea.x = resurrectArea.last.x = x + width * 0.5 - resurrectArea.width * 0.5;
                    resurrectArea.y = resurrectArea.last.y = y + height * 0.5 - resurrectArea.height * 0.5 + 12;

                    resurrectArea.visible = true;
                    resurrectAreaVisibleTime = 0.25;

                    if (!FlxG.overlap(resurrectArea, Reg.playstate.enemies, function(player:Player, enemy:Enemy) {
                        if (enemy.health <= 0 && !enemy.dead) {
                            enemy.resurrect();
                            FlxG.sound.play("assets/sounds/summon.mp3", 0.12);
                            resurrectingTime = enemy.timeToResurrect;
                            velocity.x *= 0.5;
                            velocity.y *= 0.5;
                        }
                    })) {
                        animation.play("res");
                        falseResurrect = 0.14;
                        resurrectAreaVisibleTime = 0.25;
                    }
                ///}
            }
        }

        //if (velocity.x == 0.0 && velocity.y == 0.0) {
        //    x = Math.round(x);
        //    y = Math.round(y);
        //}

        shootTime -= elapsed * 1.25;
        if (!Reg.playstate.isNight)
            shootTime -= elapsed * 0.8;

        if (shootTime <= 0.0) {
            shootTime += shootTimeMax;

            shootBullet();
        }

        if (x < FlxG.worldBounds.x) {
            x = FlxG.worldBounds.x;
            if (velocity.x < 0)
                velocity.x = 0;
        }
        else if (x + width > FlxG.worldBounds.x + FlxG.worldBounds.width) {
            x = FlxG.worldBounds.x + FlxG.worldBounds.width - width;
            if (velocity.x > 0)
                velocity.x = 0;
        }
        if (y < FlxG.worldBounds.y) {
            y = FlxG.worldBounds.y;
            if (velocity.y < 0)
                velocity.y = 0;
        }
        else if (y + height > FlxG.worldBounds.y + FlxG.worldBounds.height) {
            y = FlxG.worldBounds.y + FlxG.worldBounds.height - height;
            if (velocity.y > 0)
                velocity.y = 0;
        }
    }

    function shootBullet() {
        for (i in 0...Reg.playstate.playerBullets.members.length) {
            if (!Reg.playstate.playerBullets.members[i].exists) {
                var halfBulletSize:Float = 9;  // Half of bullet's width and height (18 / 2)
                var bulletX:Float = x + width * 0.5 + (useLeftHand ? -27 : 9) + halfBulletSize;
                var bulletY:Float = y + height * 0.5 - 21 + halfBulletSize;
                Reg.playstate.playerBullets.members[i].reset(bulletX - halfBulletSize, bulletY - halfBulletSize);
                Reg.playstate.playerBullets.members[i].velocity = getVelocityForTarget(FlxG.mouse.x, FlxG.mouse.y, bulletX, bulletY);
                
                FlxG.sound.play("assets/sounds/player_bullet_" + FlxG.random.int(1, 3) + ".wav", 0.05);

                useLeftHand = !useLeftHand; // Toggle hand used
                break;
            }
        }
    }
    

    function getVelocityForTarget(tx:Float, ty:Float, bulletX:Float, bulletY:Float): FlxPoint {
        var bVelocity = new FlxPoint(tx - bulletX, ty - bulletY);
        bVelocity.normalize();
        bVelocity.length = PlayerBullet.speed;
        return bVelocity;
    }
    

    public function killPlayer() {
        acceleration.x = acceleration.y = 0.0;
        animation.play("dead");

        FlxG.sound.play("assets/sounds/dead.wav", 0.3);

        new FlxTimer(Reg.playstate.timers).start(2.5, function(t) {
            Reg.playstate.openSubState(new GameOverWindow());
        });
    }
}