import { Injectable } from '@nestjs/common';
import type { PresencePort } from './presence.port';

/**
 * In-memory focus tracker (single instance). Keyed on userId (the stable externalId the
 * gateway has as principal.userId). NOTE: room membership ≠ viewing — the sidebar joins
 * every thread room for live updates, so presence uses an explicit `focus_thread` signal.
 * Multi-replica prod uses {@link RedisPresenceService} instead (wired when REDIS_URL is set).
 *
 * Methods are async to satisfy the PresencePort seam; the map is mutated synchronously, so an
 * un-awaited setFocus is still visible to an immediately-following isViewing.
 */
@Injectable()
export class PresenceService implements PresencePort {
  private readonly focus = new Map<string, { userId: string; threadId: string | null }>(); // socketId → focus

  async setFocus(socketId: string, userId: string, threadId: string | null): Promise<void> {
    this.focus.set(socketId, { userId, threadId });
  }

  async clearSocket(socketId: string): Promise<void> {
    this.focus.delete(socketId);
  }

  async isViewing(userId: string, threadId: string): Promise<boolean> {
    for (const f of this.focus.values()) if (f.userId === userId && f.threadId === threadId) return true;
    return false;
  }
}
