<template>
    <div class="chat-panel">
        <div class="c-f16 c-fff header">视频聊天
            <win-ctrl-bar @close="leaveRoom" @minimize="minWin" @maximize="maxWin"></win-ctrl-bar>
        </div>
        <div class="main-content clearfix">
            <div class="main-chat fl">
                
            </div>
            <div class="member-panel fl">
                <div class="c-fff c-f14 plr15 pt10">参与人员：</div>
                <ul class="clearfix p-list">
                    <li v-show="chatMembers1.length >0" v-for="member in chatMembers1" :key="member.code || member.id" :class="{'small': chatMembers1.length >=4, 'main': mainVideo == (member.code || member.id)}">
                        <div class="participant" :id="'par_'+(member.code || member.id)" @click="setMainVideo(member.code || member.id)">
                            <video :id="'video_'+ (member.code || member.id )" autoplay="" :poster="getPhoto(member.avatar)"></video>
                            <span class="name c-nowrap">{{member.name}}</span>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
        <div class="action-panel c-t-right plr15">
            <!-- <a class="c-btn btn-blue mr20" @click="addMembers">邀请其他医生</a> -->
            <a class="c-btn btn-red" @click="leaveRoom">结束</a>
        </div>
    </div>
</template>

<style rel="stylesheet/scss" lang="scss" scoped>
    .header{
        height: 40px;
        line-height: 40px;
        padding-left: 20px;
    }
    .chat-panel{
        // height: calc(100% - 41px);
        height: 100%;
        background-color: #1f1f1f;
        overflow: hidden;
    }
    .main-content{
        position: relative;
        height: calc(100% - 85px);
        background-color: #2e2e2e;
    }
    .main-chat{
        width: 70%;
        height: 100%;
    }
    .member-panel{
        width: calc(30% - 5px);
        height: 100%;
        overflow: hidden;
        overflow-y: scroll;
    }
    .action-panel{
        height: 45px;
        line-height: 45px;
        background-color: #1f1f1f;
    }
    .p-list{
        padding: 0 10px;
    }
    .p-list li{
        float: left;
        width: 100%;
        height: 160px;
        margin-top: 20px;
    }
    .p-list li.small{
        width: calc((100% - 20px) / 2);
        height: 75px;
        margin-left: 5px;
        margin-right: 5px;
    }
    .participant{
        position: relative;
        background-color: #fff;
        width: 100%;
        height: 100%;
        margin: 0 auto;
        object-fit: contain;
        // margin-top: 25px;
        // background-color: #2e2e2e;
    }
    .small .participant{
        width: 100%;
        height: 100%;
    }
    .participant img{
        height: 100%;
        width: 100%;
    }
    video{
        width: 100%;
        height: 100%;
    }
    .p-list li.main,
    .p-list li.small.main{
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 70%;
        transition: all 0.3s linear;
        margin: 0;
    }
    .participant span.name{
        position: absolute;
        left: 0;
        bottom: 0;
        color: #fff;
        background-color: #000;
        opacity: .5;
        font-size: 14px;
        padding: 0 8px;
    }
    .c-btn{
        color: #fff;
        height: 26px;
        line-height: 26px;
        font-size: 14px;
        border-radius: 2px;
        padding: 3px 10px;
    }
    .btn-blue{
        background-color: #12b7f5;
    }
    .btn-red{
        background-color: #f96565;
    }
    
</style>
<script>
import _ from 'lodash'
import storage from '../../assets/js/storage'
import adapter from '../../assets/js/webrtc/adapter'
import kurentoUtils from '../../assets/js/webrtc/kurento-utils'
import addMembers from '@/components/videoChat/add-members'
import winCtrlBar from '@/components/common/winCtrlBar'
import common from '../../assets/js/common'
import ajaxUrl from '../../assets/js/ajaxurl'
import imApi from '../../assets/js/apis/api-im'

