#pragma once

#include <functional>
#include <vector>

namespace Scenes {

    // Timeline declaratiu de passos seqüencials. Cada pas té una duració en
    // ms i un callback. Exemple d'ús:
    //
    //   timeline_
    //       .once([this] { Jd8::clearScreen(0); fade_.startFadeTo(pal); })
    //       .step(5000)                              // espera pura
    //       .step(1000, [this](float p) { /*...*/ }) // animat amb progress
    //       .once([this] { Ja::fadeOutMusic(250); });
    //
    // `tick(delta_ms)` avança el temps. Els passos one-shot s'executen al
    // moment d'entrar-hi i avancen immediatament. Els passos amb duració
    // criden el seu callback cada tick amb el progress [0..1] i passen al
    // següent quan s'exhaureix el temps. `skip()` marca tota la timeline
    // com a acabada (no executa res més) — útil per als "polsa una tecla
    // per a saltar la cinemàtica".
    class Timeline {
       public:
        using StepFn = std::function<void(float progress_0_1)>;
        using OnceFn = std::function<void()>;

        auto step(int duration_ms, StepFn fn = nullptr) -> Timeline&;
        auto once(OnceFn fn) -> Timeline&;

        void tick(int delta_ms);
        void skip();
        void reset();

        [[nodiscard]] auto done() const -> bool;
        [[nodiscard]] auto currentStepIndex() const -> int { return static_cast<int>(current_); }
        [[nodiscard]] auto currentProgress() const -> float;

       private:
        struct Step {
            int duration_ms{0};  // 0 = one-shot
            StepFn continuous;
            OnceFn oneshot;
            bool entered{false};
        };

        // Avança els one-shots consecutius des de `current_` fins a trobar
        // un pas amb duració > 0 o l'endoll de la llista.
        void flushOneShots();

        std::vector<Step> steps_;
        std::size_t current_{0};
        int elapsed_in_step_{0};
        bool skipped_{false};
    };

}  // namespace Scenes
