import type { AppPlayer, AppPlayerTeam, PlayerTeamId } from '../types/appPlayers'; import { asPlayerTeamId } from '../types/ids'; import { DEFAULT_PLAYER_RING_COLOR, normalizeAppPlayerTeam } from '../types/appPlayers'; import { normalizeHexColor } from '../npcs/npcGroups'; /** Имя команды уникально среди плоского списка (без вложенности). */ export function uniquePlayerTeamName( base: string, teams: readonly AppPlayerTeam[], exceptId?: PlayerTeamId | null, ): string { const root = base.trim() || 'Team'; const used = new Set( teams.filter((t) => t.id !== exceptId).map((t) => t.name.trim().toLowerCase()), ); if (!used.has(root.toLowerCase())) return root; let i = 2; while (used.has(`${root.toLowerCase()} (${String(i)})`)) i += 1; return `${root} (${String(i)})`; } export function normalizeAppPlayerTeams(raw: unknown): AppPlayerTeam[] { if (!Array.isArray(raw)) return []; const out: AppPlayerTeam[] = []; const ids = new Set(); for (const item of raw) { const t = normalizeAppPlayerTeam(item); if (!t || ids.has(t.id)) continue; ids.add(t.id); out.push(t); } return out; } export function assignPlayerToTeam( players: readonly AppPlayer[], playerId: string, teamId: PlayerTeamId | null, teamIds: Set, ): AppPlayer[] { return players.map((p) => { if (p.id !== playerId) return p; if (teamId && !teamIds.has(teamId)) return { ...p, teamId: null }; return { ...p, teamId }; }); } /** Удаление команды: игроки этой команды становятся без команды. */ export function deletePlayerTeam( teams: readonly AppPlayerTeam[], players: readonly AppPlayer[], teamId: PlayerTeamId, ): { teams: AppPlayerTeam[]; players: AppPlayer[] } { return { teams: teams.filter((t) => t.id !== teamId), players: players.map((p) => (p.teamId === teamId ? { ...p, teamId: null } : p)), }; } export function createPlayerTeamDraft( name: string, color: string | undefined, teams: readonly AppPlayerTeam[], ): AppPlayerTeam { const id = asPlayerTeamId(`pteam_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`); return { id, name: uniquePlayerTeamName(name, teams), color: normalizeHexColor(color, DEFAULT_PLAYER_RING_COLOR), }; }