#ifndef JNR_ENTITY_H
#define JNR_ENTITY_H

#include <stdbool.h>
#include <stdint.h>
#include "config.h"
#include "engine/physics.h"
#include "engine/animation.h"
#include "util/vec2.h"

/* Forward declarations */
typedef struct Tilemap Tilemap;
typedef struct Camera Camera;

typedef enum EntityType {
    ENT_NONE = 0,
    ENT_PLAYER,
    ENT_ENEMY_GRUNT,
    ENT_ENEMY_FLYER,
    ENT_PROJECTILE,
    ENT_PICKUP,
    ENT_PARTICLE,
    ENT_TURRET,
    ENT_MOVING_PLATFORM,
    ENT_FLAME_VENT,
    ENT_FORCE_FIELD,
    ENT_POWERUP,
    ENT_DRONE,
    ENT_ASTEROID,
    ENT_SPACECRAFT,
    ENT_LASER_TURRET,
    ENT_ENEMY_CHARGER,
    ENT_SPAWNER,
    ENT_TYPE_COUNT
} EntityType;

/* Entity flags */
#define ENTITY_INVINCIBLE    (1 << 0)
#define ENTITY_FACING_LEFT   (1 << 1)
#define ENTITY_DEAD          (1 << 2)
#define ENTITY_ALWAYS_UPDATE (1 << 3)  /* never culled by distance   */

typedef struct Entity {
    EntityType   type;
    bool         active;
    Body         body;
    Animation    anim;
    int          health;
    int          max_health;
    int          damage;
    uint32_t     flags;
    float        timer;          /* general-purpose timer       */
    void        *data;           /* type-specific data pointer  */
} Entity;

/* Function pointer types for entity behaviors */
typedef void (*EntityUpdateFn)(Entity *self, float dt, const Tilemap *map);
typedef void (*EntityRenderFn)(Entity *self, const Camera *cam);
typedef void (*EntityDestroyFn)(Entity *self);

typedef struct EntityManager {
    Entity entities[MAX_ENTITIES];
    int    count;
    /* dispatch tables */
    EntityUpdateFn  update_fn[ENT_TYPE_COUNT];
    EntityRenderFn  render_fn[ENT_TYPE_COUNT];
    EntityDestroyFn destroy_fn[ENT_TYPE_COUNT];
} EntityManager;

void    entity_manager_init(EntityManager *em);
Entity *entity_spawn(EntityManager *em, EntityType type, Vec2 pos);
void    entity_destroy(EntityManager *em, Entity *e);
void    entity_update_all(EntityManager *em, float dt, const Tilemap *map,
                          const Camera *cam);
void    entity_render_all(EntityManager *em, const Camera *cam);
void    entity_manager_clear(EntityManager *em);

/* Register behavior functions for an entity type */
void entity_register(EntityManager *em, EntityType type,
                     EntityUpdateFn update, EntityRenderFn render,
                     EntityDestroyFn destroy);

/* Returns true if the entity is a hostile enemy type.
 * Single source of truth — add new enemy types here. */
bool entity_is_enemy(const Entity *e);

#endif /* JNR_ENTITY_H */
