export interface IProviderMediaInfo {
  addr: string;
  port: number;
  sipPt: number;
}

export interface IWebRtcLinkTarget {
  sessionId: string;
  media: IProviderMediaInfo;
}

export class WebRtcLinkManager {
  private sessionToCall = new Map<string, string>();
  private callToSession = new Map<string, string>();
  private pendingCallMedia = new Map<string, IProviderMediaInfo>();

  acceptCall(callId: string, sessionId: string): IProviderMediaInfo | null {
    const previousCallId = this.sessionToCall.get(sessionId);
    if (previousCallId && previousCallId !== callId) {
      this.callToSession.delete(previousCallId);
    }

    const previousSessionId = this.callToSession.get(callId);
    if (previousSessionId && previousSessionId !== sessionId) {
      this.sessionToCall.delete(previousSessionId);
    }

    this.sessionToCall.set(sessionId, callId);
    this.callToSession.set(callId, sessionId);

    const pendingMedia = this.pendingCallMedia.get(callId) ?? null;
    if (pendingMedia) {
      this.pendingCallMedia.delete(callId);
    }
    return pendingMedia;
  }

  noteCallAnswered(callId: string, media: IProviderMediaInfo): IWebRtcLinkTarget | null {
    const sessionId = this.callToSession.get(callId);
    if (!sessionId) {
      this.pendingCallMedia.set(callId, media);
      return null;
    }

    return { sessionId, media };
  }

  removeSession(sessionId: string): string | null {
    const callId = this.sessionToCall.get(sessionId) ?? null;
    this.sessionToCall.delete(sessionId);
    if (callId) {
      this.callToSession.delete(callId);
    }
    return callId;
  }

  cleanupCall(callId: string): string | null {
    const sessionId = this.callToSession.get(callId) ?? null;
    this.callToSession.delete(callId);
    this.pendingCallMedia.delete(callId);
    if (sessionId) {
      this.sessionToCall.delete(sessionId);
    }
    return sessionId;
  }
}
