local K=require(script.Parent.Parent.t)local N=require(script.Parent.LootPool)local y={random=Random.new();luck=1}local l=K.intersection(function(K)return N.isLootPool(K),"\079\098\106\101\099\116 \109\117\115\116 \098\101 \097 \118\097\108\105\100 \076\111\111\116\080\111\111\108"end)local L={}L.__index=L local J={}J.__index=J function J.new()return setmetatable({_pools={};_state=table.clone(y)},J)end function J.withState(N,K)N._state=K return N end function J.withLootPool(N,K)table.insert(N._pools,K)return N end function J.withLootPools(K,...)local N={...}table.move(N,1,#N,#K._pools+1,K._pools)return K end function J.build(K)return L.new(K._pools,K._state)end function L.new(N,y)assert((K.array(l))(N))assert(#N>=1,"\089\111\117 \109\117\115\116 \112\114\111\118\105\100\101 \097\116 \108\101\097\115\116 \111\110\101 \112\111\111\108 \105\110 \097 \108\111\111\116 \116\097\098\108\101")return setmetatable({_pools=N,_state=y},L)end function L.builder()return J.new()end function L.getState(K)return K._state end function L.roll(K)local N={}for y,l in ipairs(K._pools)do local L=l:roll(K._state)table.move(L,1,#L,#N+1,N)end return N end return L
local t = require(script.Parent.Parent.t)
local LootPool = require(script.Parent.LootPool)

local DEFAULT_LOOT_STATE = {
    random = Random.new(),
    luck = 1,
}

local isLootPool = t.intersection(function(object)
    return LootPool.isLootPool(object), "Object must be a valid LootPool"
end)

local LootTable = {}
LootTable.__index = LootTable

-- Table builder
local LootTableBuilder = {}
LootTableBuilder.__index = LootTableBuilder

function LootTableBuilder.new()
    return setmetatable({
        _pools = {},
        _state = table.clone(DEFAULT_LOOT_STATE)
    }, LootTableBuilder)
end

function LootTableBuilder:withState(state)
    self._state = state
    return self
end

function LootTableBuilder:withLootPool(pool)
    table.insert(self._pools, pool)
    return self
end

function LootTableBuilder:withLootPools(...)
    local pools = { ... }
    table.move(pools, 1, #pools, #self._pools + 1, self._pools)
    return self
end

function LootTableBuilder:build()
    return LootTable.new(self._pools, self._state)
end

--[[
    Creates a new loot table

    Loot tables are containers of individual loot pools
]]
function LootTable.new(pools, state)
    assert(t.array(isLootPool)(pools))
    assert(#pools >= 1, "You must provide at least one pool in a loot table")

    return setmetatable({
        _pools = pools,
        _state = state,
    }, LootTable)
end

function LootTable.builder()
    return LootTableBuilder.new()
end

function LootTable:getState()
    return self._state
end

function LootTable:roll()
    local results = {}

    for _, pool in ipairs(self._pools) do
        local poolRollResults = pool:roll(self._state)
        table.move(poolRollResults, 1, #poolRollResults, #results + 1, results)
    end

    return results
end

return LootTable