local A=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local p=A:WaitForChild("\077\111\100\117\108\101\115")local f=require(p.src.utils.Logger)local R="\099\111\105\110\115"local u="\101\113\117\105\112\112\101\100\050"local K="\112\117\114\099\104\097\115\101\095\104\105\115\116\111\114\121"local d="\105\110\118\101\110\116\111\114\121"local i="\115\108\111\116\115\067\111\117\110\116"local g="\108\097\115\116\076\111\103\105\110"local S=require(p.DataStore2)local T=require(p.M)local J=require(p.src.GlobalConfig)S.Combine("\068\065\084\065",R)S.Combine("\068\065\084\065",u)S.Combine("\068\065\084\065",d)S.Combine("\068\065\084\065",i)S.Combine("\068\065\084\065",g)S.Combine("\068\065\084\065",K)local c={}function c.getCoins(p,A)local u=S(R,A)local K=u:Get(J.DEFAULT_PLAYER_COINS)f:d("\068\097\116\097\083\116\111\114\101\058 \071\101\116 \112\108\097\121\101\114 "..(A.Name..(" \099\111\105\110\115\058"..tonumber(K))))return K end function c.onCoinsUpdated(u,A,p)local K=S(R,A)f:d("\068\097\116\097\083\116\111\114\101\058 \080\108\097\121\101\114 "..(A.Name.." \099\111\105\110\115 \117\112\100\097\116\101\100"))K:OnUpdate(p)end function c.coinsAfterSave(u,A,p)local K=S(R,A)f:d("\068\097\116\097\083\116\111\114\101\058 \080\108\097\121\101\114 "..(A.Name.." \099\111\105\110\115 \097\102\116\101\114 \115\097\118\101"))K:AfterSave(p)end function c.decrementCoins(u,A,p)local K=S(R,A)if p<=0 then f:e("\073\110\118\097\108\105\100 \097\109\111\117\110\116 \115\117\098\116\114\097\099\116\101\100\058"..tostring(p))end local d=c:getCoins(A)if d>=p then f:d("\068\097\116\097\083\116\111\114\101\058 \080\108\097\121\101\114 "..(A.Name..(" \119\097\108\108\101\116 \115\117\098\116\114\097\099\116\101\100 "..tostring(p))))K:Increment(-p)else f:d("\068\097\116\097\083\116\111\114\101\058 \080\108\097\121\101\114 "..(A.Name.." \104\097\115 \110\111\116 \104\097\118\101 \101\110\111\117\103\104 \109\111\110\101\121\046"))end return d-p end function c.incrementCoins(u,A,p)local K=S(R,A)if p<=0 then f:e("\073\110\118\097\108\105\100 \097\109\111\117\110\116 \097\100\100\101\100\058"..tostring(p))end f:d("\068\097\116\097\083\116\111\114\101\058 \080\108\097\121\101\114 "..(A.Name..(" \119\097\108\108\101\116 \097\100\100\101\100 "..tostring(p))))K:Increment(p)end function c.getSlotsCount(p,A)local R=S(i,A)local u=R:Get(J.DEFAULT_PLAYER_SLOTS)f:d("\068\097\116\097\083\116\111\114\101\058 \071\101\116 \112\108\097\121\101\114 "..(A.Name.." \115\108\111\116\115\067\111\117\110\116\058"),u)return u end function c.onEquippedPetsUpdated(R,A,p)local K=S(u,A)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \112\101\116\115 \117\112\100\097\116\101\100"))K:OnUpdate(p)end function c.getEquippedPets(p,A)local R=S(u,A)local K=R:Get({})f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \101\113\117\105\112\112\105\110\103 \112\101\116\115"),K)return K end function c.setEquippedPet(R,A,p)local K=S(u,A)local d=c:getSlotsCount(A)if#c:getEquippedPets(A)<d then K:Update(function(R)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \101\113\117\105\112\112\105\110\103 \112\101\116"),p)return T.unique(T.push(R,p))end)end end function c.unsetEquippedPet(R,A,p)local K=S(u,A)K:Update(function(R)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \114\101\109\111\118\105\110\103 \112\101\116"),p)return T.unique(T.pull(R,p))end)end function c.unsetAllEquippedPet(p,A)local f=S(u,A)f:Set({})end function c.getLastLogin(p,A)local R=S(g,A)local u=R:Get(os.time())f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \076\097\115\116 \108\111\103\105\110"),u)return u end function c.setLastLogin(R,A,p)local u=S(g,A)f:d("\068\097\116\097\083\116\111\114\101\058 \115\101\116 \112\108\097\121\101\114 "..(A.Name.." \076\097\115\116 \108\111\103\105\110"))u:Set(os.time())end function c.setInventoryItem(R,A,p)local u=S(d,A)u:Update(function(R)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \117\112\100\097\116\105\110\103 \105\110\118\101\110\116\111\114\121 \105\100"),p)return T.unique(T.push(R,p))end)end function c.unsetInventoryItem(R,A,p)local u=S(d,A)u:Update(function(A)f:d("\082\101\109\111\118\105\110\103 \105\110\118\101\110\116\111\114\121 \119\105\116\104 \105\100\058",p)return T.unique(T.pull(A,p))end)end function c.getInventory(p,A)local R=S(d,A)local u=R:Get(J.DEFAULT_PLAYER_INVENTORY)f:d("\068\097\116\097\083\116\111\114\101\058 \071\101\116 \112\108\097\121\101\114 "..(A.Name.." \105\110\118\101\110\116\111\114\121"))return u end function c.onInventoryUpdated(R,A,p)local u=S(d,A)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \105\110\118\101\110\116\111\114\121 \117\112\100\097\116\101\100"))u:OnUpdate(p)end function c.setProductPurchased(R,A,p)local u=S(K,A,p)u:Update(function(R)f:d("\068\097\116\097\083\116\111\114\101\058 \112\108\097\121\101\114 "..(A.Name.." \097\100\100\105\110\103 \114\101\099\101\105\112\116"),p)return T.push(R,p)end)end function c.hasProductPurchased(f,A,p)local R=S(K,A,p)local u=R:Get({})return T.include(u,p)end return c
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Modules = ReplicatedStorage:WaitForChild('Modules')
local logger = require(Modules.src.utils.Logger)

