-- Services
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local SoundService = game:GetService("SoundService")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

-- GUI elements
local playerGui = player:WaitForChild("PlayerGui")
local fireAttackGui = playerGui:WaitForChild("FireAttackGui")
local heatFrame = fireAttackGui:WaitForChild("HeatFrame")
local currentHeat = heatFrame:WaitForChild("CurrentHeat")

-- Get the existing Hold button
local holdButton = fireAttackGui:WaitForChild("Hold")

-- GUI elements to hide/show based on arena status
local guisToHideInArena = {
	playerGui:WaitForChild("OverheatGui"),
	playerGui:WaitForChild("PetGui"),
	playerGui:WaitForChild("SHUDisplayer"),
	playerGui:WaitForChild("CodeGui")
}

-- Store removed tools
local removedTools = {}

-- Constants
local DAMAGE_INTERVAL = 0.4
local FIRE_PARTICLE_LIFETIME = 1
local FIRE_PARTICLE_SPEED = 50
local FIRE_PARTICLE_RATE = 60
local FIRE_PARTICLE_SIZE = Vector3.new(2, 2, 2)
local FIRE_PARTICLE_SPREAD = 15
local FIRE_PARTICLE_ROTATION_SPEED = 720
local MIN_HEAT_REQUIRED = 0.01
local MIN_STAMINA_REQUIRED = 0.01
local INDICATOR_COOLDOWN = 0.5

-- Remote events
local fireAbilityEvent = ReplicatedStorage:WaitForChild("FireAbilityEvent")
local dealDamageEvent = ReplicatedStorage:WaitForChild("DealDamageEvent")
local createFireParticleEvent = ReplicatedStorage:WaitForChild("CreateFireParticleEvent")

-- Variables
local isUsingAbility = false
local fireParticles = {}
local isKeyHeld = false
local isMobileButtonHeld = false
local lastIndicatorTime = 0
local isPlayerAlive = true

-- Sound effect
local fireSound = Instance.new("Sound")
fireSound.SoundId = "rbxassetid://9068935533"
fireSound.Parent = SoundService

-- Damage indicator template
local damageIndicatorTemplate = ReplicatedStorage:WaitForChild("DMGIndicator")

-- Function to check if player is in arena
local function isPlayerInArena()
	local isInArena = player:FindFirstChild("IsInArena")
	if isInArena then
		return isInArena.Value
	else
		return false -- Assume player is not in arena if value doesn't exist
	end
end

-- Function to update GUI visibility based on arena status
local function updateGuiVisibility()
	local inArena = isPlayerInArena()
	fireAttackGui.Enabled = inArena
	for _, gui in ipairs(guisToHideInArena) do
		gui.Enabled = not inArena
	end
end

-- Function to format damage numbers with suffixes
local function formatNumber(number)
	local suffixes = {
		"K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc",
		"Ud", "Dd", "Td", "Qad", "Qid", "Sxd", "Spd", "Ocd", "Nod", "Vg"
	}
	local suffixIndex = 0
	while number >= 1000 and suffixIndex < #suffixes do
		number = number / 1000
		suffixIndex = suffixIndex + 1
	end
	if suffixIndex == 0 then
		return tostring(number)
	else
		return string.format("%.3f%s", number, suffixes[suffixIndex]):gsub("%.?0+$", "")
	end
end

-- Function to create damage indicator
local function createDamageIndicator(target)
	local currentTime = tick()
	if currentTime - lastIndicatorTime < INDICATOR_COOLDOWN then
		return
	end
	lastIndicatorTime = currentTime

	local humanoid = target:FindFirstChildOfClass("Humanoid")
	if not humanoid or humanoid.Health <= 0 then
		return
	end

	local existingIndicator = target:FindFirstChild("DMGIndicator")
	if existingIndicator then
		existingIndicator:Destroy()
	end

	local dmgIndicator = damageIndicatorTemplate:Clone()
	dmgIndicator.Name = "DMGIndicator"
	dmgIndicator.Parent = target
	local textLabel = dmgIndicator:FindFirstChild("TextLabel")

	if textLabel then
		local currentSHU = player:GetAttribute("CurrentSHU") or 1
		local formattedDamage = formatNumber(currentSHU)
		textLabel.Text = string.format("-%s", formattedDamage)

		textLabel.Size = UDim2.new(0, 0, 0, 0)
		textLabel.TextTransparency = 0

		local growTween = TweenService:Create(textLabel, TweenInfo.new(0.3), {Size = UDim2.new(0, 100, 0, 30)})
		growTween:Play()

		delay(0.55, function()
			local fadeTween = TweenService:Create(textLabel, TweenInfo.new(0.2), {TextTransparency = 1})
			fadeTween:Play()
			fadeTween.Completed:Connect(function()
				dmgIndicator:Destroy()
			end)
		end)
	end
