// notifier.hpp - Sistema de notificacions toast (singleton)
// © 2026 JailDesigner
//
// Mostra missatges curts en un cuadre centrat horitzontalment al centre
// superior de la pantalla. El cuadre entra des de fora amb easing outCubic,
// aguanta el temps demanat i surt amb inCubic. El color del text és
// configurable; el fondo es deriva oscurint el RGB del text i posant alpha
// 0.65 (semitransparent).
//
// API singleton (mateix patró que Audio i Input): Notifier::init() al startup,
// Notifier::get()->notify(...) des d'on calgui, Notifier::destroy() al teardown.

#pragma once

#include <SDL3/SDL.h>

#include <cstdint>
#include <memory>
#include <string>

#include "core/graphics/vector_text.hpp"
#include "core/rendering/render_context.hpp"

namespace System {

    class Notifier {
       public:
        // Inicialitza el singleton amb el renderer global. El renderer ha de
        // viure tant com el Notifier (és del SDLManager, propietat del Director).
        static void init(Rendering::Renderer* renderer);
        static void destroy();
        [[nodiscard]] static auto get() -> Notifier*;

        // Mostra una notificació. Si ja n'hi ha una visible, es sobreescriu
        // (reset a l'estat ENTERING des de la Y actual; mai s'apilen).
        // - text: cadena a mostrar (sense salts de línia)
        // - text_color: color RGBA del text i del borde
        // - duration_s: temps que es queda visible (sense comptar entry/exit)
        void notify(const std::string& text, SDL_Color text_color, float duration_s);

        // Atajos semàntics amb colors i durada predefinits.
        void notifyInfo(const std::string& text);  // blanc, 2.0s
        void notifyWarn(const std::string& text);  // àmbar, 3.0s
        void notifyExit(const std::string& text);  // vermell, EXIT_WINDOW_S

        void update(float delta_time);
        void draw() const;

        // Activa mentre el toast està entrant o aguantant. Quan està sortint
        // o ja amagat, retorna false.
        [[nodiscard]] auto isActiveWindow() const -> bool;

        // Cert només si el toast actiu va ser disparat per notifyExit().
        // Per a la doble-pulsació d'ESC: la segona ESC confirma sortida
        // únicament si la notificació visible és la de confirmació; si era
        // de F1/F2/etc., ESC torna a obrir el prompt sense tancar.
        [[nodiscard]] auto isExitPromptActive() const -> bool;

       private:
        explicit Notifier(Rendering::Renderer* renderer);

        enum class Status : std::uint8_t { HIDDEN,
            ENTERING,
            HOLDING,
            EXITING };

        Rendering::Renderer* renderer_;
        Graphics::VectorText text_;

        Status status_{Status::HIDDEN};
        std::string current_text_;
        SDL_Color current_color_{.r = 255, .g = 255, .b = 255, .a = 255};
        float hold_remaining_s_{0.0F};
        float slide_elapsed_s_{0.0F};
        float y_current_{0.0F};
        float y_off_{0.0F};  // posició Y fora de pantalla
        float y_on_{0.0F};   // posició Y de descans (visible)
        float box_w_{0.0F};
        float box_h_{0.0F};
        float text_x_{0.0F};  // X esquerre del text dins la caixa
        float text_scale_{0.4F};
        bool current_is_exit_{false};  // true només si l'actiu ve de notifyExit()

        static std::unique_ptr<Notifier> instance;
    };

}  // namespace System
