import { UpdateOptions, Weapon } from './weapon';
import Interval from '../interval';
import {
	addV,
	angle,
	copy,
	distance,
	multiply,
	normalize,
	subtractV,
	length,
	Vector,
} from '../vector';
import Unit from '../unit';
import resources from '../resources';

export class Mace implements Weapon {
	private hitInterval = new Interval(3000);
	private projectileInterval = new Interval(500);
	private speed = 0.15;
	private power = 3;
	private projectiles = 1;
	private damageArea = 16;
	private projectileLifes = 3;
	private _level = 1;

	private _projectilesLeft = 0;
	private _projectiles: Array<{
		position: Vector;
		direction: Vector;
		angle: number;
		alive: boolean;
		lifes: number;
		enemies: Unit[];
	}> = [];

	get key() {
		return 'mace';
	}

	constructor() {}

	update(dt: number, options: UpdateOptions) {
		if (this.hitInterval.next(dt)) {
			this.addProjectile(options.position);
			this._projectilesLeft = this.projectiles - 1;
		}

		if (this._projectilesLeft > 0 && this.projectileInterval.next(dt)) {
			this.addProjectile(options.position);
			this._projectilesLeft--;
		}

		this._projectiles.forEach((projectile) => {
			projectile.angle += dt / 200;

			addV(
				projectile.position,
				multiply(copy(projectile.direction), dt * this.speed),
			);
		});
	}

	private addProjectile(position: Vector) {
		const direction = normalize([Math.random() * 2 - 1, Math.random() * 2 - 1]);
		this._projectiles.push({
			position: copy(position),
			direction,
			angle: 0,
			alive: true,
			lifes: this.projectileLifes,
			enemies: [],
		});
	}

	draw(ctx: CanvasRenderingContext2D) {
		// ctx.drawImage(this.canvas, 0, 0);

		this._projectiles.forEach((projectile) => {
			ctx.save();
			ctx.translate(
				Math.round(projectile.position[0]),
				Math.round(projectile.position[1]),
			);

			ctx.rotate(projectile.angle);

			ctx.drawImage(
				resources.getImage('dungeon'),
				339,
				55,
				10,
				24,
				-5,
				-12,
				10,
				24,
			);

			ctx.restore();
		});
	}

	filterProjectiles(left: number, top: number, right: number, bottom: number) {
		this._projectiles = this._projectiles.filter((projectile) => {
			return (
				projectile.alive &&
				projectile.position[0] > left &&
				projectile.position[1] > top &&
				projectile.position[0] < right &&
				projectile.position[1] < bottom
			);
		});
	}

	checkHit(enemy: Unit) {
		this._projectiles.forEach((projectile) => {
			if (
				projectile.alive &&
				!projectile.enemies.includes(enemy) &&
				distance(projectile.position, enemy.position) < this.damageArea
			) {
				enemy.hit(this.power);
				projectile.lifes--;
				projectile.enemies.push(enemy);
				if (projectile.lifes < 1) projectile.alive = false;
			}
		});
	}

	upgrade() {
		this._level++;

		if (this._level % 2 === 0) {
			this.projectiles++;
		}

		if (this._level % 3 === 0) {
			this.hitInterval.decrease(100);
			this.projectileLifes++;
		}

		if (this._level % 4 === 0) {
			this.power++;
		}

		if (this._level % 5 === 0) {
			this.speed -= 100;
		}
	}
}

export default Mace;
