local X=game:GetService("\080\108\097\121\101\114\115")local Y=game:GetService("\083\101\114\118\101\114\083\116\111\114\097\103\101")local w=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local A=w.AvatarEditor local e=require(Y.AvatarEditorServer)local J=require(A.Shared.Settings)local P=require(script.ProfileService)local i="\080\108\097\121\101\114\068\097\116\097\065\118\097\116\097\114"local D={}local G=P.GetProfileStore(i,{Avatar={Equipped=nil,Costumes={},Settings={Theme=J.DEFAULT_THEME}}})local function I(X,Y)local w=e:ToAppearanceInfo(Y)local A=D[X]if A then A.Data.Avatar.Equipped=w end end local function x(X,Y,w,A)local e=D[X]if e then table.insert(e.Data.Avatar.Costumes,w)end end local function Q(X,Y,w,A)local e=D[X]if e then table.remove(e.Data.Avatar.Costumes,A)end end local function F(X,Y,w)local A=D[X]if A then A.Data.Avatar.Settings[Y]=w end end local function H(X)local Y=D[X]local function w(X)(e:ApplyDescriptionFromInfo(X,Y.Data.Avatar.Equipped)):catch(warn)end e:CacheOutfits(X,Y.Data.Avatar.Costumes)e:CacheSettings(X,Y.Data.Avatar.Settings)w(X.Character or X.CharacterAdded:Wait())X.CharacterAdded:Connect(w)end local function p(Y)local w=G:LoadProfileAsync("\080\108\097\121\101\114\095"..Y.UserId,"\070\111\114\099\101\076\111\097\100")if w==nil then Y:Kick("\068\097\116\097 \102\097\105\108\101\100 \116\111 \108\111\097\100\046 \080\108\101\097\115\101 \114\101\106\111\105\110\046")return end w:Reconcile()w:ListenToRelease(function()D[Y]=nil Y:Kick("\068\097\116\097 \108\111\097\100\101\100 \114\101\109\111\116\101\108\121\046 \080\108\101\097\115\101 \114\101\106\111\105\110\046")end)if Y:IsDescendantOf(X)then D[Y]=w H(Y)else w:Release()end end local function o(X)local Y=D[X]if Y then Y:Release()end end local function b(X) end for X,Y in ipairs(X:GetPlayers())do(coroutine.wrap(p))(Y)end X.PlayerAdded:Connect(p)X.PlayerRemoving:Connect(o)e.HumanoidDescriptionChanged:Connect(I)e.CostumeAdded:Connect(x)e.CostumeRemoved:Connect(Q)e.SettingChanged:Connect(F)e.PermissionFailed:Connect(b)
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local AvatarEditor = ReplicatedStorage.AvatarEditor
local AE = require(ServerStorage.AvatarEditorServer)
local Settings = require(AvatarEditor.Shared.Settings)
local ProfileService = require(script.ProfileService)

local DATASTORE_NAME = "PlayerDataAvatar"

local playerProfiles = {}

local profileStore = ProfileService.GetProfileStore(DATASTORE_NAME, {
	Avatar = {
		Equipped = nil,
		Costumes = {},
		Settings = {
			Theme = Settings.DEFAULT_THEME,
			-- HQ = false,
		},
	},
})


local function humanoidDescriptionChanged(player, description)
	local info = AE:ToAppearanceInfo(description)
	local profile = playerProfiles[player]
	if profile then
		profile.Data.Avatar.Equipped = info
	end
end


local function outfitAdded(player, description, info, index)
	local profile = playerProfiles[player]
	if profile then
		table.insert(profile.Data.Avatar.Costumes, info)
	end
	--print(#game:GetService("HttpService"):JSONEncode(profile.Data.Avatar.Costumes))
end


local function outfitRemoved(player, description, info, index)
	local profile = playerProfiles[player]
	if profile then
		table.remove(profile.Data.Avatar.Costumes, index)
	end
	--print(profile.Data.Avatar.Costumes)
end


local function settingChanged(player, setting, value)
	local profile = playerProfiles[player]
	if profile then
		profile.Data.Avatar.Settings[setting] = value
	end
end


local function playerDataLoaded(player)
	local profile = playerProfiles[player]
	
	local function characterAdded(character)
		AE:ApplyDescriptionFromInfo(character, profile.Data.Avatar.Equipped)
		:catch(warn)
	end
	
	AE:CacheOutfits(player, profile.Data.Avatar.Costumes)
	AE:CacheSettings(player, profile.Data.Avatar.Settings)
	characterAdded(player.Character or player.CharacterAdded:Wait())

	player.CharacterAdded:Connect(characterAdded)
end

local function playerAdded(player)
	local profile = profileStore:LoadProfileAsync("Player_" .. player.UserId, "ForceLoad")
	if profile == nil then
		player:Kick("Data failed to load. Please rejoin.")
		return
	end
	
	profile:Reconcile()
	profile:ListenToRelease(function()
		playerProfiles[player] = nil
		player:Kick("Data loaded remotely. Please rejoin.")
	end)

	if player:IsDescendantOf(Players) then
		playerProfiles[player] = profile
		playerDataLoaded(player)
	else
		profile:Release()
	end
end


local function playerRemoving(player)
	local profile = playerProfiles[player]
	if profile then
		profile:Release()
	end
end


local function permissionFailed(player)
	
end


for i, player in ipairs(Players:GetPlayers()) do
	coroutine.wrap(playerAdded)(player)
end

Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
AE.HumanoidDescriptionChanged:Connect(humanoidDescriptionChanged)
AE.CostumeAdded:Connect(outfitAdded)
AE.CostumeRemoved:Connect(outfitRemoved)
AE.SettingChanged:Connect(settingChanged)
AE.PermissionFailed:Connect(permissionFailed)