/**
 * TeamManager - Multi-agent team and messaging service.
 *
 * Manages agent teams (logical groupings), inter-agent messaging,
 * and broadcasts via SharedStateBus.
 */
export class TeamManager {
    teams = new Map();
    messages = [];
    bus;
    maxTeams;
    maxMessages;
    nextTeamId = 1;
    nextMsgId = 1;
    constructor(options) {
        this.maxTeams = options?.maxTeams ?? 10;
        this.maxMessages = options?.maxMessages ?? 1000;
    }
    setBus(bus) {
        this.bus = bus;
    }
    createTeam(opts) {
        if (this.teams.size >= this.maxTeams) {
            throw new Error(`Maximum team limit reached (${this.maxTeams})`);
        }
        for (const team of this.teams.values()) {
            if (team.name === opts.name) {
                throw new Error(`Team "${opts.name}" already exists`);
            }
        }
        const team = {
            id: `team_${this.nextTeamId++}`,
            name: opts.name,
            description: opts.description,
            agents: opts.agents || [],
            createdAt: Date.now(),
        };
        this.teams.set(team.id, team);
        this.bus?.publish("state:teams", "teamManager", {
            action: "created",
            team: { ...team },
        });
        return team;
    }
    deleteTeam(idOrName) {
        let team;
        for (const t of this.teams.values()) {
            if (t.id === idOrName || t.name === idOrName) {
                team = t;
                break;
            }
        }
        if (!team)
            return false;
        this.teams.delete(team.id);
        this.bus?.publish("state:teams", "teamManager", {
            action: "deleted",
            team: { ...team },
        });
        return true;
    }
    getTeam(idOrName) {
        for (const t of this.teams.values()) {
            if (t.id === idOrName || t.name === idOrName)
                return t;
        }
        return undefined;
    }
    listTeams() {
        return Array.from(this.teams.values());
    }
    addAgentToTeam(teamIdOrName, agentId) {
        const team = this.getTeam(teamIdOrName);
        if (!team)
            throw new Error(`Team "${teamIdOrName}" not found`);
        if (!team.agents.includes(agentId)) {
            team.agents.push(agentId);
        }
    }
    removeAgentFromTeam(teamIdOrName, agentId) {
        const team = this.getTeam(teamIdOrName);
        if (!team)
            throw new Error(`Team "${teamIdOrName}" not found`);
        team.agents = team.agents.filter((a) => a !== agentId);
    }
    sendMessage(from, to, content) {
        if (this.messages.length >= this.maxMessages) {
            this.messages.splice(0, Math.max(1, Math.floor(this.maxMessages * 0.1)));
        }
        const msg = {
            id: `msg_${this.nextMsgId++}`,
            from,
            to,
            content,
            timestamp: Date.now(),
        };
        this.messages.push(msg);
        this.bus?.publish("agent:message", from, msg);
        return msg;
    }
    broadcast(from, teamIdOrName, content) {
        const team = this.getTeam(teamIdOrName);
        if (!team)
            throw new Error(`Team "${teamIdOrName}" not found`);
        const sent = [];
        for (const agentId of team.agents) {
            if (agentId !== from) {
                sent.push(this.sendMessage(from, agentId, content));
            }
        }
        return sent;
    }
    getInbox(agentId) {
        return this.messages.filter((m) => m.to === agentId || m.to === "*");
    }
    getConversation(agent1, agent2) {
        return this.messages.filter((m) => (m.from === agent1 && m.to === agent2) ||
            (m.from === agent2 && m.to === agent1));
    }
}
