<?php /** @var $guest */ ?>
@extends('layouts.meeting')
@section('content')

    <div id="meetComponent">

        {{--<h5 class="bg-dark font-weight-bold text-white m-0 py-3 px-4 d-flex">
            <span>Meeting</span>
            <span class="ml-auto" v-if="!started">
                Connecting...
            </span>
            <span class="ml-auto" v-if="started">
                <i class="fa fa-clock mr-1 text-light"></i>
                @{{ timeDisplay() }}
            </span>
        </h5>--}}

        @if(!$guest)
            <div class="d-flex align-items-center justify-content-center py-3 border-bottom">
                <span class="mr-3">
                    {{ $pro->name_display }} | {{ $pro->is_video_visit_assistant ? 'ASSISTANT' : 'MCP' }}
                </span>
                <button class="btn btn-sm btn-primary px-4 font-weight-bold"
                        v-on:click.prevent="nextPatient()"
                        :disabled="client || checkingForNextPatient || started">Next Patient</button>
                <span v-if="patientInQueue && !started" class="patient-in-q-alert text-warning text-sm ml-2 small">
                    <i class="fa fa-circle"></i>
                </span>
                <span v-if="!patientInQueue && !started" class="text-success text-sm ml-2 small">
                    <i class="fa fa-circle"></i>
                </span>
            </div>
            <div v-if="!started && noNextPatient" class="bg-light rounded text-center py-1 font-weight-bold text-sm my-3 mx-3">@{{ noNextPatient }}</div>
        @endif

        <div class="">
            <div class="py-3 text-center" v-if="started">
                <h6 class="text-black font-weight-bold m-0">Call in progress: @{{ timeDisplay() }}</h6>
            </div>
            @if($guest)
            <div class="py-3 text-center" v-if="!pro || !started">
                <h6 class="text-black font-weight-bold m-0">Please wait. Your doctor will be with you shortly...</h6>
            </div>
            @endif
            <div class="main-view mx-auto" <?= !$guest ? 'v-show="!!client"' : '' ?>>
                <div id="self-view" class="full-view" data-type="{{ $guest ? 'CLIENT' : 'PRO' }}"></div>
                <div class="thumbs">
                    <div id="remote-view-1" class="remote-view disconnected-view"
                         data-stream="" data-from="" data-type=""></div>
                    <div id="remote-view-2" class="remote-view disconnected-view"
                         data-stream="" data-from="" data-type=""></div>
                </div>
                <button class="btn btn-danger rounded-circle hang-up"
                        v-if="started"
                        title="Leave Call"
                        v-on:click.prevent="hangUp()">
                    <i class="fa fa-phone"></i>
                </button>
                <button class="btn btn-success rounded-circle call-mcp"
                        v-if="selfUserType === 'ASSISTANT'"
                        title="Call MCP Pro"
                        v-on:click.prevent="callMCPPro()">
                    <i class="fa fa-user-md"></i>
                </button>
            </div>
        </div>

    </div>

    <script>

        new Vue({
            el: '#meetComponent',
            delimiters: ['@{{', '}}'],
            data: {
                time: 0,
                startTime: 0,
                started: false,
                client: false,
                pro: false,

                selfName: '',
                selfToken: '',

                @if($guest)
                clientUid: '',
                checkInToken: '',
                @endif

                otSessionId: '',

                @if(!$guest)
                checkingForNextPatient: false,
                noNextPatient: false,
                @endif

                otSession: false,

                selfUserType: false,
                patientInQueue: false,
            },
            methods: {
                @if(!$guest)
                pollForNextPatient: function() {
                    if(!this.started) {
                        this.nextPatient(true);
                    }
                },
                nextPatient: function(_pollOnly = false) {
                    var self = this;
                    if(!_pollOnly) this.checkingForNextPatient = true;
                    $.post('/api/client/getNextClientForVideoVisit', {}, function(_data) {
                        if(_pollOnly) {
                            self.patientInQueue = _data.success;
                        }
                        else {
                            self.checkingForNextPatient = false;
                            if(!_data.success) {
                                self.noNextPatient = _data.message;
                                window.setTimeout(function() {
                                    self.noNextPatient = false;
                                }, 2000);
                            }
                            else {
                                // get ot session key from client record
                                self.client = true;
                                self.clientUid = _data.data;
                                self.getOpenTokSessionId(function() {
                                    self.selfName = '{{ $pro->name_display  }}';
                                    $.post('/api/openTok/getClientToken', {
                                        opentokSessionId: self.otSessionId,
                                        name: self.selfName
                                    }, function (_data) {
                                        self.selfToken = _data.data;
                                        self.initOpenTok();
                                    });
                                });
                            }
                        }
                    }, 'json');
                },
                @endif
                getInitials: function(_name) {
                    var parts = _name.split(/\s+/g);
                    parts = parts.map(_part => _part[0]);
                    return parts.join('');
                },
                timeDisplay: function() {
                    var seconds = this.time / 1000,
                        minutes = parseInt(seconds / 60, 10);
                    seconds = parseInt(seconds % 60, 10);
                    return minutes + " min, " + seconds + " sec";
                },
                hangUp: function() {
                    if(this.otSession) {
                        try {
                            this.otSession.disconnect();
                        }
                        catch (e) {
                            console.log('Was already disconnected.');
                        }
                        this.otSession = false;
                        this.otSessionId = '';
                        this.started = false;
                        this.startTime = false;
                        @if(!$guest)
                        this.client = false;
                        @else
                        window.location = '/join';
                        @endif
                    }
                },
                @if(!$guest)
                callMCPPro: function() {

                    // put client in mcp queue
                    $.ajax({
                        type: 'post',
                        url: '/api/clientVideoVisit/putVideoVisitInMcpQueue',
                        headers: {
                            'sessionKey': localStorage.sessionKey
                        },
                        data: {uid: this.clientUid},
                        dataType: 'json'
                    })
                    .done(function (_data) {
                        console.log(_data);
                        if(_data.success) {
                            new Noty({
                                theme: 'mint',
                                type: 'success',
                                text: 'Client added to MCP call queue',
                                progressBar: false,
                                timeout: 1500,
                            }).show();
                        }
                        else {
                            new Noty({
                                theme: 'mint',
                                type: 'alert',
                                text: _data.message,
                                progressBar: false,
                                timeout: 3000,
                            }).show();
                        }
                    })
                    .fail(function (_data) {
                        console.log(_data);
                        // alert(_data.message);
                    });

                },
                @endif
                // OT methods
                initOpenTok: function() {

                    /* fake video feed (temp) */
                    const randomColour = () => {
                        return Math.round(Math.random() * 255);
                    };

                    const canvas = document.createElement('canvas');
                    canvas.width = 640;
                    canvas.height = 480;
                    const ctx = canvas.getContext('2d');
                    var pos = 100;
                    window.setInterval(function() {
                        ctx.clearRect(0, 0, canvas.width, canvas.height);
                        ctx.font = "20px Georgia";
                        ctx.fillStyle = `rgb(220, 220, 220)`;
                        var userType = '<?= $guest? "Client" : "Pro" ?>';
                        ctx.fillText("Video feed from " + userType, 20, pos);
                        pos += 5;
                        if(pos > canvas.height) pos = 100;
                    }, 1000);

                    var self = this;

                    var apiKey = '<?= env('TOKBOX_API_KEY', '46678902') ?>';
                    var sessionId = this.otSessionId;
                    var token = this.selfToken;

                    // destroy if existing
                    self.hangUp();

                    self.otSession = OT.initSession(apiKey, sessionId);

                    // peer connected
                    self.otSession.on('streamCreated', function streamCreated(event) {
                        var subscriberOptions = {
                            insertMode: 'append',
                            width: '100%',
                            height: '100%'
                        };

                        var remoteViewElem = 'remote-view-1';
                        if($('#remote-view-1').attr('data-stream')) {
                            remoteViewElem = 'remote-view-2';
                        }

                        self.otSession.subscribe(event.stream, remoteViewElem, subscriberOptions, self.handleOpenTokError);

                        remoteViewElem = $('#' + remoteViewElem);
                        remoteViewElem.attr('data-stream', event.stream.id);
                        remoteViewElem.attr('data-from', event.stream.connection.data.split('|')[0]);

                        var userType = event.target.connection.data.split('|')[1];
                        if(userType === 'CLIENT') {
                            remoteViewElem.attr('data-type', 'CLIENT');
                        }
                        else {
                            remoteViewElem.attr('data-type', 'PRO');
                        }

                        @if($guest)
                        self.pro = true;
                        @else
                        self.client = true;
                        @endif

                        if(!self.startTime) {
                            self.startTime = new Date().getTime();
                            window.setInterval(function() {
                                self.time = new Date().getTime() - self.startTime;
                            }, 1000);
                            self.started = true;
                        }

                        self.activateParty(event.stream.id);
                    });

                    // peer disconnected
                    self.otSession.on("streamDestroyed", function(event) {
                        console.log('streamDestroyed from ' + event.stream.connection.data);
                        onPeerDisconnection(event, event.stream.connection.data);
                    });
                    // self.otSession.on("connectionDestroyed", function(event) {
                    //     debugger;
                    //     console.log('connectionDestroyed from ' + event.connection.data);
                    //     onPeerDisconnection(event, event.connection.data);
                    // });

                    function onPeerDisconnection(event, data) {
                        if(event.stream && $('.full-view[data-stream="' + event.stream.id + '"]').length) {
                            self.activateParty('self');
                        }
                        @if(!$guest)
                        if(data.split('|')[1] === 'CLIENT') {
                            self.hangUp();
                        }
                        @endif

                        if(event.stream) {
                            var remoteViewElem = $('[data-stream="' + event.stream.id + '"]');
                            if(remoteViewElem.length) {
                                remoteViewElem.attr('data-stream', '');
                                remoteViewElem.attr('data-from', '');
                            }
                            remoteViewElem.addClass('disconnected-view')
                        }

                        @if($guest)
                        self.pro = false;
                        @else
                        if(data.split('|')[1] === 'CLIENT') {
                            self.client = false;
                        }
                        @endif

                        // if no other parties in call, hang up
                        if(!$('[data-stream]:not([data-stream=""])').length) {
                            self.hangUp();
                        }
                    }

                    // self connected
                    self.otSession.on("sessionConnected", function(event) {
                        console.log(event);
                        self.selfUserType = event.target.connection.data.split('|')[1];
                        @if(!$guest)
                        self.joinMeetingAsPro(self.selfUserType);
                        @endif
                    });

                    // self disconnected
                    self.otSession.on('sessionDisconnected', function sessionDisconnected(event) {
                        console.log('You were disconnected from the session.', event.reason);
                    });

                    // initialize the publisher
                    var publisherOptions = {
                       // videoSource: canvas.captureStream(1).getVideoTracks()[0], // TODO: Comment this line to use webcam
                        insertMode: 'append',
                        width: '100%',
                        height: '100%',
                    };
                    var publisher = OT.initPublisher('self-view', publisherOptions, self.handleOpenTokError);

                    publisher.on('streamCreated', function(event) {
                        var selfView = $('#self-view');
                        selfView.attr('data-stream', event.stream.id);
                        selfView.attr('data-from', event.stream.connection.data.split('|')[0]);
                        @if($guest)
                        selfView.attr('data-type', 'CLIENT');
                        @else
                        selfView.attr('data-type', 'PRO');
                        @endif
                    });

                    // Connect to the session
                    self.otSession.connect(token, function callback(error) {
                        if (error) {
                            self.handleOpenTokError(error);
                        } else {
                            // If the connection is successful, publish the publisher to the session
                            self.otSession.publish(publisher, self.handleOpenTokError);
                        }
                    });
                },
                handleOpenTokError: function(e) {

                },

                getClientCheckinToken: function(_done) {
                    var self = this;
                    $.get('/get-client-checkin-token/' + this.clientUid, function(_data) {
                        console.log(_data);
                        self.checkInToken = _data.data;
                        _done();
                    }, 'json');
                },
                getOpenTokSessionId: function(_done) {
                    var self = this;

                    @if($guest)
                    $.ajax({
                        type: 'post',
                        url: '/api/clientVideoVisit/startVideoVisitAsClient',
                        headers: {
                            'sessionKey': localStorage.sessionKey
                        },
                        data: {checkInToken: this.checkInToken},
                        dataType: 'json'
                    })
                    .done(function (_data) {
                        console.log(_data);
                        if(_data.success) {
                            self.otSessionId = _data.data;
                            _done();
                        }
                        else {
                            alert(_data.message);
                        }
                    })
                    .fail(function (_data) {
                        console.log(_data);
                        alert(_data.message);
                    });
                    @else
                    $.get('/pro/get-opentok-session-key/' + self.clientUid, function(_data) {
                        self.otSessionId = _data.data;
                        _done();
                    }, 'json');
                    @endif
                },

                @if(!$guest)
                joinMeetingAsPro: function(_type) {
                    var self = this, endPoint = '';
                    if(_type === 'ASSISTANT') {
                        endPoint = 'joinVideoVisitAsAssistantPro';
                    }
                    else {
                        endPoint = 'joinVideoVisitAsMcpPro';
                    }
                    $.ajax({
                        type: 'post',
                        url: '/api/clientVideoVisit/' + endPoint,
                        headers: {
                            'sessionKey': localStorage.sessionKey
                        },
                        data: {uid: self.clientUid},
                        dataType: 'json'
                    })
                    .done(function (_data) {
                        console.log(_data);
                    })
                    .fail(function (_data) {
                        console.warn(_data);
                        alert(_data.message);
                    });
                },
                @endif

                activateParty: function(_stream = 'self') {
                    var current = $('.full-view');
                    if(current.attr('data-stream') === _stream) return;
                    current.removeClass('full-view').addClass('thumb-view');
                    if(current.attr('data-type') === 'CLIENT') {
                        current.prependTo('.thumbs');
                    }
                    else {
                        current.appendTo('.thumbs');
                    }
                    if(_stream === 'self') {
                        $('#self-view')
                            .removeClass('thumb-view')
                            .removeClass('disconnected-view')
                            .addClass('full-view')
                            .prependTo('.main-view');
                    }
                    else {
                        $('div[data-stream="' + _stream + '"]')
                            .removeClass('thumb-view')
                            .removeClass('disconnected-view')
                            .addClass('full-view')
                            .prependTo('.main-view');
                    }
                }

            },
            mounted: function() {

                var self = this;

                @if($guest)
                this.clientUid = localStorage.clientUid;
                this.getClientCheckinToken(function() { // get client check-in token

                    self.getOpenTokSessionId(function() { // get opentok session id
                        var name = [];
                        if (localStorage.clientFirstName) name.push(localStorage.clientFirstName);
                        if (localStorage.clientLastName) name.push(localStorage.clientLastName);
                        this.selfName = name.join(' ');
                        $.ajax({
                            type: 'post',
                            url: '/api/openTok/getClientToken',
                            headers: {
                                'sessionKey': localStorage.sessionKey
                            },
                            data: {
                                opentokSessionId: self.otSessionId,
                                name: name.join(' ')
                            },
                            dataType: 'json'
                        })
                        .done(function (_data) {
                            console.log(_data);
                            self.selfToken = _data.data;
                            self.initOpenTok();
                        })
                        .fail(function (_data) {
                            console.warn(_data);
                            alert(_data.message);
                        });

                    });
                });
                @else
                    localStorage.sessionKey = '{{ $session->session_key }}';
                @endif

                $(document).on('click', '.thumbs>div[data-stream]', function() {
                    self.activateParty($(this).attr('data-stream'));
                    return false;
                });

                @if(!$guest)

                // poll for new patients and alert
                window.setInterval(function() {
                    self.pollForNextPatient();
                }, 5000);

                @endif

                window.onbeforeunload = function() {
                    if(self.started) {
                        return "A call is in progress";
                    }
                };

            }
        });
    </script>

@endsection
