#include "game/powerup.h"
#include "game/sprites.h"
#include "engine/renderer.h"
#include "engine/particle.h"
#include <stdlib.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

/* ── Stashed entity manager ────────────────────────── */
static EntityManager *s_em = NULL;

/* ── Constants ─────────────────────────────────────── */
#define BOB_SPEED  3.0f   /* sine cycles per second */
#define BOB_HEIGHT 3.0f   /* pixels of vertical bob */
#define PICKUP_SIZE 12    /* hitbox size (centered in 16x16) */

/* ── Callbacks ─────────────────────────────────────── */

static void powerup_update(Entity *self, float dt, const Tilemap *map) {
    (void)map;
    PowerupData *pd = (PowerupData *)self->data;
    if (!pd) return;

    /* Destroy when picked up */
    if (self->flags & ENTITY_DEAD) {
        entity_destroy(s_em, self);
        return;
    }

    /* Sine bob animation */
    pd->bob_timer += dt;
    float bob = sinf(pd->bob_timer * BOB_SPEED * 2.0f * (float)M_PI) * BOB_HEIGHT;
    self->body.pos.y = pd->base_pos.y + bob;

    /* Gentle sparkle particles every ~0.4s */
    if ((int)(pd->bob_timer * 10.0f) % 4 == 0) {
        SDL_Color color;
        switch (pd->kind) {
            case POWERUP_HEALTH:  color = (SDL_Color){220, 50, 50, 200}; break;
            case POWERUP_JETPACK: color = (SDL_Color){255, 180, 50, 200}; break;
            case POWERUP_FUEL:    color = (SDL_Color){255, 120, 30, 200}; break;
            case POWERUP_DRONE:   color = (SDL_Color){50, 200, 255, 200}; break;
            case POWERUP_GUN:     color = (SDL_Color){200, 200, 220, 200}; break;
            default:              color = (SDL_Color){255, 255, 255, 200}; break;
        }
        Vec2 center = vec2(
            self->body.pos.x + self->body.size.x * 0.5f,
            self->body.pos.y + self->body.size.y * 0.5f
        );
        ParticleBurst b = {
            .origin     = center,
            .count      = 1,
            .speed_min  = 5.0f,
            .speed_max  = 15.0f,
            .life_min   = 0.3f,
            .life_max   = 0.6f,
            .size_min   = 1.0f,
            .size_max   = 2.0f,
            .spread     = (float)M_PI,
            .direction  = -(float)M_PI / 2.0f,  /* upward */
            .drag       = 1.0f,
            .gravity_scale = 0.0f,
            .color      = color,
            .color_vary = true,
        };
        particle_emit(&b);
    }

    /* Animation cycling */
    animation_update(&self->anim, dt);
}

static void powerup_render(Entity *self, const Camera *cam) {
    (void)cam;
    if (!g_spritesheet || !self->anim.def) return;

    SDL_Rect src = animation_current_rect(&self->anim);
    Body *body = &self->body;

    /* Center the 16x16 sprite on the smaller hitbox */
    float draw_x = body->pos.x + body->size.x * 0.5f - SPRITE_CELL * 0.5f;
    float draw_y = body->pos.y + body->size.y * 0.5f - SPRITE_CELL * 0.5f;

    Sprite spr = {
        .texture = g_spritesheet,
        .src     = src,
        .pos     = vec2(draw_x, draw_y),
        .size    = vec2(SPRITE_CELL, SPRITE_CELL),
        .flip_x  = false,
        .flip_y  = false,
        .layer   = LAYER_ENTITIES,
        .alpha   = 255,
    };
    renderer_submit(&spr);
}

static void powerup_destroy(Entity *self) {
    free(self->data);
    self->data = NULL;
}

/* ── Public API ────────────────────────────────────── */

void powerup_register(EntityManager *em) {
    entity_register(em, ENT_POWERUP, powerup_update, powerup_render, powerup_destroy);
    s_em = em;
}

Entity *powerup_spawn(EntityManager *em, Vec2 pos, PowerupKind kind) {
    Entity *e = entity_spawn(em, ENT_POWERUP, pos);
    if (!e) return NULL;

    e->body.size = vec2(PICKUP_SIZE, PICKUP_SIZE);
    e->body.gravity_scale = 0.0f;  /* floats in place */
    e->health = 1;
    e->max_health = 1;
    e->damage = 0;
    e->flags |= ENTITY_INVINCIBLE;  /* can't be shot */

    PowerupData *pd = calloc(1, sizeof(PowerupData));
    pd->kind = kind;
    pd->bob_timer = 0.0f;
    pd->base_pos = pos;
    e->data = pd;

    /* Set animation based on kind */
    switch (kind) {
        case POWERUP_HEALTH:  animation_set(&e->anim, &anim_powerup_health);  break;
        case POWERUP_JETPACK: animation_set(&e->anim, &anim_powerup_jetpack); break;
        case POWERUP_FUEL:    animation_set(&e->anim, &anim_powerup_fuel);    break;
        case POWERUP_DRONE:   animation_set(&e->anim, &anim_powerup_drone);   break;
        case POWERUP_GUN:     animation_set(&e->anim, &anim_powerup_gun);     break;
        default:              animation_set(&e->anim, &anim_powerup_health);   break;
    }

    return e;
}

Entity *powerup_spawn_health(EntityManager *em, Vec2 pos) {
    return powerup_spawn(em, pos, POWERUP_HEALTH);
}

Entity *powerup_spawn_jetpack(EntityManager *em, Vec2 pos) {
    return powerup_spawn(em, pos, POWERUP_JETPACK);
}

Entity *powerup_spawn_fuel(EntityManager *em, Vec2 pos) {
    return powerup_spawn(em, pos, POWERUP_FUEL);
}

Entity *powerup_spawn_drone(EntityManager *em, Vec2 pos) {
    return powerup_spawn(em, pos, POWERUP_DRONE);
}

Entity *powerup_spawn_gun(EntityManager *em, Vec2 pos) {
    return powerup_spawn(em, pos, POWERUP_GUN);
}
