// enemy.hpp - Clase para enemigos (ORNIs)
// © 2026 JailDesigner

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

#include <cstdint>

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

// Tipo de enemy
enum class EnemyType : uint8_t {
    PENTAGON = 0,  // Pentágono esquivador (zigzag)
    QUADRAT = 1,   // Cuadrado perseguidor (tracks ship)
    MOLINILLO = 2  // Molinillo agresivo (rápido, girando)
};

// Estado de animación (palpitación + rotación acelerada)
struct EnemyAnimation {
    // Palpitación (efecto respiración)
    bool palpitacio_activa = false;
    float palpitacio_fase = 0.0F;
    float palpitacio_frequencia = 2.0F;
    float palpitacio_amplitud = 0.15F;
    float palpitacio_temps_restant = 0.0F;

    // Aceleración de rotación visual (modulación a largo plazo)
    float drotacio_base = 0.0F;
    float drotacio_objetivo = 0.0F;
    float drotacio_t = 0.0F;
    float drotacio_duracio = 0.0F;
};

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

    void init() override { init(EnemyType::PENTAGON, nullptr); }
    void init(EnemyType type, const Vec2* ship_pos = 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 esta_; }

    // Override: Interfaz de colisión
    [[nodiscard]] auto getCollisionRadius() const -> float override {
        return Defaults::Entities::ENEMY_RADIUS;
    }
    [[nodiscard]] auto isCollidable() const -> bool override {
        return esta_ && timer_invulnerabilitat_ <= 0.0F;
    }

    // Marcar destruido (desactiva el cuerpo físicamente: radius=0)
    void destruir();

    // Getters
    [[nodiscard]] auto getRotationDelta() const -> float { return drotacio_; }
    [[nodiscard]] auto getVelocityVector() const -> Vec2 { return body_.velocity; }

    // Set ship position reference for tracking behavior
    void setShipPosition(const Vec2* ship_pos) { ship_position_ = ship_pos; }

    // Stage system API (base stats)
    [[nodiscard]] auto getBaseVelocity() const -> float;
    [[nodiscard]] auto getBaseRotation() const -> float;
    [[nodiscard]] auto getType() const -> EnemyType { return type_; }

    // Setters para multiplicadores de dificultad (stage system).
    // Establecen la velocidad escalar deseada manteniendo la dirección
    // actual del body_.velocity.
    void setVelocity(float speed);
    void setRotation(float rot) {
        drotacio_ = rot;
        animacio_.drotacio_base = rot;
    }
    void setTrackingStrength(float strength);

    // Invulnerabilidad
    [[nodiscard]] auto isInvulnerable() const -> bool { return timer_invulnerabilitat_ > 0.0F; }
    [[nodiscard]] auto getInvulnerabilityTime() const -> float { return timer_invulnerabilitat_; }

    // Estado "herido": entre primer impacto de bala y explosión diferida.
    // shooter_id: id del jugador que herí; 0xFF = sin atribución (cadena, etc.).
    void herir(uint8_t shooter_id = 0xFF);
    [[nodiscard]] auto isWounded() const -> bool { return wounded_timer_ > 0.0F; }
    [[nodiscard]] auto getWoundedTimer() const -> float { return wounded_timer_; }
    [[nodiscard]] auto woundExpiredThisFrame() const -> bool { return wound_expired_this_frame_; }
    void consumeWoundExpired() { wound_expired_this_frame_ = false; }
    [[nodiscard]] auto getLastHitBy() const -> uint8_t { return last_hit_by_; }

    // Aplica un impulso (cambio inmediato de velocidad mass-aware) al cuerpo físico.
    void applyImpulse(const Vec2& impulse);

   private:
    // Miembros específicos (heredados: renderer_, shape_, center_, angle_, brightness_, body_).
    // Inicializados en la declaración: el ctor por defecto deja al enemy en estado "inactivo
    // como pentágono", coherente con lo que harán init() o el ctor con renderer al activarlo.
    float drotacio_{0.0F};  // Velocidad angular visual (rad/s) — solo decoración, separada de body_.angular_velocity
    float rotacio_{0.0F};   // Rotación visual acumulada (no afecta movimiento)
    bool esta_{false};

    EnemyType type_{EnemyType::PENTAGON};
    EnemyAnimation animacio_;

    // Comportamiento type-specific
    float tracking_timer_{0.0F};          // Quadrat: tiempo desde último update de dirección
    const Vec2* ship_position_{nullptr};  // Puntero a posición de la nave (para tracking)
    float tracking_strength_{0.0F};       // Quadrat: intensidad de tracking (0.0-1.5), default 0.5
    float direction_change_timer_{0.0F};  // Pentagon: tiempo para próximo cambio de dirección

    // Invulnerabilidad post-spawn
    float timer_invulnerabilitat_{0.0F};

    // Estado "herido": timer cuenta atrás; al cruzar 0 se marca expiración.
    float wounded_timer_{0.0F};
    bool wound_expired_this_frame_{false};
    uint8_t last_hit_by_{0xFF};  // 0xFF = sin atribución

    // Métodos privados
    void updateAnimation(float delta_time);
    void updatePalpitation(float delta_time);
    void updateRotationAcceleration(float delta_time);
    void behaviorPentagon(float delta_time);
    void behaviorQuadrat(float delta_time);
    void behaviorMolinillo(float delta_time);
    [[nodiscard]] auto computeCurrentScale() const -> float;
    // Estático: solo opera sobre ship_pos pasado; no consulta estado del enemy.
    static auto attemptSafeSpawn(const Vec2& ship_pos, float& out_x, float& out_y) -> bool;

    // Helper: setear body_.velocity desde un ángulo y magnitud.
    // angle_movement=0 apunta hacia arriba (eje Y negativo SDL).
    void setVelocityFromAngle(float angle_movement, float speed);
};
