<?php

declare(strict_types=1);

namespace Blax\WebRtc\Rooms;

/**
 * A call room: the peers currently in a party-to-party / group call, each with
 * optional presence `info` (name, avatar, role — whatever the app attaches). The
 * media engine (or, for P2P, the peers themselves) forwards audio between them.
 */
final class Room
{
    /** @var array<string,array<string,mixed>> peer id => presence info */
    private array $members = [];

    public function __construct(
        public readonly string $id,
        public readonly RoomType $type = RoomType::Public,
    ) {}

    /**
     * Add a member (with optional presence info) and return the OTHER peers that
     * were already present — the set to mesh / notify.
     *
     * @param  array<string,mixed>  $info
     * @return array<int,string>
     */
    public function add(string $peerId, array $info = []): array
    {
        $others = array_keys($this->members);
        $this->members[$peerId] = $info;

        return $others;
    }

    public function remove(string $peerId): void
    {
        unset($this->members[$peerId]);
    }

    public function has(string $peerId): bool
    {
        return isset($this->members[$peerId]);
    }

    /** @return array<int,string> */
    public function peers(): array
    {
        return array_keys($this->members);
    }

    /** @return array<string,array<string,mixed>> peer id => presence info */
    public function members(): array
    {
        return $this->members;
    }

    /** @return array<string,mixed> */
    public function info(string $peerId): array
    {
        return $this->members[$peerId] ?? [];
    }

    public function isEmpty(): bool
    {
        return $this->members === [];
    }

    public function count(): int
    {
        return count($this->members);
    }
}