end

-- Function to create a fire particle (client-side)
local function createFireParticleClient(position, direction)
	local firePart = Instance.new("Part")
	firePart.Size = FIRE_PARTICLE_SIZE
	firePart.Anchored = false
	firePart.CanCollide = false
	firePart.Position = position
	firePart.BrickColor = BrickColor.new("Bright orange")
	firePart.Material = Enum.Material.Neon
	firePart.Transparency = 0

	local spreadX = math.rad(math.random(-FIRE_PARTICLE_SPREAD, FIRE_PARTICLE_SPREAD))
	local spreadY = math.rad(math.random(-FIRE_PARTICLE_SPREAD, FIRE_PARTICLE_SPREAD))
	direction = CFrame.fromOrientation(spreadX, spreadY, 0) * direction

	local bodyVelocity = Instance.new("BodyVelocity")
	bodyVelocity.Velocity = direction * FIRE_PARTICLE_SPEED
	bodyVelocity.MaxForce = Vector3.new(1e5, 1e5, 1e5)
	bodyVelocity.Parent = firePart

	local bodyAngularVelocity = Instance.new("BodyAngularVelocity")
	bodyAngularVelocity.AngularVelocity = Vector3.new(
		math.random(-FIRE_PARTICLE_ROTATION_SPEED, FIRE_PARTICLE_ROTATION_SPEED),
		math.random(-FIRE_PARTICLE_ROTATION_SPEED, FIRE_PARTICLE_ROTATION_SPEED),
		math.random(-FIRE_PARTICLE_ROTATION_SPEED, FIRE_PARTICLE_ROTATION_SPEED)
	)
	bodyAngularVelocity.MaxTorque = Vector3.new(1e5, 1e5, 1e5)
	bodyAngularVelocity.Parent = firePart

	firePart.Parent = workspace
	table.insert(fireParticles, firePart)

	TweenService:Create(firePart, TweenInfo.new(FIRE_PARTICLE_LIFETIME), {
		Transparency = 1,
		Size = FIRE_PARTICLE_SIZE * 0.1
	}):Play()

	delay(FIRE_PARTICLE_LIFETIME, function()
		local index = table.find(fireParticles, firePart)
		if index then
			table.remove(fireParticles, index)
		end
		firePart:Destroy()
	end)
end

-- Function to check for nearby characters and deal damage
local function checkForDamage()
	for _, firePart in ipairs(fireParticles) do
		local nearbyParts = workspace:GetPartBoundsInRadius(firePart.Position, FIRE_PARTICLE_SIZE.X * 2)
		for _, part in ipairs(nearbyParts) do
			local character = part:FindFirstAncestorOfClass("Model")
			if character and character:FindFirstChildOfClass("Humanoid") and character ~= player.Character then
				dealDamageEvent:FireServer(character)
				createDamageIndicator(character)
			end
		end
	end
end

-- Function to stop the fire ability
local function stopFireAbility()
	isUsingAbility = false
	fireAbilityEvent:FireServer(false)
	RunService:UnbindFromRenderStep("FireAbility")
	fireSound:Stop()
end

-- Function to check if the player can use the ability
local function canUseAbility()
	if not isPlayerAlive or not isPlayerInArena() then
		return false
	end
	local currentHeat = player:GetAttribute("CurrentHeat") or 0
	local currentStamina = player:GetAttribute("CurrentStamina") or 1
	return currentHeat > MIN_HEAT_REQUIRED and currentStamina > MIN_STAMINA_REQUIRED
end

