import BrowserService from "./BrowserService";

export default class MediaRecorderManager {
    private _browserService : BrowserService;
    private _isPreparedToRecordMedia : boolean;
    private _recordedChunks : Blob[];
    private _recorder : MediaRecorder;
    private _captureId : number;

    constructor(browserService : BrowserService) {
        this._browserService = browserService;
        this._isPreparedToRecordMedia = false;
        this._recordedChunks = [];
    }

    get isPreparedToRecordMedia(): boolean {
        return this._isPreparedToRecordMedia;
    }

    prepareRecording() : Promise<void>{
        // console.log("prepare");
        return new Promise((resolve, reject) => {
            this._recordedChunks = [];
            this._browserService.captureStreamOnWindow()
            .then((capturedStream) => {
                if (capturedStream.stream !== null) {
                    // console.log('id:', capturedStream.id);
                    capturedStream.stream.getVideoTracks()[0].onended = () => {
                        // console.log('ended');
                        this.destroyRecording();
                    };
                    this._captureId = capturedStream.id;
                    const options = {mimeType: 'video/webm; codecs=vp9'};
                    this._recorder = new MediaRecorder(capturedStream.stream, options);
                    this._recorder.ondataavailable = event => {
                            // console.log('video event:',event);
                            if (event.data.size > 0) {
                                // console.log('push on recordedChunks');
                                this._recordedChunks.push(event.data);
                            }
                        };
                    this._recorder.onerror = (error) => {
                        console.log('error',error);
                    }
                    this._isPreparedToRecordMedia = true;
                    resolve();
                } else {
                    reject();
                }
            })
            .catch((e) => {
                console.error(e)
                reject(e);
            })
        })
    }

    destroyRecording() : Promise<void> {
        // console.log("destory");
        this._recordedChunks = [];
        return new Promise((resolve, reject) => {
            if (!this._isPreparedToRecordMedia) {
                resolve();
            } else {
                this._recorder.stream.getTracks().forEach((track: MediaStreamTrack) => {
                    // console.log('stop track');
                    track.stop();
                });
                this._browserService.hideCapture(this._captureId);
                this._isPreparedToRecordMedia = false;
                resolve();
            }
        })
    }

    startRecording() : Promise<void> {
        return new Promise((resolve, reject) => {
            // console.log("start");
            if (!this._isPreparedToRecordMedia) {
                resolve();
            } else {
                this._recordedChunks = [];
                this._recorder.onstart = () => {
                    resolve();
                }
                try {
                    this._recorder.start();
                } catch(e) {
                    reject(e);
                }

            }
        })

    }

    stopRecording() : Promise<void>{
        return new Promise((resolve, reject) => {
            if (!this._isPreparedToRecordMedia) {
                resolve();
            } else {
                this._recordedChunks = [];
                this._recorder.onstop = () => {
                    resolve();
                }
                if (this._recorder.state !== "inactive") {
                    try {
                        this._recorder.stop();
                    } catch(e) {
                        reject(e);
                    }
                } else {
                    resolve();
                }
            }
        })


    }

    getRecordedChunks() : Blob | undefined {
        if (this._recordedChunks.length > 0) {
            return new Blob(this._recordedChunks, {type : 'video/webm'});
        }
    }

}