local i=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local M=i:WaitForChild("\099\111\109\109\111\110")local D=i:WaitForChild("\108\105\098")local p=M:WaitForChild("\114\101\099\115\112\108\117\103\105\110\115")local x=require(D:WaitForChild("\082\069\067\083"))local K=require(D:WaitForChild("\080\105\122\122\097\065\108\112\097\099\097"))local o=require(D:WaitForChild("\083\105\103\110\097\108"))local j=require(D:WaitForChild("\080\114\111\109\105\115\101"))local w=require(M:WaitForChild("\082\101\099\115\067\111\109\112\111\110\101\110\116\115"))local R=require(script.Systems)local U=require(script.Steppers)local e=require(p:WaitForChild("\099\114\101\097\116\101\073\110\106\101\099\116\111\114\080\108\117\103\105\110"))local d=require(p:WaitForChild("\099\114\101\097\116\101\067\111\109\112\111\110\101\110\116\080\114\111\112\115\079\118\101\114\114\105\100\101\080\108\117\103\105\110"))local h=K.GameModule:extend("\067\108\105\101\110\116\082\069\067\083\067\111\110\116\097\105\110\101\114")function h.create(i)i.recsCoreCreated=o.new()end function h.onStoreAndApi(D,i,M)D.recsCore=x.Core.new({x.BuiltInPlugins.CollectionService();x.BuiltInPlugins.ComponentChangedEvent;d();e("\103\101\116\067\108\105\101\110\116\077\111\100\117\108\101",function(i,M)return D.core:getModule(M)end),e("\112\122\067\111\114\101",D.core),e("\115\116\111\114\101",i);e("\097\112\105",M)})for i,M in pairs(w)do D.recsCore:registerComponent(M)end D.recsCore:registerSystems(R)D.recsCore:registerSteppers(U)end function h.getCore(i)return j.async(function(M,D)if not i.recsCore then i.recsCoreCreated:wait()end M(i.recsCore)end)end function h.preInit(i) end function h.init(i)local M=i.core:getModule("\083\116\111\114\101\067\111\110\116\097\105\110\101\114")local D=i.core:getModule("\067\108\105\101\110\116\065\112\105");(j.all({M:getStore();D:getApi()})):andThen(function(M)local D,p=unpack(M)i:onStoreAndApi(D,p)i.recsCore:start()i.recsCoreCreated:fire(i.recsCore)end)end function h.postInit(i) end return h
-- TODO: Genericize this module and replace with a common RECSContainer

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local common = ReplicatedStorage:WaitForChild("common")
local lib = ReplicatedStorage:WaitForChild("lib")
local recsPlugins = common:WaitForChild("recsplugins")

local RECS = require(lib:WaitForChild("RECS"))
local PizzaAlpaca = require(lib:WaitForChild("PizzaAlpaca"))
local Signal = require(lib:WaitForChild("Signal"))
local Promise = require(lib:WaitForChild("Promise"))

local RecsComponents = require(common:WaitForChild("RecsComponents"))
local Systems = require(script.Systems)
local Steppers = require(script.Steppers)

local createInjectorPlugin = require(recsPlugins:WaitForChild("createInjectorPlugin"))
local createComponentPropsOverridePlugin = require(recsPlugins:WaitForChild("createComponentPropsOverridePlugin"))

local ClientRECSContainer = PizzaAlpaca.GameModule:extend("ClientRECSContainer")

function ClientRECSContainer:create()
    self.recsCoreCreated = Signal.new()
end

function ClientRECSContainer:onStoreAndApi(store,api)
    self.recsCore = RECS.Core.new({
        RECS.BuiltInPlugins.CollectionService(),
        RECS.BuiltInPlugins.ComponentChangedEvent,
        createComponentPropsOverridePlugin(),
        createInjectorPlugin("getClientModule", function(_, name)
            return self.core:getModule(name)
        end),
        createInjectorPlugin("pzCore", self.core),
        createInjectorPlugin("store", store),
        createInjectorPlugin("api", api),
    })

    -- register all components
    for _, component in pairs(RecsComponents) do
        self.recsCore:registerComponent(component)
    end

    self.recsCore:registerSystems(Systems)
    self.recsCore:registerSteppers(Steppers)
end

function ClientRECSContainer:getCore()
    return Promise.async(function(resolve, reject)
        if not self.recsCore then self.recsCoreCreated:wait() end
        resolve(self.recsCore)
    end)
end

function ClientRECSContainer:preInit()
end

function ClientRECSContainer:init()
    local storeContainer = self.core:getModule("StoreContainer")
    local clientApi = self.core:getModule("ClientApi")
    Promise.all({
        storeContainer:getStore(),
        clientApi:getApi(),
    }):andThen(function(resolved)
        local store, api = unpack(resolved)
        self:onStoreAndApi(store,api)

        self.recsCore:start()
        self.recsCoreCreated:fire(self.recsCore)
    end)
end

function ClientRECSContainer:postInit()
end


return ClientRECSContainer