local ReplicatedStorage = game:GetService("ReplicatedStorage")

local GameConfig = require(ReplicatedStorage.Shared.GameConfig)
local LootTables = require(ReplicatedStorage.Shared.LootTables)
local GridUtils = require(ReplicatedStorage.Shared.GridUtils)
local Economy = require(ReplicatedStorage.Shared.Economy)

local PlacementService = require(script.Parent.PlacementService)
local ConveyorService = require(script.Parent.ConveyorService)

local ZooService = {}
ZooService.__index = ZooService

local function consumeToken(state, tokenId)
	for index, token in ipairs(state.pendingEggTokens) do
		if token.tokenId == tokenId then
			table.remove(state.pendingEggTokens, index)
			return token
		end
	end
	return nil
end

function ZooService:TryBuyEgg(state, eggType)
	local offer = ConveyorService:FindOffer(state, eggType)
	if offer == nil then
		return false, "OfferUnavailable"
	end
	if state.coins < offer.price then
		return false, "NotEnoughCoins"
	end
	if LootTables.EggTypes[eggType] == nil then
		return false, "UnknownEgg"
	end

	state.coins -= offer.price
	local token = { tokenId = state.nextTokenId, eggType = eggType, boughtAt = os.time() }
	state.nextTokenId += 1
	table.insert(state.pendingEggTokens, token)
	return true, token
end

function ZooService:TryPlaceEgg(state, tokenId, x, y, nowUnix)
	local token = consumeToken(state, tokenId)
	if token == nil then
		return false, "InvalidToken"
	end

	local eggDef = LootTables.EggTypes[token.eggType]
	if eggDef == nil then
		error("ZooService: token contains unknown egg type")
	end

	local ok, reason = PlacementService:PlaceEgg(
		state,
		token.eggType,
		tokenId,
		x,
		y,
		nowUnix + eggDef.hatchSeconds,
		math.random(1, 2000000000)
	)
	if ok == false then
		table.insert(state.pendingEggTokens, token)
		return false, reason
	end

	return true, nil
end

function ZooService:TryUpgradePlot(state)
	if state.plotLevel >= GameConfig.Plot.MaxLevel then
		return false, "PlotMaxLevel"
	end
	local cost = Economy.GetPlotUpgradeCost(state.plotLevel)
	if state.coins < cost then
		return false, "NotEnoughCoins"
	end

	state.coins -= cost
	state.plotLevel += 1
	local width, height = GridUtils.PlotSizeFromLevel(state.plotLevel)
	state.grid.width = width
	state.grid.height = height
	return true, nil
end

return ZooService
