#include "game/entity_registry.h"
#include "game/player.h"
#include "game/enemy.h"
#include "game/projectile.h"
#include "game/hazards.h"
#include "game/powerup.h"
#include "game/drone.h"
#include "game/spacecraft.h"
#include <string.h>
#include <stdio.h>

EntityRegistry g_entity_registry = {0};

/* ── Wrapper spawn functions ──────────────────────
 * Some spawn functions need extra args beyond (em, pos).
 * We wrap them to match the EntitySpawnFn signature.
 * ──────────────────────────────────────────────────── */

static Entity *spawn_platform_v(EntityManager *em, Vec2 pos) {
    return mplat_spawn_dir(em, pos, vec2(0.0f, 1.0f));
}

static Entity *spawn_powerup_health(EntityManager *em, Vec2 pos) {
    return powerup_spawn_health(em, pos);
}

static Entity *spawn_powerup_jetpack(EntityManager *em, Vec2 pos) {
    return powerup_spawn_jetpack(em, pos);
}

static Entity *spawn_powerup_drone(EntityManager *em, Vec2 pos) {
    return powerup_spawn_drone(em, pos);
}

static Entity *spawn_powerup_gun(EntityManager *em, Vec2 pos) {
    return powerup_spawn_gun(em, pos);
}

/* ── Registry population ─────────────────────────── */

static void reg_add(const char *name, const char *display,
                    EntitySpawnFn fn, SDL_Color color, int w, int h) {
    EntityRegistry *r = &g_entity_registry;
    if (r->count >= MAX_REGISTRY_ENTRIES) return;
    r->entries[r->count++] = (EntityRegEntry){
        .name     = name,
        .display  = display,
        .spawn_fn = fn,
        .color    = color,
        .width    = w,
        .height   = h,
    };
}

void entity_registry_init(EntityManager *em) {
    g_entity_registry.count = 0;

    /* Register all entity behaviors with the entity manager */
    player_register(em);
    player_set_entity_manager(em);
    grunt_register(em);
    flyer_register(em);
    projectile_register(em);
    turret_register(em);
    mplat_register(em);
    flame_vent_register(em);
    force_field_register(em);
    powerup_register(em);
    drone_register(em);
    asteroid_register(em);
    spacecraft_register(em);

    /* ════════════════════════════════════════════
     *  REGISTRY TABLE
     *
     *  To add a new entity type to the game:
     *  1. Create its .h/.c files
     *  2. Register its behaviors above
     *  3. Add one reg_add() line below
     *
     *  The editor will pick it up automatically.
     * ════════════════════════════════════════════ */

    /*        .lvl name       display name     spawn fn              color (editor)                w   h  */
    reg_add("grunt",         "Grunt",          grunt_spawn,          (SDL_Color){200, 60, 60, 255},   GRUNT_WIDTH,   GRUNT_HEIGHT);
    reg_add("flyer",         "Flyer",          flyer_spawn,          (SDL_Color){140, 80, 200, 255},  FLYER_WIDTH,   FLYER_HEIGHT);
    reg_add("turret",        "Turret",         turret_spawn,         (SDL_Color){160, 160, 160, 255}, TURRET_WIDTH,  TURRET_HEIGHT);
    reg_add("platform",      "Platform (H)",   mplat_spawn,          (SDL_Color){80, 180, 80, 255},   MPLAT_WIDTH,   MPLAT_HEIGHT);
    reg_add("platform_v",    "Platform (V)",   spawn_platform_v,     (SDL_Color){80, 160, 100, 255},  MPLAT_WIDTH,   MPLAT_HEIGHT);
    reg_add("flame_vent",    "Flame Vent",     flame_vent_spawn,     (SDL_Color){255, 120, 40, 255},  FLAME_WIDTH,   FLAME_HEIGHT);
    reg_add("force_field",   "Force Field",    force_field_spawn,    (SDL_Color){60, 140, 255, 255},  FFIELD_WIDTH,  FFIELD_HEIGHT);
    reg_add("powerup_hp",    "Health Pickup",  spawn_powerup_health, (SDL_Color){255, 80, 80, 255},   12, 12);
    reg_add("powerup_jet",   "Jetpack Refill", spawn_powerup_jetpack,(SDL_Color){255, 200, 50, 255},  12, 12);
    reg_add("powerup_drone", "Drone Pickup",   spawn_powerup_drone,  (SDL_Color){80, 200, 255, 255},  12, 12);
    reg_add("powerup_gun",   "Gun Pickup",    spawn_powerup_gun,    (SDL_Color){200, 200, 220, 255}, 12, 12);
    reg_add("asteroid",      "Asteroid",      asteroid_spawn,       (SDL_Color){140, 110, 80, 255},  ASTEROID_WIDTH, ASTEROID_HEIGHT);
    reg_add("spacecraft",    "Spacecraft",    spacecraft_spawn,     (SDL_Color){187, 187, 187, 255}, SPACECRAFT_WIDTH, SPACECRAFT_HEIGHT);

    printf("Entity registry: %d types registered\n", g_entity_registry.count);
}

const EntityRegEntry *entity_registry_find(const char *name) {
    for (int i = 0; i < g_entity_registry.count; i++) {
        if (strcmp(g_entity_registry.entries[i].name, name) == 0) {
            return &g_entity_registry.entries[i];
        }
    }
    return NULL;
}

Entity *entity_registry_spawn(EntityManager *em, const char *name, Vec2 pos) {
    const EntityRegEntry *entry = entity_registry_find(name);
    if (!entry) {
        fprintf(stderr, "entity_registry_spawn: unknown type '%s'\n", name);
        return NULL;
    }
    return entry->spawn_fn(em, pos);
}
