
#include <Color/Color.hpp>
#include <FuelRuleRegistry/FuelRuleRegistry.hpp>
#include <ItemFilter/ItemFilterByName/ItemFilterByName.hpp>
#include <ItemRegistry/ItemRegistry.hpp>
#include <ItemStack/ItemStack.hpp>
#include <Material/Material.hpp>
#include <Widget/IconLabel/IconLabel.hpp>
#include <Widget/Label/Label.hpp>
#include <Widget/Layout/Center/Center.hpp>
#include <Widget/Layout/CompoundWidget/Deck/Deck.hpp>
#include <Widget/Layout/CompoundWidget/Explorer/Explorer.hpp>
#include <Widget/Layout/CompoundWidget/FuelRuleExplorer/FuelRuleExplorer.hpp>
#include <Widget/Layout/Row/Row.hpp>
#include <Widget/Panel/Panel.hpp>
#include <Widget/StaticItemSlot/StaticItemSlot.hpp>

void FuelRuleExplorer::buildRuleCache()
{
    std::vector<ItemStack> allStacks;
    itemRegistry.getAllStacks(allStacks);

    for (ItemStack &stack : allStacks)
    {
        if (!fuelRuleRegistry.isValidFuel(stack))
        {
            continue;
        }

        uint32_t amount = fuelRuleRegistry.getFuelAmount(stack);
        rules.push_back({stack, amount});
    }

    std::sort(rules.begin(), rules.end(), [](const Rule &a, const Rule &b) {
        return a.fuelAmount < b.fuelAmount;
    });
}

FuelRuleExplorer::FuelRuleExplorer()
{
    if (rules.empty())
    {
        buildRuleCache();
    }

    addChildren(
        new Explorer<Rule>(
            "/fuel-rule-explorer",
            [this](std::string query)
            {
                std::vector<Rule> results;
                ItemFilterByName filter(query);

                for (Rule &rule : rules)
                {
                    if (filter.matches(rule.stack))
                    {
                        results.push_back(rule);
                    }
                }

                return results;
            },

            [](Rule rule) -> Widget*
            {
                return new Deck<Row, Center>(
                    new StaticItemSlot(
                        [rule]()
                        {
                            return rule.stack;
                        }
                    ),
                    new IconLabel(Material::rightArrow),
                    new Panel(glm::ivec2(2, 0)),
                    new Label(
                        formatString("$+ units", rule.fuelAmount),
                        Color::fuelStat
                    )
                );
            }
        )
    );
}