--[[
			// CurrencyWidget.lua by Kip Turner
--]]

local TextService = game:GetService('TextService')
local PlatformService;
pcall(function() PlatformService = game:GetService('PlatformService') end)


local CoreGui = game:GetService("CoreGui")
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")

local UserDataModule = require(Modules:FindFirstChild('UserData'))
local GlobalSettings = require(Modules:FindFirstChild('GlobalSettings'))
local Utility = require(Modules:FindFirstChild('Utility'))
local Strings = require(Modules:FindFirstChild('LocalizedStrings'))
local LoadingWidget = require(Modules:FindFirstChild('LoadingWidget'))


local function CreateCurrencyWidget(properties)
	properties = properties or {}

	local this = {}

	this.RobuxChanged = Utility.Signal()

	local CachedTotalRobuxValue = nil
	local CachedRobuxValue = nil
	local destroyed = false

	local RobuxBalanceTitle = Utility.Create'TextLabel'
	{
		Name = 'RobuxBalanceTitle';
		Size = UDim2.new(0,0,0,0);
		Position = properties.Position or UDim2.new(0, 0, 0, 0);
		TextXAlignment = 'Left';
		TextYAlignment = 'Top';
		TextColor3 = GlobalSettings.WhiteTextColor;
		Text = Strings:LocalizedString('RobuxBalanceTitle') .. ':';
		Font = GlobalSettings.RegularFont;
		FontSize = GlobalSettings.HeaderSize;
		BackgroundTransparency = 1;
		ZIndex = properties.ZIndex or 2;
		Parent = properties.Parent or nil;
	};
	local robuxTitleSize = TextService:GetTextSize(RobuxBalanceTitle.Text, Utility.ConvertFontSizeEnumToInt(RobuxBalanceTitle.FontSize), RobuxBalanceTitle.Font, Vector2.new())
	RobuxBalanceTitle.Size = UDim2.new(0, robuxTitleSize.X, 0, robuxTitleSize.Y)

		local RobuxBalanceIcon = Utility.Create'ImageLabel'
		{
			Name = 'RobuxIcon';
			Position = UDim2.new(1,10,0,0);
			Size = UDim2.new(0,46,0,46);
			BackgroundTransparency = 1;
			Image = 'rbxasset://textures/ui/Shell/Icons/ROBUXIconOutlined@1080.png';
			ZIndex = properties.ZIndex or 2;
			Parent = RobuxBalanceTitle;
		};
		Utility.CalculateAnchor(RobuxBalanceIcon, UDim2.new(1,17,0.5,0), Utility.Enum.Anchor.CenterLeft)
			local RobuxBalanceValue = Utility.Create'TextLabel'
			{
				Name = 'RobuxBalanceValue';
				Size = UDim2.new(0,0,1,0);
				Position = UDim2.new(1,5,0,-2);
				Text = '';
				TextXAlignment = 'Left';
				TextYAlignment = 'Center';
				TextColor3 = GlobalSettings.GreenTextColor;
				Font = GlobalSettings.RegularFont;
				FontSize = GlobalSettings.HeaderSize;
				BackgroundTransparency = 1;
				ZIndex = properties.ZIndex or 2;
				TextTransparency = 1;
				Parent = RobuxBalanceIcon;
			};


	local function UpdateBalanceText()
		local balanceValueString = CachedRobuxValue and Utility.FormatNumberString(tostring(CachedRobuxValue)) or '-'
		local balanceStringWidth = TextService:GetTextSize(balanceValueString, Utility.ConvertFontSizeEnumToInt(RobuxBalanceValue.FontSize), RobuxBalanceValue.Font, Vector2.new())
		RobuxBalanceValue.Size = UDim2.new(0, balanceStringWidth.X, 1, 0)
		RobuxBalanceValue.Text = balanceValueString
		if RobuxBalanceValue.TextTransparency == 1 and CachedRobuxValue ~= nil then
			Utility.PropertyTweener(RobuxBalanceValue, 'TextTransparency', 1, 0, 0.5, Utility.EaseOutQuad, true)
		end
	end


	local robuxAmountChangedLoader = nil
	local RobuxChangedConn = nil
	if PlatformService then
		local robuxChangedEventCount = 0

		local function fetchNewRobuxAsync(thisEventCount)
			local prepurchaseRobux = CachedRobuxValue or UserDataModule.GetPlatformUserBalanceAsync()
			local prepurchaseTotalRobux = CachedTotalRobuxValue or UserDataModule.GetTotalUserBalanceAsync()
			Utility.ExponentialRepeat(
				function() return thisEventCount == robuxChangedEventCount and not destroyed end,
				function()
					local balance = UserDataModule.GetPlatformUserBalanceAsync()
					local totalBalance = UserDataModule.GetTotalUserBalanceAsync()
					if balance and totalBalance and not destroyed then
						if balance ~= prepurchaseRobux and totalBalance ~= prepurchaseTotalRobux then
							CachedRobuxValue = balance
							CachedTotalRobuxValue = totalBalance
							UpdateBalanceText()
							if this.RobuxChanged ~= nil then
								this.RobuxChanged:fire(balance)
							end
							return true
						end
					end
				end
			 )
		end

		local function OnRobuxAmountChanged()
			robuxChangedEventCount = robuxChangedEventCount + 1
			local thisEventCount = robuxChangedEventCount

			if robuxAmountChangedLoader then
				robuxAmountChangedLoader:Cleanup()
				robuxAmountChangedLoader = nil
			end
			local loader = LoadingWidget({Parent = RobuxBalanceValue, Size = UDim2.new(0,50,0,50), Position = UDim2.new(1,75,0,25)}, {function() fetchNewRobuxAsync(thisEventCount) end})
			robuxAmountChangedLoader = loader
			robuxAmountChangedLoader:AwaitFinished()
			if robuxAmountChangedLoader and loader == robuxAmountChangedLoader then
				robuxAmountChangedLoader:Cleanup()
				robuxAmountChangedLoader = nil
			end

		end

		Utility.DisconnectEvent(RobuxChangedConn)
		RobuxChangedConn = PlatformService.RobuxAmountChanged:connect(function(platformPurchaseResult)
			if platformPurchaseResult == 3 then
				OnRobuxAmountChanged()
			end
		end)
	end

	function this:GetAbsoluteSize()
		return (RobuxBalanceValue.AbsolutePosition + RobuxBalanceValue.AbsoluteSize) - (RobuxBalanceTitle.AbsolutePosition)
	end

	function this:GetRobuxAmount()
		return CachedRobuxValue
	end

	function this:GetRobuxAmountAsync()
		if CachedRobuxValue then
			return CachedRobuxValue
		end
		UserDataModule.GetLocalUserIdAsync()
		spawn(function()
			wait(1)
			if CachedRobuxValue == nil then
				local tempWidget = LoadingWidget({Parent = RobuxBalanceValue, Size = UDim2.new(0,50,0,50), Position = UDim2.new(1,75,0,25)}, {function() while CachedRobuxValue == nil do wait() end end})
				tempWidget:AwaitFinished()
				tempWidget:Cleanup()
				tempWidget = nil
			end
		end)
		spawn(function()
			CachedTotalRobuxValue = UserDataModule.GetTotalUserBalanceAsync()
		end)
		CachedRobuxValue = UserDataModule.GetPlatformUserBalanceAsync()
		UpdateBalanceText()
		return CachedRobuxValue
	end

	function this:Destroy()
		destroyed = true
		RobuxBalanceTitle.Parent = nil
		self.RobuxChanged = nil
		if robuxAmountChangedLoader then
			robuxAmountChangedLoader:Cleanup()
			robuxAmountChangedLoader = nil
		end
		RobuxChangedConn = Utility.DisconnectEvent(RobuxChangedConn)
	end

	function this:GetGuiObject()
		return RobuxBalanceTitle
	end

	spawn(function()
		this:GetRobuxAmountAsync()
	end)

	return this
end

return CreateCurrencyWidget
