// enemy_ai.hpp - Sistema declaratiu d'IA per a enemics
// © 2026 JailDesigner
//
// Cada enemic declara al seu YAML quin movement primitiu fa servir i, opcional-
// ment, una llista d'accions periòdiques (tick). El motor només dispatcha; el
// comportament viu a les dades. Patró paral·lel al d'events declaratius
// (enemy_event.hpp).

#pragma once

#include <cstdint>
#include <string>
#include <vector>

// Primitiva de moviment activa per a un enemic. Substitueix el switch
// hardcoded sobre EnemyType.
enum class MovementType : uint8_t {
    ZIGZAG,                 // Canvi de direcció probabilístic agressiu (Pentagon/Star)
    TRACKING,               // LERP discret cap al ship cada N segons (Square)
    RECTILINEAR_PROXIMITY,  // Rectilini + boost rotació visual prop del ship (Pinwheel)
    WANDER,                 // Canvi de direcció probabilístic suau, sense target
    CHASE,                  // Steering continu cap al ship més proper
    FLEE,                   // Steering continu allunyant-se del ship més proper
};

// Accions que s'executen periòdicament (un timer per acció). Futur (Fase C):
// SHOOT amb aim_mode/jitter/bullet config.
enum class AiActionType : uint8_t {
    SHOOT,
};

enum class AimMode : uint8_t {
    RANDOM,  // Angle uniformement aleatori
    AIMED,   // atan2(nearest_ship - center) + soroll gaussià (jitter_rad)
};

// Camps de tots els movements; només el subset rellevant per al type actiu
// s'usa. Els altres queden a 0.0F. Mateixa filosofia que la BehaviorCfg
// llegacy però amb el type explícit dins.
struct MovementConfig {
    MovementType type{MovementType::ZIGZAG};

    // ZIGZAG i WANDER (canvi de direcció probabilístic; comparteixen camps).
    float angle_change_max{0.0F};
    float zigzag_prob_per_second{0.0F};

    // TRACKING
    float tracking_strength{0.0F};
    float tracking_interval{0.0F};

    // RECTILINEAR_PROXIMITY
    float rotation_proximity_multiplier{0.0F};
    float proximity_distance{0.0F};

    // CHASE / FLEE: força del steering per segon (LERP velocity ↔ direcció ideal).
    // 1.0 = en ~1s la velocitat queda totalment realineada cap al target.
    float chase_strength{0.0F};
    float flee_strength{0.0F};
};

// Acció periòdica. interval = segons entre disparades; el dispatcher manté un
// timer per acció (paral·lel a aquesta llista) i dispara quan arriba a 0.
struct AiTickAction {
    AiActionType type{AiActionType::SHOOT};
    float interval{1.0F};
    AimMode aim_mode{AimMode::RANDOM};
    float jitter_rad{0.0F};
    float bullet_speed{200.0F};      // px/s; la magnitud la decideix l'enemic, no el bullet config
    std::string bullet_config_name;  // bullet config a usar (lazy-load des de BulletRegistry)
};

struct EnemyAiConfig {
    MovementConfig movement;
    std::vector<AiTickAction> tick;
};

// Estat per-instància que la primitiva de moviment manté entre frames (timers
// d'interval, contadors de canvi de direcció...). Es viu dins de Enemy i el
// sistema d'IA hi escriu via getAiState().
struct EnemyAiState {
    float direction_change_timer{0.0F};  // ZIGZAG
    float tracking_timer{0.0F};          // TRACKING
    float tracking_strength{0.0F};       // TRACKING (cau de cfg, mutable per dificultat)
};
