local H=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local A=game:GetService("\076\111\099\097\108\105\122\097\116\105\111\110\083\101\114\118\105\099\101")local Q=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local u=game:GetService("\080\108\097\121\101\114\115")local T=game:GetService("\082\117\110\083\101\114\118\105\099\101")local V=H("\074\115\111\110\084\111\076\111\099\097\108\105\122\097\116\105\111\110\084\097\098\108\101")local K=H("\080\115\101\117\100\111\076\111\099\097\108\105\122\101")local x=H("\080\114\111\109\105\115\101")assert(T:IsClient(),"\067\108\105\101\110\116\084\114\097\110\115\108\097\116\111\114 \099\097\110 \111\110\108\121 \098\101 \114\101\113\117\105\114\101\100 \111\110 \099\108\105\101\110\116")local h={}function h.Init(H)local h=V.loadFolder(Q:WaitForChild("\105\049\056\110"))h.Name="\074\083\079\078\084\114\097\110\115\108\097\116\105\111\110\084\097\098\108\101"h.Parent=A if T:IsStudio()then K.addToLocalizationTable(h,"\113\108\112-\112\108\115","\101\110")end H._englishTranslator=h:GetTranslator("\101\110")local U=x.spawn(function(H,Q)local T=nil local V,K=pcall(function()T=A:GetTranslatorForPlayerAsync(u.LocalPlayer)end)if not V then Q(K or"\070\097\105\108\101\100 \116\111 \071\101\116\084\114\097\110\115\108\097\116\111\114\070\111\114\080\108\097\121\101\114\065\115\121\110\099")return end if T then assert(typeof(T)=="\073\110\115\116\097\110\099\101")H(T)return end Q("\084\114\097\110\115\108\097\116\111\114 \119\097\115 \110\111\116 \114\101\116\117\114\110\101\100")return end)local z=20 if T:IsStudio()then z=.5 end delay(z,function()if not U:IsPending()then return end U:Reject(("\071\101\116\084\114\097\110\115\108\097\116\111\114\070\111\114\080\108\097\121\101\114\065\115\121\110\099 \105\115 \115\116\105\108\108 \112\101\110\100\105\110\103 \097\102\116\101\114 \037\102\044 \117\115\105\110\103 \108\111\099\097\108 \116\097\098\108\101"):format(z))end)local j=U:Catch(function(H)warn(("\091\069\082\082\093\091\067\108\105\101\110\116\084\114\097\110\115\108\097\116\111\114\070\097\099\097\100\101\093 - \037\115"):format(tostring(H)))local Q=A:GetTranslatorForPlayer(u.LocalPlayer)return Q end)H._clientTranslator=j:Wait()assert(typeof(H._clientTranslator)=="\073\110\115\116\097\110\099\101")return H end function h.FormatByKey(A,H,...)assert(A._clientTranslator,"\067\108\105\101\110\116\084\114\097\110\115\108\097\116\111\114 \105\115 \110\111\116 \105\110\105\116\105\097\108\105\122\101\100")assert(type(H)=="\115\116\114\105\110\103","\075\101\121 \109\117\115\116 \098\101 \097 \115\116\114\105\110\103")local Q={...}local u local T,V=pcall(function()u=A._clientTranslator:FormatByKey(H,unpack(Q))end)if T and not V then return u end if V then warn(V)else warn("\070\097\105\108\101\100 \116\111 \108\111\099\097\108\105\122\101 \'"..(H.."\'"))end if A._clientTranslator.LocaleId~=A._englishTranslator.LocaleId then T,V=pcall(function()u=A._englishTranslator:FormatByKey(H,unpack(Q))end)if T and not V then return u end end return H end return h
--- Gets local translator for player
-- @module ClientTranslator

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

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

local JsonToLocalizationTable = require("JsonToLocalizationTable")
local PseudoLocalize = require("PseudoLocalize")
local Promise = require("Promise")

assert(RunService:IsClient(), "ClientTranslator can only be required on client")

local ClientTranslatorFacade = {}

--- Initializes a new instance of the ClientTranslatorFacade
--  Must be called before usage
function ClientTranslatorFacade:Init()
	local localizationTable = JsonToLocalizationTable.loadFolder(ReplicatedStorage:WaitForChild("i18n"))
	localizationTable.Name = "JSONTranslationTable"
	localizationTable.Parent = LocalizationService

	if RunService:IsStudio() then
		PseudoLocalize.addToLocalizationTable(localizationTable, "qlp-pls", "en")
	end

	self._englishTranslator = localizationTable:GetTranslator("en")

	local asyncTranslatorPromise = Promise.spawn(function(resolve, reject)
		local translator = nil
		local ok, err = pcall(function()
			translator = LocalizationService:GetTranslatorForPlayerAsync(Players.LocalPlayer)
		end)

		if not ok then
			reject(err or "Failed to GetTranslatorForPlayerAsync")
			return
		end

		if translator then
			assert(typeof(translator) == "Instance")
			resolve(translator)
			return
		end

		reject("Translator was not returned")
		return
	end)

	-- Give longer in non-studio mode
	local timeout = 20
	if RunService:IsStudio() then
		timeout = 0.5
	end

	delay(timeout, function()
		if not asyncTranslatorPromise:IsPending() then
			return
		end
		asyncTranslatorPromise:Reject(
			("GetTranslatorForPlayerAsync is still pending after %f, using local table")
			:format(timeout))
	end)

	local finalPromise = asyncTranslatorPromise:Catch(function(err)
		warn(("[ERR][ClientTranslatorFacade] - %s"):format(tostring(err)))
		local translator = LocalizationService:GetTranslatorForPlayer(Players.LocalPlayer)
		return translator
	end)

	self._clientTranslator = finalPromise:Wait()
	assert(typeof(self._clientTranslator) == "Instance")

	return self
end

--- @{inheritDoc}
function ClientTranslatorFacade:FormatByKey(key, ...)
	assert(self._clientTranslator, "ClientTranslator is not initialized")
	assert(type(key) == "string", "Key must be a string")
	local data = {...}
	local result
	local ok, err = pcall(function()
		result = self._clientTranslator:FormatByKey(key, unpack(data))
	end)

	if ok and not err then
		return result
	end

	if err then
		warn(err)
	else
		warn("Failed to localize '" .. key .. "'")
	end

	-- Fallback to English
	if self._clientTranslator.LocaleId ~= self._englishTranslator.LocaleId then
		-- Ignore results as we know this may error
		ok, err = pcall(function()
			result = self._englishTranslator:FormatByKey(key, unpack(data))
		end)

		if ok and not err then
			return result
		end
	end

	return key
end

return ClientTranslatorFacade