-- Function to start the fire ability
local function startFireAbility()
	if not canUseAbility() then return end

	isUsingAbility = true
	fireAbilityEvent:FireServer(true)
	fireSound:Play()

	local lastParticleTime = 0
	local particleInterval = 1 / FIRE_PARTICLE_RATE

	RunService:BindToRenderStep("FireAbility", Enum.RenderPriority.Character.Value, function(deltaTime)
		if not (isKeyHeld or isMobileButtonHeld) or not canUseAbility() then
			stopFireAbility()
			return
		end

		lastParticleTime = lastParticleTime + deltaTime
		if lastParticleTime >= particleInterval then
			lastParticleTime = lastParticleTime - particleInterval
			local direction = character.PrimaryPart.CFrame.LookVector
			local firePosition = character.Head.Position + direction * 2
			createFireParticleEvent:FireServer(firePosition, direction)
		end

		checkForDamage()
	end)
end

-- Function to update the heat display
local function updateHeatDisplay()
	local heat = player:GetAttribute("CurrentHeat") or 0
	TweenService:Create(currentHeat, TweenInfo.new(0.1), {Size = UDim2.new(heat, 0, 1, 0)}):Play()
end

-- Function to restore tools
local function restoreTools()
	-- Only restore if we have stored tools and player is not in arena
	if #removedTools > 0 and not isPlayerInArena() then
		for _, tool in ipairs(removedTools) do
			local toolClone = tool:Clone()
			toolClone.Parent = player.Backpack
		end
		-- Clear the stored tools after restoring
		table.clear(removedTools)
	end
end

-- Function to handle tool removal and storage
local function updateHoldButtonVisibility()
	local isInArena = isPlayerInArena()

	if isInArena then
		-- Store and remove tools
		for _, item in pairs(player.Backpack:GetChildren()) do
			if item:IsA("Tool") then
				table.insert(removedTools, item:Clone())
				item:Destroy()
			end
		end
	end

	-- Set the holdButton visibility
	if UserInputService.TouchEnabled and isInArena then
		holdButton.Visible = true
	else
		holdButton.Visible = false
	end
end

-- Input handling for PC
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.F and not gameProcessed then
		isKeyHeld = true
		if not isUsingAbility and canUseAbility() then
			startFireAbility()
		end
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.F and not gameProcessed then
		isKeyHeld = false
		stopFireAbility()
	end
end)

-- Input handling for mobile
holdButton.MouseButton1Down:Connect(function()
	isMobileButtonHeld = true
	if not isUsingAbility and canUseAbility() then
		startFireAbility()
	end
end)

holdButton.MouseButton1Up:Connect(function()
	isMobileButtonHeld = false
	stopFireAbility()
end)

-- Player respawn handler
local function onPlayerRespawn(newCharacter)
	character = newCharacter
	humanoid = character:WaitForChild("Humanoid")
	isPlayerAlive = true
	stopFireAbility()
	updateGuiVisibility()

	-- Restore tools on respawn if not in arena
	restoreTools()

	humanoid.Died:Connect(function()
		isPlayerAlive = false
		stopFireAbility()
	end)
end

-- Handle current and future respawns
player.CharacterAdded:Connect(onPlayerRespawn)
if player.Character then
	onPlayerRespawn(player.Character)
end

-- Update loops and event connections
player:GetAttributeChangedSignal("CurrentHeat"):Connect(updateHeatDisplay)
player:GetAttributeChangedSignal("CurrentHeat"):Connect(function()
	if isUsingAbility and not canUseAbility() then
		stopFireAbility()
	end
end)

player:GetAttributeChangedSignal("CurrentStamina"):Connect(function()
	if isUsingAbility and not canUseAbility() then
		stopFireAbility()
	end
end)

-- Function to check for IsInArena value periodically
local function checkForIsInArena()
	while true do
		local isInArena = player:FindFirstChild("IsInArena")
		if isInArena then
			-- Connect to the Changed event
			isInArena.Changed:Connect(function()
				updateGuiVisibility()
				if isUsingAbility and not canUseAbility() then
					stopFireAbility()
				end

				-- Handle tool restoration when leaving arena
				if not isPlayerInArena() then
					restoreTools()
				else
					updateHoldButtonVisibility() -- Remove tools when entering arena
				end
			end)
			-- Update GUI visibility initially
			updateGuiVisibility()
			updateHoldButtonVisibility()
			break -- Exit the loop once we've found and connected to IsInArena
		else
			wait(0.5) -- Wait 5 seconds before checking again
		end
	end
