import { AgoraAppStore, AgoraSdkClient, StreamType } from "any-hooks/types/agora";
import { watch } from "vue";
import { useInjector, useState } from "vue-vulcan";
import { AGORA_APP_SDK } from "../communication/token";

export interface AgoraStreamItem {
  url?: string;
  uid: number; //agora仅支持类型为number的uid
  videoPause?: boolean;
  audioPause?: boolean;
}

/** 基于声网sdk封装，由于多平台特性，请在应用根组件将对应平台的声网SDK对象以及appid通过useProvider提供; */
export function useAgoraClient() {    
  const [streamList, setStream]    = useState<AgoraStreamItem[]>([]);
  const { appid, sdk }             = useInjector<AgoraAppStore>(AGORA_APP_SDK);

  let client : AgoraSdkClient;

  const joinChannelWithAgora = (token: string, cid: string, uid: number) => {
    console.log('准备初始化agora');
    console.log('token', token);
    console.log('cid', cid);
    console.log('uid', uid);
    client = new sdk.Client() as AgoraSdkClient;    
    subscribeRemoteStream();    
    client.init(appid, () => {      
      // client.setRole('audience');
      client.join(
        token, 
        cid, 
        uid, 
        pushVideoStream, 
        err => console.error('加入频道', err)
      );
    }, err => console.error('初始化', err));    
  }

  //推送本地视频流
  const [localPushurl, setPushUrl]  = useState('');
  const pushVideoStream = () => {
    client.publish( url => {setPushUrl(url);console.log('成功生成推流地址'+url)}, console.error);
  }

  //监听远程视频流
  const subscribeRemoteStream = () => {    
    console.log('订阅远端流')
    client.on('stream-added', evt => {    
      console.log('远端流加入')  
      client.subscribe(
        evt.uid, 
        url => {updateStremList('add', {uid: evt.uid, url}); console.log(`用户${evt.uid}加入频道${url}`)},
        console.log
      )
    });
    client.on('update-url', evt => updateStremList('add',  evt));
    client.on('stream-removed', evt => updateStremList('remove',  evt.uid));
    client.on('mute-video', evt => updateStremList('mute-video', evt.uid));
    client.on('unmute-video', evt => updateStremList('unmute-video', evt.uid));
    client.on('error', err => console.log('agora err', err))
  }
  watch(streamList, val => console.log(`远端流变化val`, val));

  // 暂停本地流推送
  const muteLocalStream = (type: StreamType) => {
    return new Promise (resolve => {
      client.muteLocal(type, () => resolve({}))
    })    
  }

  // 恢复本地流推送
  const unmuteLocalStream = (type: StreamType) => {
    return new Promise (resolve => {
      client.unmuteLocal(type, () => resolve({}))
    })
  }

  // 暂停远程流接收
  const muteRemoteStream = (uid: number, type: StreamType) => {
    return new Promise( resolve => {
      client.mute(uid, type, () => resolve({}) )
    })
  }

  // 恢复远程流接收
  const unmuteRemoteStream = (uid: number, type: StreamType) => {
    return new Promise( resolve => {
      client.unmute(uid, type , () => resolve({}))
    })
  }

  // 根据uid来新增或移除远端视频流列表  
  function updateStremList (action: string, input: any) {    
    switch(action) {
      case 'add':
        setStream(streamList.value.concat(input));
      break;
      case 'remove':
        console.log('remove', input)
        const res = streamList.value.filter( item => {
          return !input.includes(item.uid)
        });
        setStream(res);
      break;
      case 'mute-video':
      case 'unmute-video':        
        const arr = streamList.value;
        const index = arr.findIndex( item => item.uid === input );
        arr[index] && (arr[index].videoPause = action === 'mute-video' ? true: false);        
        setStream(arr);
      break;
    }
  }

  // 退出频道
  const leaveChannelWithAgora = () => {        
    client.leave(() => setStream([]));
    setPushUrl(null);
    client = null;
  }  

  return {
    localPushurl,
    streamList,
    joinChannelWithAgora,
    leaveChannelWithAgora,
    muteLocalStream,
    muteRemoteStream,
    unmuteLocalStream,
    unmuteRemoteStream
  }
}

