#ifndef CATEGORY_VIEW_HPP_
#define CATEGORY_VIEW_HPP_

#include <Page/Page.hpp>
#include <RuntimeStateCache/RuntimeStateCache.hpp>
#include <Widget/Layout/CompoundWidget/CompoundWidget.hpp>
#include <Widget/Layout/CompoundWidget/IconText/IconText.hpp>
#include <Widget/Layout/CompoundWidget/ListBox/ListBox.hpp>
#include <Widget/Layout/Row/Row.hpp>
#include <Widget/Layout/ScrollPanel/ScrollPanel.hpp>
#include <Widget/Panel/Panel.hpp>
#include <Widget/Portal/Portal.hpp>
#include <memory>
#include <vector>

/**
 * @brief A widget which allows the user to view pages based on a left navigation panel.
 */
class CategoryView : public CompoundWidget
{
private:
    std::vector<Page*> pages;
    std::vector<size_t> pageIndexes;

    struct State
    {
        size_t selectedPageIndex = 0;
    };

    std::shared_ptr<State> state;

    void addPage(Page *page);

    constexpr void addPages() {}

    template<typename... TArgs>
    void addPages(Page *page, TArgs... rest)
    {
        if (page != nullptr)
        {
            addPage(page);
        }
        
        addPages(rest...);
    }

    template<typename... TArgs>
    void addPages(std::vector<Page*> morePages, TArgs... rest)
    {
        for (Page* page : morePages)
        {
            addPage(page);
        }

        addPages(rest...);
    }

public:
    template<typename... TArgs>
    CategoryView(std::string stateUrl, TArgs... pages)
    {
        state = RuntimeStateCache::get<State>(stateUrl);
        addPages(pages...);

        addChildren(
            new Row(
                Layout::WithProportion<1>(),
                new ListBox<size_t>(
                    pageIndexes,
                    state->selectedPageIndex,
                    [this](size_t index) -> Widget*
                    {
                        Page *page = this->pages[index];
                        return new IconText(page->icon, page->tip);
                    }
                ),

                new Panel(glm::ivec2(2, 0)),

                Layout::WithProportion<3>(),
                new Portal(
                    [this]() -> Widget*
                    {
                        return this->pages[this->state->selectedPageIndex]->body;
                    }
                )
            )
        );
    }

    virtual ~CategoryView();
};

#endif