-- Portal Pro :: Modules/Reagents.lua
-- Rune counting and cost basis. Without this the ledger reports gross, not profit.

local ADDON_NAME, PP = ...
local U, C = PP.U, PP.C

local R = PP:NewModule("Reagents")
PP.Reagents = R

R.RUNE_TELEPORT = 17031 -- Rune of Teleportation
R.RUNE_PORTAL   = 17032 -- Rune of Portals

local lastCount = { [R.RUNE_TELEPORT] = 0, [R.RUNE_PORTAL] = 0 }
local warned = false

local refreshPending = false

function R:OnEnable()
	self:Refresh()

	-- BAG_UPDATE fires several times per loot or vendor transaction. Coalesce into one
	-- refresh per frame so a full-bag update doesn't rescan six times.
	local function schedule()
		if refreshPending then return end
		refreshPending = true
		C_Timer.After(0, function()
			refreshPending = false
			R:Refresh()
		end)
	end

	PP:RegisterEvent("BAG_UPDATE_DELAYED", schedule)
	PP:RegisterEvent("BAG_UPDATE", schedule)
end

function R:Count(kind)
	local id = (kind == "teleport") and self.RUNE_TELEPORT or self.RUNE_PORTAL
	return C.ItemCount(id)
end

function R:PortalCount()   return C.ItemCount(self.RUNE_PORTAL) end
function R:TeleportCount() return C.ItemCount(self.RUNE_TELEPORT) end

--- Configured unit cost in copper for one cast of the given kind.
function R:UnitCost(kind)
	local cfg = PP.profile and PP.profile.reagents
	if not cfg then return 0 end
	if kind == "teleport" then return cfg.teleportCost or 0 end
	return cfg.portalCost or 0
end

--- Re-read counts and warn once when stock crosses the low threshold.
function R:Refresh()
	if not PP.profile then return end
	local portal   = self:PortalCount()
	local teleport = self:TeleportCount()

	local changed = (portal ~= lastCount[self.RUNE_PORTAL]) or (teleport ~= lastCount[self.RUNE_TELEPORT])
	lastCount[self.RUNE_PORTAL]   = portal
	lastCount[self.RUNE_TELEPORT] = teleport

	if changed then
		PP:Fire("REAGENTS_CHANGED", portal, teleport)
	end

	local threshold = PP.profile.reagents and PP.profile.reagents.lowWarning or 5
	if portal <= threshold then
		if not warned and portal > 0 then
			warned = true
			PP:Warn(("Low on Rune of Portals - %d left."):format(portal))
		elseif portal == 0 and not warned then
			warned = true
			PP:Warn("Out of Rune of Portals. You can't open portals until you restock.")
		end
	elseif portal > threshold then
		warned = false
	end
end

--- Can the player cast right now? Returns false plus a reason string.
function R:CanCast(kind)
	if self:Count(kind) <= 0 then
		local item = (kind == "teleport") and "Rune of Teleportation" or "Rune of Portals"
		return false, "No " .. item
	end
	return true
end

--- How many more casts the current stock supports.
function R:Remaining(kind)
	return self:Count(kind)
end
