local function visItems(items)
	for k,v in ipairs(items) do
		term.setTextColor(colors.gray)
		if v.items and #v.items > 1 then
			term.write("\31 ")
		else
			term.write("  ")
		end
		if v.nbt then
			term.setTextColor(colors.purple)
		else
			term.setTextColor(colors.white)
		end
		term.write(v.name)
		term.setTextColor(colors.white)
		if v.count > 1 then
			textutils.pagedPrint(" ("..v.count..")")
		else
			textutils.pagedPrint("")
		end
	end
end

local lib = require("/User/Cloud/Public/Storage_Manager/api")

local x,y = term.getCursorPos()

local function wr(txt)
	term.setCursorPos(x,y)
	term.clearLine()
	term.setCursorPos(x,y)
	term.write(txt)
end

if not _G.setupCache then
	wr("Loading setup...")
	_G.setupCache = {lib.getSetup()}
end
local chests, input, output, furnaces = unpack(setupCache)

local inv
if not _G.invCache then
	wr("Loading inventory...")
	inv = lib.getInventory(chests)
	_G.invCache = inv
else
	inv = invCache
end

wr("")
local tArgs = {...}
if tArgs[1] == "list" then
	if not tArgs[2] then
		visItems(inv)
		return true
	elseif tArgs[2] == "tags" or tArgs[2] == "groups" then
		local tbl = {}
		local target = inv[tArgs[2]]
		for k,v in pairs(target) do
			table.insert(tbl, k)
		end
		table.sort(tbl)
		for i,t in ipairs(tbl) do
			textutils.pagedPrint(t)
		end
		return true
	elseif tArgs[2] == "tag" or tArgs[2] == "group" then
		if not tArgs[3] then
			print("Usage: storage list "..tArgs[2].." <"..tArgs[2]..">")
		else
			local target = inv[tArgs[2].."s"]
			if target[tArgs[3]] then
				visItems(target[tArgs[3]])
				return true
			else
				print("Could not find "..tArgs[2].." \""..tArgs[3].."\" (Note; tags and groups are case sensitive!)")
			end
		end
	else
		print("Usage: storage list <tags/groups/tag/group>")
	end
elseif tArgs[1] == "search" then
	if not tArgs[2] then
		print("Usage: storage search <search>")
	else
		local ls = {}
		local srch = tArgs[2]:lower()
		for i,item in ipairs(inv) do
			local found = false
			if item.name:lower():find(srch) then
				table.insert(ls, item)
			else
				for k,v in pairs(item.tags) do
					if k:lower():find(srch) then
						table.insert(ls, item)
						found = true
						break
					end
				end
				if not found then
					for k,v in pairs(item.groups) do
						if k:lower():find(srch) then
							table.insert(ls, item)
							found = true
							break
						end
					end
				end
			end
		end
		table.sort(ls, function(a,b) return a.name > b.name end)
		visItems(ls)
		return true
	end
elseif tArgs[1] == "reload" then
	wr("Reloading inventory...")
	inv = lib.getInventory(chests)
	_G.invCache = inv
	wr("Done!")
	print("")
	return true
elseif tArgs[1] == "smelt" then
	if not tArgs[2] or not tArgs[3] or not tonumber(tArgs[3]) then
		print("Usage: storage smelt <item> <amount>")
	else
		local update,err = lib.smeltItemAsync(tArgs[2],tonumber(tArgs[3]),furnaces,inv)
		if not update then
			print("Failed: "..err)
			return
		end

		while true do
			local done, progress, transferred = update()
			if done then
				wr("Reloading inventory...")
				inv = lib.getInventory(chests)
				_G.invCache = inv
				wr("Done!")
				print("")
				return true
			end
			wr("Transferred: ["..transferred.."]  Smelted: ["..progress.."]")
			os.sleep(5)
		end
		return
	end
elseif tArgs[1] == "supersmelt" then
	if not tArgs[2] or not tArgs[3] or not tonumber(tArgs[3]) then
		print("Usage: storage supersmelt <item> <amount>")
	else
		local total = tonumber(tArgs[3])
		local step = math.ceil(total/#furnaces)
	
		wr("Dividing "..total.." items over "..(#furnaces).." furnaces...")
		--os.sleep(1)
		local funcs = {}
		for t=1,#furnaces do
			--print(math.min(total, step).." in furnace "..peripheral.getName(furnaces[t]))
			--os.sleep(1)
			local update,err = lib.smeltItemAsync(tArgs[2], math.min(total, step), {furnaces[t]}, inv)
			if not update then
				print("Failed: "..err)
				return
			end
			table.insert(funcs, update)
			total = total-step
		end

		while true do
			local tProgress,tTransferred = 0, 0
			local allDone = true
			for _,func in ipairs(funcs) do
				local done,progress,transferred = func()
				if not done then
					allDone = false
					tProgress = tProgress + progress
					tTransferred = tTransferred + transferred
				end
			end
			if allDone then
				wr("Reloading inventory...")
				inv = lib.getInventory(chests)
				_G.invCache = inv
				wr("Done!")
				print("")
				return true
			end
			wr("Transferred: ["..tTransferred.."]  Smelted: ["..tProgress.."]")
			os.sleep(5)
		end
	end
else
	print("Usage: storage <list/search/reload/smelt/supersmelt>")
end

print("Note: Parameters with spaces need to be enclosed in quotation marks.\nExample: storage list group \"Building Blocks\"")