local J={}local s=game:GetService("\084\101\097\109\115")local p=game:GetService("\080\108\097\121\101\114\115")local Z=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local d=require(Z:WaitForChild("\078\101\118\101\114\109\111\114\101"))local t=d("\083\116\100")local F=t.randumb local G=d(game.ServerStorage.Configurations)local S=d(script.Parent.CtfDisplayManager)local C={}local q={}for J,s in ipairs(s:GetTeams())do C[s]={}q[s]=0 end local function a(J)for s,p in ipairs(s:GetTeams())do if p.TeamColor==J then return p end end return nil end function J.ClearTeamScores(J)for J,s in ipairs(s:GetTeams())do q[s]=0 S:UpdateScore(s,0)end end function J.HasTeamWon(J)for J,s in ipairs(s:GetTeams())do if q[s]>=G.CAPS_TO_WIN then return s end end return false end function J.GetWinningTeam(J)local p=0 local Z=nil for J,s in ipairs(s:GetTeams())do if q[s]>p then p=q[s]Z=s end end return Z end function J.AreTeamsTied(J)local p=s:GetTeams()local Z=0 local d=false for J,s in ipairs(p)do if q[s]==Z then d=true elseif q[s]>Z then d=false Z=q[s]end end return d end function J.AssignPlayerToTeam(s,J)local p local Z=math.huge for J,s in pairs(C)do if#s<Z then p=J Z=#s end end table.insert(C[p],J)J.Neutral=false J.TeamColor=p.TeamColor end function J.RemovePlayer(s,J)local p=a(J.TeamColor)local Z=C[p]for s=1,#Z,1 do if Z[s]==J then table.remove(Z,s)return end end end function J.ShuffleTeams(Z)for J,s in ipairs(s:GetTeams())do C[s]={}end local d=p:GetPlayers()local t=F:ShuffleList(d)for s,p in pairs(t)do J:AssignPlayerToTeam(p)end end function J.AddTeamScore(p,J,s)local Z=a(J)q[Z]=q[Z]+s S:UpdateScore(Z,q[Z])end return J
local TeamManager = {}

-- ROBLOX services

local Teams = game:GetService("Teams")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local require = require(ReplicatedStorage:WaitForChild("Nevermore"))
local std = require("Std")
local randumb = std.randumb

-- Game services
local Configurations = require(game.ServerStorage.Configurations)
local DisplayManager = require(script.Parent.CtfDisplayManager)

-- Local variables

local TeamPlayers = {}
local TeamScores = {}

-- Initialization

for _, team in ipairs(Teams:GetTeams()) do
	TeamPlayers[team] = {}
	TeamScores[team] = 0
end

-- Local Functions

local function GetTeamFromColor(teamColor)
	for _, team in ipairs(Teams:GetTeams()) do
		if team.TeamColor == teamColor then
			return team
		end
	end
	return nil
end

-- Public Functions

function TeamManager:ClearTeamScores()
	for _, team in ipairs(Teams:GetTeams()) do
		TeamScores[team] = 0
		DisplayManager:UpdateScore(team, 0)
	end
end

function TeamManager:HasTeamWon()
	for _, team in ipairs(Teams:GetTeams()) do
		if TeamScores[team] >= Configurations.CAPS_TO_WIN then
			return team
		end
	end
	return false
end

function TeamManager:GetWinningTeam()
	local highestScore = 0
	local winningTeam = nil
	for _, team in ipairs(Teams:GetTeams()) do
		if TeamScores[team] > highestScore then
			highestScore = TeamScores[team]
			winningTeam = team
		end
	end
	return winningTeam
end

function TeamManager:AreTeamsTied()
	local teams = Teams:GetTeams()
	local highestScore = 0
	local tied = false
	for _, team in ipairs(teams) do
		if TeamScores[team] == highestScore then
			tied = true
		elseif TeamScores[team] > highestScore then
			tied = false
			highestScore = TeamScores[team]
		end
	end
	return tied
end

function TeamManager:AssignPlayerToTeam(player)
	local smallestTeam
	local lowestCount = math.huge
	for team, playerList in pairs(TeamPlayers) do
		if #playerList < lowestCount then
			smallestTeam = team
			lowestCount = #playerList
		end
	end
	table.insert(TeamPlayers[smallestTeam], player)
	player.Neutral = false
	player.TeamColor = smallestTeam.TeamColor
end

function TeamManager:RemovePlayer(player)
	local team = GetTeamFromColor(player.TeamColor)
	local teamTable = TeamPlayers[team]
	for i = 1, #teamTable do
		if teamTable[i] == player then
			table.remove(teamTable, i)
			return
		end
	end
end

function TeamManager:ShuffleTeams()
	for _, team in ipairs(Teams:GetTeams()) do
		TeamPlayers[team] = {}
	end
	local players = Players:GetPlayers()
	local shuffledPlayers = randumb:ShuffleList(players)
	for _, player in pairs(shuffledPlayers) do 
		TeamManager:AssignPlayerToTeam(player)
	end
end

function TeamManager:AddTeamScore(teamColor, score)
	local team = GetTeamFromColor(teamColor)
	TeamScores[team] = TeamScores[team] + score
	DisplayManager:UpdateScore(team, TeamScores[team])
end

return TeamManager
