// logo_scene.hpp - Pantalla de start del juego
// Muestra logo JAILGAMES animat con zoom i salta al juego
// © 2026 JailDesigner

#pragma once

#include <SDL3/SDL.h>

#include <array>
#include <cstdint>
#include <memory>
#include <vector>

#include "core/defaults.hpp"
#include "core/graphics/shape.hpp"
#include "core/rendering/sdl_manager.hpp"
#include "core/system/scene.hpp"
#include "core/system/scene_context.hpp"
#include "core/types.hpp"
#include "game/effects/debris_manager.hpp"

class LogoScene final : public Scene {
   public:
    explicit LogoScene(SDLManager& sdl, SceneManager::SceneContext& context);
    ~LogoScene() override;  // Destructor per aturar sons

    // Scene interface
    void handleEvent(const SDL_Event& event) override;
    void update(float delta_time) override;
    void draw() override;
    [[nodiscard]] auto isFinished() const -> bool override;

   private:
    // Màquina de estats per l'animación
    enum class AnimationState : std::uint8_t {
        PRE_ANIMATION,   // Pantalla negra inicial
        ANIMATION,       // Animación de zoom de lletres
        POST_ANIMATION,  // Logo complet visible
        EXPLOSION,       // Explosión seqüencial de lletres
        POST_EXPLOSION   // Espera después de l'última explosión
    };

    SDLManager& sdl_;
    SceneManager::SceneContext& context_;
    AnimationState current_state_{AnimationState::PRE_ANIMATION};  // Estat actual de la màquina
    float
        temps_current_state_{0.0F};  // Temps en l'state actual (reset en cada transición)

    // Gestor de fragments de explosions
    std::unique_ptr<Effects::DebrisManager> debris_manager_;

    // Seguiment de explosions seqüencials
    size_t letter_explosion_index_{0};       // Índex de la següent letter a explode
    float time_since_last_explosion_{0.0F};  // Temps desde l'última explosión
    std::vector<size_t> explosion_order_;    // Ordre aleatori de índexs de lletres

    // Estructura para cada letter del logo
    struct LogoLetter {
        std::shared_ptr<Graphics::Shape> shape;
        Vec2 position;        // Posición final en pantalla
        float width;          // Ancho del bounding box
        float center_offset;  // Distancia de min_x a shape_centre.x
    };

    std::vector<LogoLetter> letters_;  // 9 lletres: J-A-I-L-G-A-M-E-S

    // Seguiment de sons de lletres (evitar reproduccions repetides)
    std::array<bool, 9> sound_played_;  // Track si cada letter ya ha reproduit el so

    // Cicle d'atracció: si en entrar al logo ja hi ha música sonant (venim de la
    // demo amb title.ogg en marxa), el logo no ha d'emetre sons ni reiniciar la
    // música — només repintar-se en silenci.
    bool attract_silent_{false};

    // Constants de animación
    static constexpr float DURATION_PRE = 1.5F;             // Duració PRE_ANIMATION (pantalla negra)
    static constexpr float DURATION_ZOOM = 4.0F;            // Duració del zoom (segons)
    static constexpr float DURATION_POST_ANIMATION = 3.0F;  // Duració POST_ANIMATION (logo complet)
    static constexpr float DURATION_POST_EXPLOSION = 3.0F;  // Duració POST_EXPLOSION (espera final)
    static constexpr float DELAY_ENTRE_EXPLOSIONS = 0.1F;   // Temps entre explosions de lletres
    static constexpr float SPEED_EXPLOSIO = 240.0F;         // Velocidad base fragments (px/s)
    static constexpr float INITIAL_SCALE = 0.1F;            // Escala inicial (10%)
    static constexpr float FINAL_SCALE = 0.8F;              // Escala final (80%)
    static constexpr float LETTER_SPACING = 10.0F;          // Espaiat entre lletres

    // Constants de animación seqüencial
    static constexpr float LETTER_THRESHOLD = 0.6F;                        // Umbral per activar següent letter (0.0-1.0)
    static constexpr float ZOOM_ORIGIN_X = Defaults::Game::WIDTH * 0.5F;   // Vec2 inicial X del zoom
    static constexpr float ZOOM_ORIGIN_Y = Defaults::Game::HEIGHT * 0.4F;  // Vec2 inicial Y del zoom

    // Métodos privats
    void initLetters();
    void updateExplosions(float delta_time);
    // Estático: solo consulta Input (singleton), no estado de la escena.
    static auto checkSkipButtonPressed() -> bool;

    // Métodos de gestió de estats
    void changeState(AnimationState nou_estat);
    [[nodiscard]] auto allLettersComplete() const -> bool;
};
