import { Sprite, Text, Graphics } from 'pixi';
import GameItem from './game-item.js';

export default class Starship extends GameItem
{
	constructor(sheet, userId, userName, isMine, type, settings)
	{
		super();

		this.sheet = sheet;
		this.userId = userId;
		this.type = type.toLowerCase();
		this.settings = settings;
		this.isMine = isMine;

		this.rotationRad = 0;   // heading in the simulation space (radians)
		this.rotatingDir = 0;   // +1 counterclockwise, -1 clockwise, 0 not rotating
		this._doThrust = false;
		this._thrusterValue = 0;
		this._shield = 0;

		this.maxShield = settings.getNumber('maxShield');

		// Radar: a dot pointing to the center of space; shown on the current user's ship only
		if (isMine)
		{
			this.radar = new Sprite(sheet.textures['radar_0001']);
			this.radar.anchor.set(0.5);
			this.container.addChild(this.radar);
		}

		// Ship sprite (points to the right; the thruster flame extends it to the left)
		this.sprite = new Sprite();
		this.container.addChild(this.sprite);
		this.setFrame(1);

		// Shield bar (below the ship, above the username)
		this.shieldBar = new Graphics();
		this.shieldBar.y = 15;
		this.container.addChild(this.shieldBar);
		this.drawShield();

		// Username label (below the shield bar)
		this.nameText = new Text({
			text: userName,
			style: { fill: isMine ? 0x6fbff9 : 0xffffff, fontSize: 10, fontFamily: 'Arial' }
		});
		this.nameText.anchor.set(0.5, 0);
		this.nameText.y = 20;
		this.container.addChild(this.nameText);
	}

	// Thrust acceleration converted from pixels/sec^2 to pixels/ms^2
	get thrustAcceleration()
	{
		return this.settings.getNumber('thrustAccel') / 1000000;
	}

	// Max speed converted from pixels/sec to pixels/ms
	get maxSpeed()
	{
		return this.settings.getNumber('maxSpeed') / 1000;
	}

	// Rotation speed converted from degrees/sec to radians/ms
	get rotationSpeed()
	{
		return (this.settings.getNumber('rotationSpeed') * Math.PI / 180) / 1000;
	}

	get doThrust()
	{
		return this._doThrust;
	}

	set doThrust(value)
	{
		this._doThrust = value;
		this.thrusterValue = value ? 2 : 0;
	}

	get thrusterValue()
	{
		return this._thrusterValue;
	}

	// 0 = no flame, 1 = small flame (local activation), 2 = full flame (server confirmed)
	set thrusterValue(value)
	{
		this._thrusterValue = value;
		this.setFrame(1 + Math.min(2, Math.max(0, value)));
	}

	/**
	 * Set the ship sprite frame (1..3), anchoring it at the frame pivot so the ship body doesn't move.
	 */
	setFrame(frame)
	{
		const key = `ship_${this.type}_000${frame}`;
		this.sprite.texture = this.sheet.textures[key];

		// Anchor at the frame pivot baked in the atlas, so the ship body stays fixed when the
		// thruster flame (which extends the sprite to the left) grows. Defaults to the center.
		const anchor = this.sheet.data.frames[key]?.anchor;
		this.sprite.anchor.set(anchor?.x ?? 0.5, anchor?.y ?? 0.5);
	}

	get shield()
	{
		return this._shield;
	}

	set shield(value)
	{
		this._shield = value;
		this.drawShield();
	}

	drawShield()
	{
		const w = 20;
		const h = 2;
		const perc = this.maxShield > 0 ? Math.max(0, Math.min(1, this._shield / this.maxShield)) : 0;

		this.shieldBar.clear();
		this.shieldBar.rect(-w / 2, 0, w, h).fill({ color: 0x333333 });
		if (perc > 0)
			this.shieldBar.rect(-w / 2, 0, w * perc, h).fill({ color: 0x33cc66 });
	}

	/**
	 * Update the display from the current simulation state.
	 */
	render()
	{
		this.updatePosition();

		// The screen y axis is flipped, so the rendered rotation is the opposite of the simulation heading
		this.sprite.rotation = -this.rotationRad;

		// Point the radar to the center of space (0, 0) in screen space
		if (this.radar != null)
			this.radar.rotation = Math.atan2(this.yy, -this.xx);
	}
}
