// playfield.hpp - Fons del playfield (graella + sub-graella amb animació de creació)
// © 2026 JailDesigner
//
// La graella es construeix una sola vegada al constructor. El draw és stateless:
// rep un `creation_progress` global ∈ [0, 1] i cada línia computa quina porció
// li toca dibuixar segons el seu slot a la timeline.
//
// Disseny preparat per a futures capacitats:
//   - Línies "vives" que reaccionen a explosions / pas de la nau (reaction_intensity).
//   - Capes addicionals al fons (estrelles, gradients, scanlines).

#pragma once

#include <array>
#include <vector>

#include "core/defaults/playfield.hpp"
#include "core/rendering/render_context.hpp"
#include "core/types.hpp"

namespace Graphics {

    class Playfield {
       public:
        explicit Playfield(Rendering::Renderer* renderer);

        // Avança timers interns (creació + reaccions).
        void update(float delta_time);

        // Pinta la graella. La porció dibuixada de cada línia depèn del timer intern.
        void draw() const;

        // Notifica que una nau ha passat per (pos) a velocitat (speed_px_s).
        // Si està prop d'alguna línia i va prou ràpida, la línia entra en orbit.
        void notifyShipPass(Vec2 pos, float speed_px_s);

        // Notifica el spawn d'un firework a (pos). Les línies V i H més properes
        // generen un pulse brillant que es propaga.
        void notifyFireworkSpawn(Vec2 pos);

       private:
        struct Pulse {
            bool active{false};
            float center_t{0.5F};  // posició al llarg de la línia (0..1)
            float age_s{0.0F};
        };

        struct Line {
            Vec2 start;             // top (verticals) o left (horitzontals)
            Vec2 end;               // bottom (verticals) o right (horitzontals)
            float brightness;       // base (GRID_BRIGHTNESS o SUBGRID_BRIGHTNESS)
            float spawn_time_s;     // moment de naixement
            bool is_vertical;       // direcció (per saber el perpendicular de l'orbit)
            float orbit_amplitude;  // amplitud actual de l'orbit (px, ≥ 0)
            float orbit_phase;      // fase del sin (avança contínuament)
            std::array<Pulse, Defaults::Playfield::MAX_PULSES_PER_LINE> pulses;
        };

        void buildLines();
        [[nodiscard]] auto computeLineProgress(const Line& line) const -> float;
        static void spawnPulseAt(Line& line, float center_t);

        Rendering::Renderer* renderer_;
        std::vector<Line> lines_;
        float elapsed_s_{0.0F};
    };

}  // namespace Graphics
