import Janus, { JanusJS } from "janus-gateway";
import JanusInstance from "./entities/JanusInstance";
import PubVideoroom from "./entities/PubVideoroom";
import { DeviceInfo, JanusDevices, WhatToPublish } from "./types";


class Janky {

    public janusInstance: JanusInstance | undefined;
    public janusSession: Janus | undefined;
    public videoroomPub: PubVideoroom | undefined;
    public handler: JanusJS.PluginHandle | undefined;

    constructor(
        private readonly roomID: number,
        private readonly userID: string,
        public publishType: WhatToPublish,
    ) {}
    
    public async connectJanus(debug: boolean): Promise<void> {
        this.janusInstance = new JanusInstance(debug);
        this.janusSession = await this.janusInstance.initiate();
    }

    public async startPublishing(): Promise<void> {
        this.videoroomPub = new PubVideoroom(
            this.roomID,
            this.userID,
            this.janusSession as Janus,
            this.publishType
        );
        this.handler = await this.videoroomPub.initiate();
    }

    public isAudioMuted(): boolean {
        return this.handler?.isAudioMuted() ?? false;
    };
    public isVideoMuted(): boolean {
        return this.handler?.isVideoMuted() ?? false;
    }
    public async unpublish(): Promise<void> {
        await this.videoroomPub?.unpublish();
    } 
    public isMobile(): boolean {
        const mobilePattern = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
        return mobilePattern.test(window.navigator.userAgent);
    }

    public listDevices() {
        return new Promise<DeviceInfo[]>((resolves: (data: DeviceInfo[]) => void) => {
            (Janus as unknown as JanusDevices).listDevices(
                (data: DeviceInfo[]) => {
                    resolves(data);
                }
            );
        });
    }

    public switchByType(publishType: WhatToPublish) {
        this.videoroomPub?.switchByType(publishType);
    }

    public switchByDevice(
        audioDeviceId: string | undefined,
        videoDeviceId: string | undefined
    ) {
        return this.videoroomPub?.switchByDevice(audioDeviceId, videoDeviceId);
    }

    public toggleAudio() {
        if(this.isAudioMuted()) {
            this.videoroomPub?.unmuteAudio();
            return true;
        }
        this.videoroomPub?.muteAudio();
        return false;
    }

    public toggleVideo() {
        if(this.isVideoMuted()) {
            this.videoroomPub?.unmuteVideo();
            return true;
        }
        this.videoroomPub?.muteVideo();
        return;
    }

};

export default Janky;

 