// 360 degrees per 2 seconds = 180 deg/sec
const ROTATION_SPEED = 180;
// Acceleration in pixels/sec² when thrusting
const THRUST_ACCEL = 200;
// Drag in pixels/sec² when coasting (slow deceleration)
const DRAG = 35;
const MAX_SPEED = 420;
const FIRE_RATE = 280; // ms between shots
// Nose is 24px ahead of sprite center in texture-local space
const NOSE_OFFSET = 24;
const INVINCIBLE_DURATION = 3000; // ms

export default class Player {
    constructor(scene, x, y) {
        this.scene = scene;
        this.alive = true;

        // Texture is 64x32; ship nose points right (angle=0)
        this.sprite = scene.physics.add.sprite(x, y, 'player');
        this.sprite.body.setAllowGravity(false);
        this.sprite.body.setDrag(DRAG, DRAG);
        // Hitbox: circle radius 13 centered at texture center (32,16)
        this.sprite.body.setCircle(13, 19, 3);

        // Start pointing up (-90°)
        this.angle = -90;
        this.sprite.angle = this.angle;

        this.spaceKey = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
        this.aKey = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);

        this.lastFired = 0;
        this.invincible = false;
        this.invincibleUntil = 0;

        this.thrusterSound = scene.sound.add('sfx_thruster', { loop: true, volume: 0.6 });
    }

    update(time, delta) {
        if (!this.alive) return;

        const dt = delta / 1000;

        // Invincibility flicker
        if (this.invincible) {
            if (time > this.invincibleUntil) {
                this.invincible = false;
                this.sprite.setAlpha(1);
            } else {
                this.sprite.setAlpha(Math.sin(time / 80) > 0 ? 1 : 0.15);
            }
        }

        // Rotate toward mouse cursor
        const pointer = this.scene.input.activePointer;
        const world = this.scene.cameras.main.getWorldPoint(pointer.x, pointer.y);
        const targetAngle = Phaser.Math.RadToDeg(
            Math.atan2(world.y - this.sprite.y, world.x - this.sprite.x)
        );
        const maxRot = ROTATION_SPEED * dt;
        const diff = Phaser.Math.Angle.ShortestBetween(this.angle, targetAngle);
        this.angle += Phaser.Math.Clamp(diff, -maxRot, maxRot);
        this.sprite.angle = this.angle;

        // Thrust on left mouse button
        const thrusting = pointer.leftButtonDown();
        if (thrusting) {
            const rad = Phaser.Math.DegToRad(this.angle);
            this.sprite.body.velocity.x += Math.cos(rad) * THRUST_ACCEL * dt;
            this.sprite.body.velocity.y += Math.sin(rad) * THRUST_ACCEL * dt;
            this.sprite.setTexture('player_thrust');
            if (!this.thrusterSound.isPlaying) this.thrusterSound.play();
        } else {
            this.sprite.setTexture('player');
            if (this.thrusterSound.isPlaying) this.thrusterSound.stop();
        }

        // Cap total speed
        const speed = this.sprite.body.speed;
        if (speed > MAX_SPEED) {
            this.sprite.body.velocity.scale(MAX_SPEED / speed);
        }

        // Wrap around screen
        this.scene.physics.world.wrap(this.sprite, 30);

        // Fire: hold key fires at fixed rate
        if (this.spaceKey.isDown || this.aKey.isDown) {
            if (time - this.lastFired > FIRE_RATE) {
                this.lastFired = time;
                const rad = Phaser.Math.DegToRad(this.angle);
                this.scene.spawnPlayerBullet(
                    this.sprite.x + Math.cos(rad) * NOSE_OFFSET,
                    this.sprite.y + Math.sin(rad) * NOSE_OFFSET,
                    this.angle
                );
            }
        }
    }

    // Returns true if the hit should count (not invincible)
    hit() {
        return !this.invincible;
    }

    // Hide the ship and go invincible immediately – call before delaying respawn
    die() {
        this.alive = false;
        if (this.thrusterSound.isPlaying) this.thrusterSound.stop();
        this.invincible = true;
        this.invincibleUntil = this.scene.time.now + 99999;
        this.sprite.body.setVelocity(0, 0);

        const x = this.sprite.x;
        const y = this.sprite.y;
        const angle = this.sprite.angle;

        // White flash for 100ms, then hide
        this.sprite.setTint(0xffffff);
        this.scene.time.delayedCall(100, () => {
            if (this.sprite && this.sprite.active) {
                this.sprite.clearTint();
                this.sprite.setActive(false).setVisible(false);
            }
        });

        this._spawnShatterShards(x, y, angle);
    }

    _spawnShatterShards(x, y, angle) {
        const scene = this.scene;
        const defs = [
            { angleOffset: -115, dist: 65, size: 7,  spin:  270 },
            { angleOffset:  115, dist: 65, size: 9,  spin: -270 },
            { angleOffset:  175, dist: 80, size: 11, spin:  240 },
        ];

        defs.forEach((def, i) => {
            const gfx = scene.add.graphics();
            gfx.setDepth(5);
            gfx.fillStyle(0x00ff44, 1);
            const s = def.size;
            if (i === 0)      gfx.fillTriangle(0, -s, -s * 0.6, s * 0.5,  s * 0.4, s * 0.5);
            else if (i === 1) gfx.fillTriangle(s * 0.5, -s * 0.8, -s * 0.5, -s * 0.3, 0, s);
            else              gfx.fillTriangle(-s * 0.7, 0, s * 0.7, 0, 0, s);
            gfx.x = x;
            gfx.y = y;

            const rad = Phaser.Math.DegToRad(angle + def.angleOffset);
            scene.tweens.add({
                targets: gfx,
                x: x + Math.cos(rad) * def.dist,
                y: y + Math.sin(rad) * def.dist,
                angle: gfx.angle + def.spin,
                alpha: 0,
                duration: 800,
                ease: 'Quad.Out',
                onComplete: () => gfx.destroy()
            });
        });
    }

    makeInvincible() {
        this.invincible = true;
        this.invincibleUntil = this.scene.time.now + INVINCIBLE_DURATION;
        this.sprite.setAlpha(1);
    }

    respawn(x, y) {
        this.alive = true;
        this.sprite.setPosition(x, y);
        this.sprite.body.setVelocity(0, 0);
        this.sprite.setActive(true).setVisible(true);
        this.angle = -90;
        this.sprite.angle = this.angle;
        this.makeInvincible();
    }

    destroy() {
        this.alive = false;
        if (this.thrusterSound) { this.thrusterSound.stop(); this.thrusterSound.destroy(); }
        if (this.sprite && this.sprite.active) {
            this.sprite.destroy();
        }
    }
}
