local ReplicatedStorage = game:GetService("ReplicatedStorage")

local GameConfig = require(ReplicatedStorage.Shared.GameConfig)
local LootTables = require(ReplicatedStorage.Shared.LootTables)
local MutationRules = require(ReplicatedStorage.Shared.MutationRules)
local WeightedRandom = require(ReplicatedStorage.Shared.WeightedRandom)
local BiomeRules = require(ReplicatedStorage.Shared.BiomeRules)
local GridUtils = require(ReplicatedStorage.Shared.GridUtils)

local HatchingService = {}
HatchingService.__index = HatchingService

local function buildAnimalCell(animalId, mutationId, nowUnix)
	return {
		kind = "animal",
		id = animalId,
		mutation = mutationId,
		level = 1,
		placedAt = nowUnix,
	}
end

function HatchingService:TryHatchCell(state, x, y, nowUnix, eventModifiers)
	local key = GridUtils.CellKey(x, y)
	local cell = state.grid.cells[key]
	if cell == nil or cell.kind ~= "egg" then
		return false
	end
	if nowUnix < cell.hatchAt then
		return false
	end

	local eggDef = LootTables.EggTypes[cell.eggType]
	if eggDef == nil then
		error("HatchingService: unknown egg type in state")
	end

	local rng = Random.new(cell.seed)
	local pickedAnimalId = WeightedRandom.PickId(rng, eggDef.loot)
	local animalDef = LootTables.Animals[pickedAnimalId]
	if animalDef == nil then
		error("HatchingService: unknown animal from loot table")
	end

	local cellBiome = BiomeRules.GetCellBiome(state.grid.width, x)
	if BiomeRules.IsAnimalAllowedOnBiome(animalDef.biome, cellBiome) == false then
		state.grid.cells[key] = nil
		return true
	end

	local mutationChance = GameConfig.Mutation.BaseChance + eventModifiers.mutationBonus
	local mutationId = "none"
	if rng:NextNumber(0, 1) < mutationChance then
		mutationId = WeightedRandom.PickId(rng, MutationRules:GetMutationEntries())
	end

	state.grid.cells[key] = buildAnimalCell(pickedAnimalId, mutationId, nowUnix)
	return true
end

function HatchingService:Run(state, nowUnix, eventModifiers)
	local changed = false
	for key, cell in pairs(state.grid.cells) do
		if cell.kind == "egg" and nowUnix >= cell.hatchAt then
			local xText, yText = string.match(key, "^(%d+)_(%d+)$")
			if xText ~= nil and yText ~= nil then
				local hatched = self:TryHatchCell(state, tonumber(xText), tonumber(yText), nowUnix, eventModifiers)
				if hatched then
					changed = true
				end
			end
		end
	end
	return changed
end

return HatchingService