export default {
    props:{
        'chatMembers': {
            type: Array
        }, 
        'sessionId':{
            type: String,
            default: ''
        },
        'createChat':{
            type: Boolean,
            default: false
        }
    },
    data(){
        return {
            docInfo:{},
            uderId: '',
            userName: '',
            ws: '',
            participants: {},
            mainVideo: '',
            chatMembers1: [],
            modalBoxOffset: {},
            heartCheck: {
              //视频websocket心跳检测器
              timeout: 5000,
              timeoutObj: null,
              serverTimeoutObj: null,
              // reset: function(){
              //   clearTimeout(this.timeoutObj);
              //   clearTimeout(this.serverTimeoutObj);
              //   return this;
              // },
              // start: function(){

              // }
            }
        }
    },
    components:{
        winCtrlBar
    },
    mounted(){
        this.docInfo = storage.getItem(storage.API_LOGIN_DOCTOR);
        this.userId = this.docInfo.uid,
        this.userName = this.docInfo.name;
        this.mainVideo = this.userId;

        this.modalBoxOffset = $(".v--modal-box").offset();

        var vm = this;

        if(!this.chatMembers || this.chatMembers.length == 0){
            this.getMembers();
        }else{
            this.chatMembers1 = this.chatMembers
        }
        
        window.onbeforeunload = function() {
            debugger
            vm.ws.close();
        };
        this.$root.bus.$on('addChatMember', value=>{
            vm.addChatMember(value);
        })
    },
    watch:{
        chatMembers1(){
            var vm = this
            this.ws = new WebSocket('wss://'+ ajaxUrl.videoScoketUrl);
            this.initWS();
            if(this.createChat){
                //发起视频聊天
                this.createNewChat();
            }
            setTimeout(function(){
                vm.register();
            }, 300)
        }
    },
    methods:{
        async getMembers(){
            let rs = await imApi.Sessions.getParticipants(this.sessionId)
            this.chatMembers1 = _.map(rs.data, function(o){
                if(!o.code){
                    o.code = o.id;
                }
                return o;
            })
            // console.log(this.chatMembers1);
        },
        async createNewChat(){
            let list = this.chatMembers1.concat(this.selectArr),
                arr = _.map(list, "name"),
                name = arr.join("、"),
                participants = {};

            // _.each(list, function(o){
            //     participants[o.code] = o;
            // });
            _.map(this.chatMembers1, function(o){
                participants[o.code] = o;
                return o;
            })
            
            //会话的名称，如果长度>10，则用...结尾
            if(name.length > 10){
                name = name.substr(0, 10)+"...";
            }
            let rs = await imApi.Sessions.createGroupSession(this.sessionId, '4', name, participants, 1)
        },
        getPhoto(p){
            if(!p){
                return './images/d-male.png'
            }else{
                return common.setImgUrl(p)
            }
        },
        initWS(){
            var vm = this;
            vm.ws.onopen = function () {
              //心跳检测重置
              vm.heartCheck.reset().start();
            };
            vm.ws.onmessage = function(message) {
                var parsedMessage = JSON.parse(message.data);
                switch (parsedMessage.id) {
                case 'existingParticipants':
                    vm.onExistingParticipants(parsedMessage);
                    break;
                case 'newParticipantArrived':
                    vm.onNewParticipant(parsedMessage);
                    break;
                case 'participantLeft':
                    vm.onParticipantLeft(parsedMessage);
                    break;
                case 'receiveVideoAnswer':
                    vm.receiveVideoResponse(parsedMessage);
                    break;
                case 'iceCandidate':
                    vm.participants[parsedMessage.userId].rtcPeer.addIceCandidate(parsedMessage.candidate, function (error) {
                        if (error) {
                        console.error("Error adding candidate: " + error);
                        return;
                        }
                    });
                    break;
                case 'talk':
                    console.log("talk", parsedMessage)
                    break;
                default:
                    console.error('Unrecognized message', parsedMessage);
                }
                // vm.heartCheck.reset().start();
            }
            vm.heartCheck.reset = function(){
              console.log("reset");
              clearInterval(vm.heartCheck.timeoutObj);
              return vm.heartCheck;
            }
            vm.heartCheck.start = function(){
              var self = vm.heartCheck;
              self.timeoutObj = setInterval(function(){
                //这里发送一个心跳，后端收到后，返回一个心跳消息，
                //onmessage拿到返回的心跳就说明连接正常
                var aa={
                  id : 'heartbeat'
                }
                var bb = JSON.stringify(aa);
                console.log("send heartbeat");
                vm.ws.send(bb);

                // self.serverTimeoutObj = setTimeout(function(){
                //   //如果超过一定时间还没重置，说明后端主动断开了
                //   vm.ws.close();
                // }, self.timeout)

              }, self.timeout)
            }
        },
        register(){
            var message = {
                id : 'joinRoom',
                userId : this.userId,
                roomId : this.sessionId,
            }
            console.log(this.ws.readyState);
            if (this.ws.readyState===1) {
                this.sendMessage(message);
            }
        },
        leaveRoom() {
            debugger
            var vm = this;
            new Promise(function(resolve, reject){
                vm.sendMessage({
                    id : 'leaveRoom'
                });
                resolve();
            }).then(function(){
                for ( var key in vm.participants) {
                    vm.participants[key].dispose();
                }
                vm.ws.close();
                vm.$emit('close');
            })
        },
        sendMessage(message) {
            var jsonMessage = JSON.stringify(message);
            // console.log('Senging message: ' + jsonMessage);
            this.ws.send(jsonMessage);
            console.log(22)
        },
        onNewParticipant(request) {
            debugger
            // console.log("onNewParticipant", request);
            this.receiveVideo(request.userId);
        },
        receiveVideoResponse(result) {
            debugger
            // console.log("receiveVideoResponse", result);
            this.participants[result.userId].rtcPeer.processAnswer (result.sdpAnswer, function (error) {
                if (error) return console.error (error);
            });
        },
        callResponse(message) {
            debugger
            if (message.response != 'accepted') {
                console.info('Call not accepted by peer. Closing call');
                stop();
            } else {
                webRtcPeer.processAnswer(message.sdpAnswer, function (error) {
                    if (error) return console.error (error);
                });
            }
        },
        onExistingParticipants(msg) {
            debugger
            // console.log("onExistingParticipants");
            var constraints = {
                audio : true,
                video : {
                    mandatory : {
                        maxWidth : 320,
                        maxFrameRate : 15,
                        minFrameRate : 15
                    }
                }
            };
            var participant1 = new this.participant(this.userId, this);
            this.participants[this.userId] = participant1;
            var video = participant1.getVideoElement();

            var options = {
                localVideo: video,
                mediaConstraints: constraints,
                onicecandidate: participant1.onIceCandidate.bind(participant1)
            };

            participant1.rtcPeer = new window.kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options,
                function (error) {
                    debugger
                if(error) {
                    return console.error(error);
                }
                this.generateOffer (participant1.offerToReceiveVideo.bind(participant1));
            });

            msg.data.forEach(this.receiveVideo);
        },
        receiveVideo(sender) {
            debugger
            // console.log("receiveVideo");
            // console.log("sender = "+sender);
            var participant1 = new this.participant(sender, this);
            this.participants[sender] = participant1;
            var video = participant1.getVideoElement();

            var options = {
                remoteVideo: video,
                onicecandidate: participant1.onIceCandidate.bind(participant1)
            }
            
            participant1.rtcPeer = new window.kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options,
                    function (error) {
                    if(error) {
                        return console.error(error);
                    }
                    this.generateOffer (participant1.offerToReceiveVideo.bind(participant1));
            });
        },
        onParticipantLeft(request) {
            debugger
            // console.log('onParticipantLeft Participant ' + request.userId + ' left');
            var participant1 = this.participants[request.userId];
            participant1.dispose();
            delete this.participants[request.userId];
        },
        participant(code, vm){
            let container = document.getElementById("par_"+code),
                video = document.getElementById("video_"+code);

            video.autoplay = true;
            video.controls = false;
    
            return {
                rtcPeer: {writable: true},
                getElement() {
                    return container;
                },
                getVideoElement() {
                    return video;
                },
                offerToReceiveVideo(error, offerSdp, wp){
                    debugger
                    if (error) return console.error ("sdp offer error")
                    // console.log('Invoking SDP offer callback function');
                    var msg =  { id : "receiveVideoFrom",
                            sender : code,
                            sdpOffer : offerSdp
                        };
                    vm.sendMessage(msg);
                },
                onIceCandidate(candidate, wp) {
                    debugger
                    // console.log("Local candidate" + JSON.stringify(candidate));
            
                    var message = {
                        id: 'onIceCandidate',
                        candidate: candidate,
                        userId: code
                    };
                    vm.sendMessage(message);
                },
                dispose () {
                    debugger
                    // console.log('Disposing participant ' + this.codes);
                    this.rtcPeer.dispose();
                    // container.parentNode.removeChild(container);
                }
            }
        },
        setMainVideo(code){
            this.mainVideo = code;
        },
        addMembers(){
            // this.$layer.iframe({
            //     content: {
            //         content: addMembers, //传递的组件对象
            //         parent: this,//当前的vue对象
            //         data:{}//props
            //     },
            //     area:['500px','400px'],
            //     title: '邀请加入视频通话'
            // });
            // console.log("chatMembers1 = ", this.chatMembers1);
            this.$modal.show(addMembers, {
                chatMembers: this.chatMembers1
            }, {
                draggable: true, 
                width: '500px',
                height: '400px',
                clickToClose: false,
                // reset: true
            })

        },
        addChatMember(value){
            var list = _.values(value),
                len = list.length;
            for(let i=0; i<len; i++){
                this.$set(this.chatMembers1, this.chatMembers1.length, list[i])
            }
        },
        // closeWin(){
        //     this.sendMessage({
        //         id : 'leaveRoom'
        //     });
        //     this.ws.close();
        //     this.$emit('close');
        // },
        minWin(){

        },
        maxWin(isMax){
            if(isMax){
                $(".v--modal-box").css({
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: 'calc(100vh)'
                });
            }else{
                $(".v--modal-box").css({
                    top: this.modalBoxOffset.top,
                    left: this.modalBoxOffset.left,
                    width: '800px',
                    height: '500px'
                });
            }
        }
    }
}
</script>
