// enemy_config.hpp - Configuració d'un tipus d'enemic carregada des de YAML
// © 2026 JailDesigner
//
// Una instància per tipus (Pentagon/Square/Pinwheel), carregada un cop al
// startup per EnemyRegistry i compartida entre totes les instàncies d'aquell
// tipus. Estructura paral·lela a PlayerConfig.

#pragma once

#include <SDL3/SDL.h>

#include <optional>
#include <string>

#include "external/fkyaml_node.hpp"
#include "game/entities/enemy.hpp"  // EnemyType
#include "game/entities/enemy_ai.hpp"
#include "game/entities/enemy_event.hpp"

struct EnemyConfig {
    struct ShapeCfg {
        std::string path;
        float scale;             // multiplicador visual + hitbox sobre la mida nativa del .shp
        float collision_factor;  // ajust opcional del hitbox respecte el cercle circumscrit (default 1.0)
    };

    struct PhysicsCfg {
        float mass;
        float speed;
        float rotation_delta_min;
        float rotation_delta_max;
        float restitution;     // rebot contra parets (1.0 = perfectament elàstic)
        float linear_damping;  // fricció lineal (s^-1)
        float angular_damping;
    };

    // Camps específics de cada AI. Els no aplicables a un tipus queden a 0.0F
    // i no s'usen — el dispatch viu a Enemy::behaviorXxx.
    struct BehaviorCfg {
        // Pentagon
        float zigzag_prob_per_second{0.0F};
        float angle_change_max{0.0F};
        // Square
        float tracking_strength{0.0F};
        float tracking_interval{0.0F};
        // Pinwheel
        float rotation_proximity_multiplier{0.0F};
        float proximity_distance{0.0F};
    };

    // Animacions decoratives. Compartides estructuralment entre tots els tipus
    // però amb valors propis per personalitzar la "personalitat" visual de cada un.
    struct AnimationCfg {
        struct PulseCfg {
            float trigger_prob_per_second;  // probabilitat per segon d'iniciar un pulse
            float duration_min;
            float duration_max;
            float amplitude_min;  // amplitud d'escala (±)
            float amplitude_max;
            float frequency_min;  // Hz
            float frequency_max;
        };
        struct RotationAccelCfg {
            float trigger_prob_per_second;
            float duration_min;  // segons de transició al nou speed
            float duration_max;
            float multiplier_min;  // multiplicador sobre rotation_delta_base
            float multiplier_max;
        };
        PulseCfg pulse;
        RotationAccelCfg rotation_accel;
    };

    struct WoundedCfg {
        float duration;  // segons en estat ferit abans d'explotar
        float blink_hz;  // freqüència del parpelleig color normal ↔ wounded
    };

    struct SpawnCfg {
        float invulnerability_duration;          // segons d'invulnerabilitat post-spawn
        float invulnerability_brightness_start;  // brightness inicial (corba LERP)
        float invulnerability_brightness_end;    // brightness final
        float invulnerability_scale_start;       // escala inicial (corba LERP, 0 = invisible)
        float invulnerability_scale_end;         // escala final (1 = mida nativa)
        float safety_distance;                   // px mínim respecte al player al spawn
    };

    struct ColorsCfg {
        SDL_Color normal;
        SDL_Color wounded;
    };

    std::string name;
    EnemyType ai_type;
    ShapeCfg shape;
    PhysicsCfg physics;
    BehaviorCfg behavior;
    AnimationCfg animation;
    WoundedCfg wounded;
    SpawnCfg spawn;
    ColorsCfg colors;
    int score;
    // Salut inicial: per defecte 1 (un balazo → on_no_health). Els YAMLs poden
    // pujar-lo (p.ex. 10 per a un enemic tough). El sistema d'events és qui
    // decideix què passa quan la salut arriba a 0 via on_no_health.
    int health{1};
    EnemyEventConfig events;
    EnemyAiConfig ai;

    // Parseja un descriptor d'enemic. expected_ai_type valida que ai_type del
    // YAML coincideix amb el tipus que el caller espera (segons el directori).
    static auto fromYaml(const fkyaml::node& node, EnemyType expected_ai_type)
        -> std::optional<EnemyConfig>;
};
