#pragma once

#include "core/jail/jdraw8.hpp"

namespace Scenes {

    // Wrapper RAII damunt de `Jd8::Surface`. Allibera automàticament amb
    // `Jd8::freeSurface` al destructor. Move-only per evitar dobles alliberaments.
    // Converteix implícitament a `Jd8::Surface` per a poder passar-lo
    // directament a `Jd8::blit*` sense haver de cridar `.get()`.
    class SurfaceHandle {
       public:
        SurfaceHandle() = default;
        explicit SurfaceHandle(const char* file);
        ~SurfaceHandle();

        SurfaceHandle(const SurfaceHandle&) = delete;
        auto operator=(const SurfaceHandle&) -> SurfaceHandle& = delete;

        SurfaceHandle(SurfaceHandle&& other) noexcept;
        auto operator=(SurfaceHandle&& other) noexcept -> SurfaceHandle&;

        // Allibera la surface actual (si n'hi ha) i carrega una nova.
        // Usat per escenes que recarreguen assets a mitja cinemàtica
        // (p.ex. doSecreta que passa de tomba1 a tomba2).
        void reset(const char* file);

        // Adopta una surface ja creada (p.ex. amb Jd8::newSurface). Pren ownership
        // — la surface adoptada s'allibera al destructor o al següent reset/adopt.
        void adopt(Jd8::Surface raw);

        // Allibera ownership sense destruir la surface. Retorna el pointer cru;
        // el caller passa a ser responsable d'alliberar-lo (o de passar-lo a un
        // altre propietari). Usat quan una escena delega a codi legacy que
        // també allibera la mateixa surface — cal "soltar" el ownership per
        // evitar double free.
        [[nodiscard]] auto release() -> Jd8::Surface;

        // Conversió implícita per al confort d'ús: Jd8::blit(handle)
        // en lloc de Jd8::blit(handle.get()).
        operator Jd8::Surface() const { return surface_; }
        [[nodiscard]] auto get() const -> Jd8::Surface { return surface_; }
        [[nodiscard]] auto valid() const -> bool { return surface_ != nullptr; }

       private:
        Jd8::Surface surface_{nullptr};
    };

}  // namespace Scenes