local STORE_COINS = 'coins'
local STORE_EQUIPPED = 'equipped2'
local STORE_PURCHASE_HISTORY = 'purchase_history'
local STORE_INVENTORY = 'inventory'
local STORE_SLOTS_COUNT = 'slotsCount'
local STORE_LAST_LOGIN = 'lastLogin'

local DataStore2 = require(Modules.DataStore2)
local M = require(Modules.M)
local GlobalConfig = require(Modules.src.GlobalConfig)

-- Always "combine" any key you use! To understand why, read the "Gotchas" page.
DataStore2.Combine('DATA', STORE_COINS)
DataStore2.Combine('DATA', STORE_EQUIPPED)
DataStore2.Combine('DATA', STORE_INVENTORY)
DataStore2.Combine('DATA', STORE_SLOTS_COUNT)
DataStore2.Combine('DATA', STORE_LAST_LOGIN)
DataStore2.Combine('DATA', STORE_PURCHASE_HISTORY)

local GameDatastore = {}

function GameDatastore:getCoins(player)
	local datastore = DataStore2(STORE_COINS, player)
	local coins = datastore:Get(GlobalConfig.DEFAULT_PLAYER_COINS)

	logger:d('DataStore: Get player ' .. player.Name .. ' coins:' .. tonumber(coins))
	return coins
end

function GameDatastore:onCoinsUpdated(player, coinsUpdated)
	local datastore = DataStore2(STORE_COINS, player)
	logger:d('DataStore: Player ' .. player.Name .. ' coins updated')
	datastore:OnUpdate(coinsUpdated)
end
function GameDatastore:coinsAfterSave(player, coinsSaved)
	local datastore = DataStore2(STORE_COINS, player)
	logger:d('DataStore: Player ' .. player.Name .. ' coins after save')
	datastore:AfterSave(coinsSaved)
end

function GameDatastore:decrementCoins(player, coinsToSubtract)
	local datastore = DataStore2(STORE_COINS, player)

	if coinsToSubtract <= 0 then
		logger:e('Invalid amount subtracted:' .. tostring(coinsToSubtract))
	end

	local playerCoins = GameDatastore:getCoins(player)
	if playerCoins >= coinsToSubtract then
		logger:d(
			'DataStore: Player ' .. player.Name .. ' wallet subtracted ' .. tostring(
				coinsToSubtract
			)
		)
		datastore:Increment(-coinsToSubtract)
	else
		logger:d('DataStore: Player ' .. player.Name .. ' has not have enough money.')
	end

	return playerCoins - coinsToSubtract
end

