---------------------------------------------------
function module:CreateRanks()
	coroutine.wrap(function()
		
		local ranksInfo = main.signals.RetrieveRanksInfo:InvokeServer()
		local permRanksInfo = ranksInfo.PermRanks
		local ranksToSort = ranksInfo.Ranks
		local permissions = ranksInfo.Permissions
		
		--Organise ranks
		local rankPositions = {}
		local ranks = {}
		for i, rankDetails in pairs(ranksToSort) do
			local rankId = rankDetails[1]
			local rankName = rankDetails[2]
			table.insert(ranks, 1, {rankId, rankName, {}})
		end
		for i,v in pairs(ranks) do
			rankPositions[v[1]] = i
		end
		
		for pName, pDetails in pairs(permissions) do
			--Owner
			if pName == "owner" and rankPositions[5] then
				local ownerRankDetail = ranks[rankPositions[5]]
				table.insert(ownerRankDetail[3], {main.ownerName, "Owner", main:GetModule("cf"):GetUserImage(main.ownerId)})
			--SpecificUsers and PermRanks
			elseif pName == "specificusers" then
				for plrName, rankId in pairs(pDetails) do
					if #plrName > 1 then
						local rankDetail = ranks[rankPositions[rankId]]
						local boxInfo = {plrName, "Specific User", main:GetModule("cf"):GetUserImage(main:GetModule("cf"):GetUserId(plrName))}
						table.insert(rankDetail[3], boxInfo)
					end
				end
				for i, record in pairs(permRanksInfo) do
					if not record.RemoveRank then
						local rankDetail = ranks[rankPositions[record.Rank]]
						if rankDetail then
							local boxInfo = {main:GetModule("cf"):GetName(record.UserId), "PermRank", main:GetModule("cf"):GetUserImage(record.UserId), record}
							table.insert(rankDetail[3], boxInfo)
						end
					end
				end
			elseif pName == "gamepasses" then
				--Gamepasses
				for gamepassId, gamepassInfo in pairs(pDetails) do
					if not main:GetModule("cf"):FindValue(main.products, gamepassId) then
						local rankDetail = ranks[rankPositions[gamepassInfo.Rank]]
						if rankDetail then
							local boxInfo = {gamepassInfo.Name, "Gamepass", gamepassInfo.IconImageAssetId, tonumber(gamepassId), gamepassInfo.PriceInRobux}
							table.insert(rankDetail[3], boxInfo)
						end
					end
				end
			elseif pName == "assets" then
				--Assets
				for assetId, assetInfo in pairs(pDetails) do
					local rankDetail = ranks[rankPositions[assetInfo.Rank]]
					if rankDetail then
						local boxInfo = {assetInfo.Name, "Asset", main:GetModule("cf"):GetAssetImage(assetId), tonumber(assetId), assetInfo.PriceInRobux}
						table.insert(rankDetail[3], boxInfo)
					end
				end
			elseif pName == "groups" then
				--Groups
				for groupId, groupInfo in pairs(pDetails) do
					for roleName, roleInfo in pairs(groupInfo.Roles) do
						if roleInfo.Rank then
							local rankDetail = ranks[rankPositions[roleInfo.Rank]]
							if rankDetail then
								local boxInfo = {groupInfo.Name.." | "..roleName, "Group", groupInfo.EmblemUrl, tonumber(groupId)}
								table.insert(rankDetail[3], boxInfo)
							end
						end
					end
				end
			elseif otherPermissions[pName] then
				--Other
				local info = otherPermissions[pName]
				local rank = permissions[info[1]]
				if rank > 0 then
					local rankDetail = ranks[rankPositions[rank]]
					if rankDetail then
						local boxInfo = {info[2], info[3], string.upper(string.sub(info[1], 1, 1))}
						table.insert(rankDetail[3], boxInfo)
					end
				end
			end
		end
		--Can view PermRank menu
		local canModifyPermRanks = false
		if main.pdata.Rank >= (main.commandRanks.permrank or 4) then
			canModifyPermRanks = true
		end
		
		--Clear labels
		main:GetModule("cf"):ClearPage(pages.ranks)
			
		--Setup labels
		local labelCount = 0
		for i,v in pairs(ranks) do
			local rankId = v[1]
			local rankName = v[2]
			local boxes = v[3]
			--
			labelCount = labelCount + 1
			local rankTitle = templates.rankTitle:Clone()
			rankTitle.Name = "Label".. labelCount
			rankTitle.RankIdFrame.TextLabel.Text = rankId
			rankTitle.RankName.Text = rankName
			rankTitle.Visible = true
			rankTitle.Parent = pages.ranks
			--
			for _, boxInfo in pairs(boxes) do
				labelCount = labelCount + 1
				local boxTitle = boxInfo[1]
				local boxDesc = boxInfo[2]
				local boxImage = boxInfo[3]
				local rankItem = templates.rankItem:Clone()
				rankItem.Name = "Label".. labelCount
				rankItem.ItemTitle.Text = boxTitle
				rankItem.ItemDesc.Text = boxDesc
				if #tostring(boxImage) == 1 then
					rankItem.ItemIcon.Text = boxImage
					rankItem.ItemIcon.Visible = true
					rankItem.ItemImage.Visible = false
				else
					if tonumber(boxImage) then
						boxImage = "rbxassetid://"..boxImage
					end
					rankItem.ItemImage.Image = tostring(boxImage)
				end
				local xScale = 0.7
				rankItem.Unlock.Visible = false
				rankItem.ViewMore.Visible = false
				if boxDesc == "Gamepass" or boxDesc == "Asset" then
					local productId = boxInfo[4]
					local productPrice = boxInfo[5]
					rankItem.ItemImage.BackgroundTransparency = 1
					rankItem.Unlock.Visible = true
					rankItem.Unlock.MouseButton1Down:Connect(function()
						buyFrame.ProductName.Text = boxTitle
						buyFrame.ProductImage.Image = boxImage
						buyFrame.PurchaseToUnlock.TextLabel.Text = rankName
						buyFrame.InGame.TextLabel.Text = main.gameName
						buyFrame.MainButton.Price.Text = (productPrice or 0).." "
						buyFrame.MainButton.ProductId.Value = productId
						buyFrame.MainButton.ProductType.Value = boxDesc
						main:GetModule("cf"):ShowWarning("BuyFrame")
					end)
					xScale = 0.4
				elseif boxDesc == "PermRank" then
					local record = boxInfo[4]
					if canModifyPermRanks then
						local viewMore = rankItem.ViewMore
						viewMore.Visible = true
						viewMore.MouseButton1Down:Connect(function()
							main:GetModule("cf"):ShowPermRankedUser{boxTitle, record.UserId, record.RankedBy}
						end)
					end
					xScale = 0.6
				else
					xScale = 0.7
				end
				rankItem.ItemTitle.Size = UDim2.new(xScale, 0, rankItem.ItemTitle.Size.Y.Scale, 0)
				rankItem.ItemDesc.Size = UDim2.new(xScale, 0, rankItem.ItemDesc.Size.Y.Scale, 0)
				rankItem.Visible = true
				rankItem.Parent = pages.ranks
			end
		end
		
		--Canvas Size
		if labelCount >= 2 then
			for i = 1,2 do
				local firstLabel = pages.ranks["Label1"]
				local finalLabel = pages.ranks["Label".. labelCount]
				pages.ranks.CanvasSize = UDim2.new(0, 0, 0, (finalLabel.AbsolutePosition.Y + finalLabel.AbsoluteSize.Y - firstLabel.AbsolutePosition.Y))
			end
		end
	
	end)()
end