import Janus, { JanusJS } from "janus-gateway";
import Videoroom from "./Videoroom";
import Subscriber from "../services/Subscriber";
import SubscriberEventsHandler from "../services/SubscribeEventHandler";
import eventEmitter from "../repositories/eventEmitter";
import { PUBLISHING_EVENTS } from "../events";

class SubVideoroom extends Videoroom{

    protected readonly type = 'subscriber';
    protected handler: JanusJS.PluginHandle | undefined;
    private subscriber: Subscriber | undefined;
    public mediaStream: MediaStream = new MediaStream();

    constructor(
        public readonly roomID: number,
        protected readonly userID: string,
        protected readonly janusSession: Janus,
        protected readonly rid: number,
        protected readonly streams: any
    ) {
        super();
    }

    public async initiate(): Promise<JanusJS.PluginHandle> {
        await this.attachVideoroom();
        return this.handler as JanusJS.PluginHandle;
    };

    protected attachVideoroom(): Promise<JanusJS.PluginHandle> {
        return new Promise<JanusJS.PluginHandle>((resolves: (value: JanusJS.PluginHandle) => void) => {
            this.janusSession.attach({
                plugin: 'janus.plugin.videoroom',
                opaqueId: this.userID.toString(),
                success: async (handle: JanusJS.PluginHandle) => {
                    this.handler = handle;
                    await this.perpareRTC();
                    resolves(handle);
                    return {};
                },
                onmessage: async (msg: JanusJS.Message, jsep: JanusJS.JSEP) => {
                    await this.handleMessages(msg, jsep);
                },
                onremotetrack: (track: MediaStreamTrack, mid: string, on: boolean) => {
                    this.mediaStream.addTrack(track);
                    eventEmitter.emit(PUBLISHING_EVENTS.RECIVED_TRACK, track, on, this.userID, this.rid);
                },
                slowLink: (uplink, lost, mid) => {
                    console.log(uplink, lost, mid);
                    alert('SEEEELOWWWW CONNECTION... يا فقراء');
                },
                oncleanup: () => {
                    alert('Should clean things');
                },
            } as JanusJS.PluginOptions);
        });
    };
    protected async perpareRTC(): Promise<void> { 
        const handler = this.handler  as JanusJS.PluginHandle;
        this.subscriber = new Subscriber(this.roomID, handler);
        this.subscriber.subscribeToNewFeeds(this.rid, this.streams);
    }
    protected async handleMessages(msg: JanusJS.Message, jsep: JanusJS.JSEP) : Promise<void> {
        new SubscriberEventsHandler({
            msg,
            jsep,
            handleRemoteSDP: () => this.subscriber?.doAnswer(jsep as JanusJS.JSEP)
        })
    }

};

export default SubVideoroom;