end

-- Start the periodic check for IsInArena
spawn(checkForIsInArena)

-- Initial GUI update
updateHeatDisplay()

-- Listen for the server's signal to create particles
createFireParticleEvent.OnClientEvent:Connect(function(position, direction)
	createFireParticleClient(position, direction)
end)

-- Cleanup
character.AncestryChanged:Connect(function(_, parent)
	if not parent then
		stopFireAbility()
	end
end)

-- Function to handle tool changes
local function onToolChanged()
	if isPlayerInArena() then
		-- Check both backpack and character for tools
		for _, item in pairs(player.Backpack:GetChildren()) do
			if item:IsA("Tool") then
				table.insert(removedTools, item:Clone())
				item:Destroy()
			end
		end

		for _, item in pairs(character:GetChildren()) do
			if item:IsA("Tool") then
				table.insert(removedTools, item:Clone())
				item:Destroy()
			end
		end
	end
	updateHoldButtonVisibility()
end

-- Connect the tool changed function to both backpack and character
player.Backpack.ChildAdded:Connect(onToolChanged)
player.Backpack.ChildRemoved:Connect(onToolChanged)
character.ChildAdded:Connect(onToolChanged)
character.ChildRemoved:Connect(onToolChanged)

-- Handle character changes
player.CharacterAdded:Connect(function(newCharacter)
	character = newCharacter
	humanoid = character:WaitForChild("Humanoid")
	isPlayerAlive = true

	-- Reconnect tool change handlers for new character
	character.ChildAdded:Connect(onToolChanged)
	character.ChildRemoved:Connect(onToolChanged)

	-- Handle initial state
	onToolChanged()
end)

-- Handle initial tool state
onToolChanged() 	"K",  -- Thousand
	"M",  -- Million
	"B",  -- Billion
	"T",  -- Trillion
	"Qa",  -- Quadrillion
	"Qi", 
	"Sx", 
	"Sp", 
	"Oc", 
	"No", 
	"Dc",
	"Ud",
	"Dd",
	"Td",
	"Qad",
	"Qid", 
	"Sxd", 
	"Spd", 
	"Ocd", 
	"Nod", 
	"Vg", 
	"UVg",
	"DVg",
	"TVg",
	"QaVg",
	"QiVg",
	"SxVg",
	"SpVg",
	"OcVg",
	"NoVg",
	"Tg",
	"UTg",
	"DTg",
	"TTg",
	"QaTg",
	"QiTg",
	"SxTg",
	"SpTg",
	"OcTg",
	"NoTg",
	"Qag",
	"Uqg",
	"Dqg",
	"Tqg",
	"Qaqg",
	"Qiqg",
	"Sxqg",
	"Spqg",
	"Ocqg",
	"Noqg",
	"Qng",
	"Uqng",
	"Dqng",
	"Tqng",
	"Qaqng",
	"Qiqng",
	"Sxqng",
	"Spqng",
	"Ocqng",
	"Noqng",
	"Sxg",
	"Usxg",
	"Dsxg",
	"Tsxg",
	"Qasxg",
	"Qisxg",
	"Sxsxg",
	"SpSxg",
	"OcSxg",
	"NoSxg",
	"Spg",
	"Uspg",
	"Dspg",
	"Tspg",
	"Qaspg",
	"Qispg",
	"Sxspg",
	"Spspg",
	"Ocspg",
	"NoSpg",
	"Ocg",
	"Uocg",
	"Docg",
	"Tocg",
	"Qaocg",
	"Qiocg",
	"Sxocg",
	"Spocg",
	"OcOCg",
	"NoOcg",
	"Nog",
	"Unog",
	"Dnog",
	"Tnog",
	"Qanog",
	"Qinog",
	"Sxnog",
	"Spnog",
	"Ocnog",
	"NoNog",
	"C", (put these suffix into the other one)