#ifndef MURANIUM_REFINERY_HPP_
#define MURANIUM_REFINERY_HPP_

#include <Machine/IElectricMachine.hpp>
#include <Machine/IFluidMachine.hpp>
#include <vector>
#include <Machine/Machine.hpp>
#include <ItemStack/ItemStack.hpp>
#include <Item/IInventory.hpp>
#include <Machine/IBeltMachine.hpp>

class MUraniumRefinery final :
    public Machine,
    public IInventory,
    public IBeltMachine,
    public IElectricMachine,
    public IFluidMachine
{
private:
    std::vector<ItemStack> stacks;
    int progress = 0;

    ItemStack& inputSlot();
    ItemStack& rechargeSlot();
    bool cycle();

public:
    static constexpr int energyCapacity = 1000;
    static constexpr int completedProgress = 300;
    static constexpr int refuCapacity = 20000;
    static constexpr int powerUsage = 50;
    static constexpr int refuPerDust = 500;

    MUraniumRefinery(LocalWorld &world, glm::ivec3 pos);

    int getEnergy();
    int getProgress();
    int getRefuAmount();

    virtual void serializeState(std::vector<uint8_t> &outBytes) override;
    virtual void deserializeState(const uint8_t *data, size_t size) override;
    virtual int getNumSlots() override;
    virtual ItemStack getStackInSlot(int slot) override;
    virtual void setStackInSlot(int slot, ItemStack stack) override;
    virtual bool isAllowedStackInSlot(int slot, ItemStack stack) override;
    virtual void onItemStackEntering(Side side, ItemStack &stack) override;
    virtual ItemStack tryExtractItem(Side side, ItemFilter &filter, uint32_t modeCode) override;
    virtual bool canConnectExtractor(Side side) override;
    virtual void update() override;
    virtual bool canConnectElectricWire(Side side) override;
    virtual bool canConnectFluidPipe(Side side) override;
    virtual int getMaxFluidToRelease(std::optional<Side> side, std::string fluidName) override;
};

#endif