local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local remotes = ReplicatedStorage:WaitForChild("Remotes")
local Texts = require(ReplicatedStorage.Shared.Texts)
local t = Texts.Get(Texts.defaultLocale)

local requestState = remotes:WaitForChild("RequestState") :: RemoteFunction
local requestBuyEgg = remotes:WaitForChild("RequestBuyEgg") :: RemoteFunction
local requestUpgrade = remotes:WaitForChild("RequestUpgrade") :: RemoteFunction
local sellAnimal = remotes:WaitForChild("SellAnimal") :: RemoteFunction
local placeEggRemote = remotes:WaitForChild("PlaceEgg") :: RemoteEvent
local stateSync = remotes:WaitForChild("StateSync") :: RemoteEvent

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "BuildAZooHUD"
screenGui.ResetOnSpawn = false
screenGui.Parent = playerGui

local panel = Instance.new("Frame")
panel.Name = "Panel"
panel.Size = UDim2.new(0, 360, 0, 360)
panel.Position = UDim2.new(0, 10, 0, 10)
panel.Parent = screenGui

local function mkLabel(y, h, text)
	local label = Instance.new("TextLabel")
	label.Size = UDim2.new(1, -10, 0, h)
	label.Position = UDim2.new(0, 5, 0, y)
	label.TextXAlignment = Enum.TextXAlignment.Left
	label.Text = text
	label.Parent = panel
	return label
end

local status = mkLabel(5, 30, t.hudLoading)
local gridHint = mkLabel(40, 26, t.placementHint)
local conveyorHint = mkLabel(68, 22, t.conveyorHint)

local conveyorFrame = Instance.new("Frame")
conveyorFrame.Size = UDim2.new(1, -10, 0, 72)
conveyorFrame.Position = UDim2.new(0, 5, 0, 95)
conveyorFrame.Parent = panel

local offerButtons = {}
for index = 1, 3 do
	local btn = Instance.new("TextButton")
	btn.Name = "Offer" .. tostring(index)
	btn.Size = UDim2.new(0, 110, 0, 62)
	btn.Position = UDim2.new(0, (index - 1) * 120, 0, 5)
	btn.TextWrapped = true
	btn.Parent = conveyorFrame
	offerButtons[index] = btn
end

local function button(name, y, label)
	local b = Instance.new("TextButton")
	b.Name = name
	b.Size = UDim2.new(1, -10, 0, 28)
	b.Position = UDim2.new(0, 5, 0, y)
	b.Text = label
	b.Parent = panel
	return b
end

local upConveyor = button("UpgradeConveyor", 172, "Upgrade Conveyor")
local upPlot = button("UpgradePlot", 204, "Upgrade Plot")
local sellAt = button("SellAt", 236, "Sell animal at selected cell")

local selectedCellX = 1
local selectedCellY = 1
local pendingTokenByEggType = {}
local currentState = {}
local conveyorOffset = 0

local function clampSelection()
	local width = currentState.grid and currentState.grid.width or 1
	local height = currentState.grid and currentState.grid.height or 1
	selectedCellX = math.clamp(selectedCellX, 1, width)
	selectedCellY = math.clamp(selectedCellY, 1, height)
end

local function updateStatus(localState)
	status.Text = string.format(
		t.statusTemplate,
		localState.coins or 0,
		localState.plotLevel or 1,
		localState.conveyorLevel or 1,
		selectedCellX,
		selectedCellY,
		localState.pendingEggTokens or 0
	)
end

local function buyEgg(eggType)
	local buyOk, tokenOrReason = requestBuyEgg:InvokeServer(eggType)
	if buyOk == false then
		status.Text = string.format(t.buyFailed, tostring(tokenOrReason))
		return
	end
	pendingTokenByEggType[eggType] = tokenOrReason.tokenId
	status.Text = string.format(t.boughtToken, eggType, tokenOrReason.tokenId)
end

local function renderOffers(state)
	for index, buttonInstance in ipairs(offerButtons) do
		local offer = state.conveyorOffers and state.conveyorOffers[index]
		if offer == nil then
			buttonInstance.Text = t.noOffer
			buttonInstance.AutoButtonColor = false
			buttonInstance.Active = false
		else
			buttonInstance.Text = string.format("%s\n%d coins", offer.eggType, offer.price)
			buttonInstance.AutoButtonColor = true
			buttonInstance.Active = true
			buttonInstance.MouseButton1Click:Once(function()
				buyEgg(offer.eggType)
			end)
		end
	end
end

stateSync.OnClientEvent:Connect(function(payload)
	if payload.error then
		status.Text = string.format(t.errorPrefix, tostring(payload.error))
		return
	end
	currentState = payload
	clampSelection()
	renderOffers(payload)
	updateStatus(payload)
end)

local ok, stateOrReason = requestState:InvokeServer()
if ok then
	currentState = stateOrReason
	clampSelection()
	renderOffers(currentState)
	updateStatus(currentState)
end

upConveyor.MouseButton1Click:Connect(function()
	local success, reason = requestUpgrade:InvokeServer("Conveyor")
	if success == false then
		status.Text = string.format(t.upgradeConveyorFailed, tostring(reason))
	end
end)

upPlot.MouseButton1Click:Connect(function()
	local success, reason = requestUpgrade:InvokeServer("Plot")
	if success == false then
		status.Text = string.format(t.upgradePlotFailed, tostring(reason))
	end
end)

sellAt.MouseButton1Click:Connect(function()
	local success, reason = sellAnimal:InvokeServer(selectedCellX, selectedCellY)
	if success == false then
		status.Text = string.format(t.sellFailed, tostring(reason))
	end
end)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end
	if input.KeyCode == Enum.KeyCode.One and pendingTokenByEggType.Basic ~= nil then
		placeEggRemote:FireServer(pendingTokenByEggType.Basic, selectedCellX, selectedCellY)
		pendingTokenByEggType.Basic = nil
	elseif input.KeyCode == Enum.KeyCode.Two and pendingTokenByEggType.Ocean ~= nil then
		placeEggRemote:FireServer(pendingTokenByEggType.Ocean, selectedCellX, selectedCellY)
		pendingTokenByEggType.Ocean = nil
	elseif input.KeyCode == Enum.KeyCode.Three and pendingTokenByEggType.Mountain ~= nil then
		placeEggRemote:FireServer(pendingTokenByEggType.Mountain, selectedCellX, selectedCellY)
		pendingTokenByEggType.Mountain = nil
	elseif input.KeyCode == Enum.KeyCode.Right then
		selectedCellX += 1
	elseif input.KeyCode == Enum.KeyCode.Left then
		selectedCellX -= 1
	elseif input.KeyCode == Enum.KeyCode.Up then
		selectedCellY -= 1
	elseif input.KeyCode == Enum.KeyCode.Down then
		selectedCellY += 1
	end
	clampSelection()
	updateStatus(currentState)
end)

RunService.RenderStepped:Connect(function(dt)
	conveyorOffset += dt * 32
	local loopWidth = 360
	for index, buttonInstance in ipairs(offerButtons) do
		local x = ((index - 1) * 120 - conveyorOffset) % loopWidth
		buttonInstance.Position = UDim2.new(0, x, 0, 5)
	end
end)