function GameDatastore:incrementCoins(player, coinsToAdd)
	local datastore = DataStore2(STORE_COINS, player)

	if coinsToAdd <= 0 then
		logger:e('Invalid amount added:' .. tostring(coinsToAdd))
	end

	logger:d('DataStore: Player ' .. player.Name .. ' wallet added ' .. tostring(coinsToAdd))
	datastore:Increment(coinsToAdd)
end

----

function GameDatastore:getSlotsCount(player)
	local datastore = DataStore2(STORE_SLOTS_COUNT, player)
	local slotsCount = datastore:Get(GlobalConfig.DEFAULT_PLAYER_SLOTS)

	logger:d('DataStore: Get player ' .. player.Name .. ' slotsCount:', slotsCount)
	return slotsCount
end

----

function GameDatastore:onEquippedPetsUpdated(player, equippedUpdated)
	local datastore = DataStore2(STORE_EQUIPPED, player)
	logger:d('DataStore: player ' .. player.Name .. ' pets updated')
	datastore:OnUpdate(equippedUpdated)
end

function GameDatastore:getEquippedPets(player)
	local datastore = DataStore2(STORE_EQUIPPED, player)
	local petIds = datastore:Get({})

	logger:d('DataStore: player ' .. player.Name .. ' equipping pets', petIds)
	return petIds
end

function GameDatastore:setEquippedPet(player, id)
	local datastore = DataStore2(STORE_EQUIPPED, player)
	local playerSlotsCount = GameDatastore:getSlotsCount(player)

	if #GameDatastore:getEquippedPets(player) < playerSlotsCount then
		datastore:Update(function(currentPets)
			logger:d('DataStore: player ' .. player.Name .. ' equipping pet', id)
			return M.unique(M.push(currentPets, id))
		end)
	end
end

function GameDatastore:unsetEquippedPet(player, id)
	local datastore = DataStore2(STORE_EQUIPPED, player)

	datastore:Update(function(currentPets)
		logger:d('DataStore: player ' .. player.Name .. ' removing pet', id)
		return M.unique(M.pull(currentPets, id))
	end)
end

function GameDatastore:unsetAllEquippedPet(player)
	local datastore = DataStore2(STORE_EQUIPPED, player)

	datastore:Set({})
end

----

function GameDatastore:getLastLogin(player)
	local datastore = DataStore2(STORE_LAST_LOGIN, player)
	local lastLogin = datastore:Get(os.time())

	logger:d('DataStore: player ' .. player.Name .. ' Last login', lastLogin)
	return lastLogin
end

function GameDatastore:setLastLogin(player, id)
	local datastore = DataStore2(STORE_LAST_LOGIN, player)
	logger:d('DataStore: set player ' .. player.Name .. ' Last login')

	datastore:Set(os.time())
end

-- INVENTORY

function GameDatastore:setInventoryItem(player, id)
	local datastore = DataStore2(STORE_INVENTORY, player)

	datastore:Update(function(currentInventory)
		logger:d('DataStore: player ' .. player.Name .. ' updating inventory id', id)
		return M.unique(M.push(currentInventory, id))
	end)
end

function GameDatastore:unsetInventoryItem(player, id)
	local datastore = DataStore2(STORE_INVENTORY, player)

	datastore:Update(function(currentPets)
		logger:d('Removing inventory with id:', id)
		return M.unique(M.pull(currentPets, id))
	end)
end

function GameDatastore:getInventory(player)
	local datastore = DataStore2(STORE_INVENTORY, player)
	local inventory = datastore:Get(GlobalConfig.DEFAULT_PLAYER_INVENTORY)

	logger:d('DataStore: Get player ' .. player.Name .. ' inventory')
	return inventory
end

function GameDatastore:onInventoryUpdated(player, inventoryUpdated)
	local datastore = DataStore2(STORE_INVENTORY, player)

	logger:d('DataStore: player ' .. player.Name .. ' inventory updated')
	datastore:OnUpdate(inventoryUpdated)
end
-- Developer product purchase history

function GameDatastore:setProductPurchased(player, purchaseId)
	local datastore = DataStore2(STORE_PURCHASE_HISTORY, player, purchaseId)
	datastore:Update(function(current)
		logger:d('DataStore: player ' .. player.Name .. ' adding receipt', purchaseId)
		return M.push(current, purchaseId)
	end)
end

function GameDatastore:hasProductPurchased(player, purchaseId)
	local datastore = DataStore2(STORE_PURCHASE_HISTORY, player, purchaseId)
	local current = datastore:Get({})
	return M.include(current, purchaseId)
end

return GameDatastore