#pragma once

#include "foundation/result.h"
#include "ui_core/node_lifetime.h"

#include <cstdint>
#include <cstddef>
#include <vector>

namespace pp::ui {

enum class UiOverlayKind : std::uint8_t {
    popup,
    dialog,
};

struct UiOverlayEntry {
    NodeHandle node {};
    NodeHandle parent {};
    UiOverlayKind kind = UiOverlayKind::popup;
    bool captures_pointer = false;
    bool captures_keyboard = false;
};

class UiOverlayLifetime {
public:
    UiOverlayLifetime(NodeLifetimeTree& tree, NodeHandle root) noexcept;

    [[nodiscard]] pp::foundation::Result<NodeHandle> open_popup();
    [[nodiscard]] pp::foundation::Result<NodeHandle> open_child_popup(NodeHandle parent_popup);
    [[nodiscard]] pp::foundation::Result<NodeHandle> open_dialog(bool modal);
    [[nodiscard]] pp::foundation::Status close(NodeHandle overlay) noexcept;
    void clear_for_layout_reload() noexcept;

    [[nodiscard]] bool tracks(NodeHandle overlay) const noexcept;
    [[nodiscard]] std::size_t overlay_count() const noexcept;
    [[nodiscard]] pp::foundation::Result<NodeHandle> top_overlay() const noexcept;

private:
    [[nodiscard]] pp::foundation::Result<NodeHandle> open_overlay(
        NodeHandle parent,
        UiOverlayKind kind,
        bool captures_pointer,
        bool captures_keyboard);
    void prune_dead_entries() noexcept;
    void restore_capture(UiCaptureKind kind) noexcept;
    [[nodiscard]] bool tracked_alive(NodeHandle overlay) const noexcept;

    NodeLifetimeTree& tree_;
    NodeHandle root_ {};
    std::vector<UiOverlayEntry> entries_;
};

}
