import { type Component } from "../components";

export abstract class Entity {
  static Id = 0;

  public id: string;
  public components: Map<string, Component>;
  public name: string;

  protected hooks: Map<string, { add: Function; remove: Function }>;

  constructor(name: string, id: string = (Entity.Id++).toString()) {
    this.name = name;
    this.id = id;
    this.components = new Map();
    this.hooks = new Map();
  }

  public addComponent(component: Component) {
    const hadBeforeSet = this.components.has(component.name);
    this.components.set(component.name, component);
    if (!hadBeforeSet) {
      this.hooks.get(component.name)?.add();
    }
  }

  public removeComponent(name: string) {
    this.components.delete(name);
    this.hooks.get(name)?.remove();
  }

  public getComponent<T>(name: string): T {
    if (!this.hasComponent(name)) {
      throw new Error("Entity does not have component " + name);
    }
    return this.components.get(name) as T;
  }

  public getComponents(): Component[] {
    return Array.from(this.components.values());
  }

  public hasComponent(name: string): boolean {
    return this.components.has(name);
  }
}
