// bullet.hpp - Clase para projectils de la ship
// © 2026 JailDesigner

#pragma once
#include <SDL3/SDL.h>

#include <cstdint>

#include "core/entities/entity.hpp"
#include "core/types.hpp"

// Forward declaration — la definició completa s'inclou només al .cpp.
struct BulletConfig;

class Bullet : public Entities::Entity {
   public:
    Bullet()
        : Entity(nullptr) {}
    explicit Bullet(Rendering::Renderer* renderer);

    void init() override;
    // cfg = nullptr → manté el config actual (per defecte: BulletRegistry::get()).
    // cfg != nullptr → substitueix el config per a aquesta bala (recarrega
    // shape, recalcula collision_radius_, mass, etc.). Útil per a bales
    // d'enemic amb shape pròpia.
    void fire(const Vec2& position, float angle, uint8_t owner_id, float bullet_speed, const BulletConfig* cfg = nullptr);
    void update(float delta_time) override;
    void postUpdate(float delta_time) override;
    void draw() const override;

    // Override: Interfaz de Entity
    [[nodiscard]] auto isActive() const -> bool override { return is_active_; }

    // Override: Interfaz de colisión (radi derivat al ctor des del shape).
    [[nodiscard]] auto getCollisionRadius() const -> float override { return collision_radius_; }
    [[nodiscard]] auto isCollidable() const -> bool override {
        return is_active_;
    }

    // Configuració associada (vàlida des del ctor — la bala l'agafa del BulletRegistry).
    [[nodiscard]] auto getConfig() const -> const BulletConfig& { return *config_; }

    // Getters (API pública sin cambios)
    [[nodiscard]] auto getOwnerId() const -> uint8_t { return owner_id_; }
    [[nodiscard]] auto getPrevPosition() const -> const Vec2& { return prev_position_; }
    void desactivar();

   private:
    const BulletConfig* config_{nullptr};  // apunta al BulletRegistry; vàlid post-ctor
    float collision_radius_{0.0F};         // derivat: shape.bounding_radius × scale × collision_factor

    bool is_active_{false};
    uint8_t owner_id_{0};   // 0=P1, 1=P2
    Vec2 prev_position_{};  // posició al final del frame anterior (swept CCD)
};
