import AgoraRTC, {IAgoraRTCClient, IMicrophoneAudioTrack, IRemoteAudioTrack} from "agora-rtc-sdk-ng"

import config from './config';

import Notice from '$utils/class/notice';

import {AgoraStatus,AgoraEvent} from './const';

export {AgoraStatus,AgoraEvent};

export default class Agora extends Notice{

    // 设置当前客户端
    private client:IAgoraRTCClient= undefined;

    // 默认收集的声音
    public volume:number = 100;

    private microphoneTrack:IMicrophoneAudioTrack;

    private remoteAudioTrack:IRemoteAudioTrack;

    // 创建客户端语音对象
    constructor(channel:string,uid:string | null) {
        super();

        this.userPublishedWatch = this.userPublishedWatch.bind(this);

        this.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

        this.client.join(config.appId,channel,config.token,uid).then(()=>{
            // 设置成功加入频道
            this.setStatus(AgoraStatus.join);
            // 订阅他们聊天
            this.addUserPublished();
            // 触发初始化成功
            this.triggerListener(AgoraEvent.initialization);
        }).catch(()=>{
            // 设置成功加入频道失败
            this.setStatus(AgoraStatus.joinFail);
            // 触发初始化失败
            this.triggerListener(AgoraEvent.fail);
        });

    }

    async userPublishedWatch(user, mediaType){
        // 开始订阅远端用户。
        await this.client.subscribe(user, mediaType);
        // 表示本次订阅的是音频。
        if (mediaType === "audio") {
            // 订阅完成后，从 `user` 中获取远端音频轨道对象。
            this.remoteAudioTrack = user.audioTrack;
            // 播放音频因为不会有画面，不需要提供 DOM 元素的信息。
            this.remoteAudioTrack.play();
        }
    }

    // 订阅他人聊天
    addUserPublished(){
        // 仅成功加入后才可以加入订阅
        if (this.status === AgoraStatus.join) {
            this.setStatus(AgoraStatus.listener);
            this.client.on("user-published", this.userPublishedWatch);
        }
    }

    // 加入订阅
    joinPublished() {
        return new Promise<void>( async (resolve, reject)=>{
            if (this.status === AgoraStatus.listener || this.status === AgoraStatus.publishedFail || this.status === AgoraStatus.microphoneFail) {

                // 设置当前状态为加入订阅中
                this.setStatus(AgoraStatus.joinPublished);

                try {
                    this.microphoneTrack = await AgoraRTC.createMicrophoneAudioTrack();

                    // 移除所有监听
                    this.client.unpublish();
                    // 发布订阅
                    this.client.publish([this.microphoneTrack]).then(()=>{
                        this.setStatus(AgoraStatus.published);
                        resolve();
                    }).catch(()=>{

                        this.setStatus(AgoraStatus.publishedFail);
                        reject();
                    });
                } catch (e) {

                    // 如果等于权限被拒绝触发
                    if (e.code === 'PERMISSION_DENIED') {
                        this.setStatus(AgoraStatus.microphoneFail);
                    }

                    reject();
                }

            } else {
                reject();
            }
        });

    }

    // 移除订阅
    unPublish(){
        if (this.status === AgoraStatus.joinPublished || this.status ===  AgoraStatus.published) {
            // 设置为听取别人聊天
            this.setStatus(AgoraStatus.listener);
            // 移除订阅
            this.client.unpublish();
        }
    }

    // 设置远端采集
    setVolume(value){
       if (this.volume !== value) {
           this.volume = value;
           this.remoteAudioTrack && this.remoteAudioTrack.setVolume(value);
       }
    }

    // 设置当前所处于的状态
    public status:AgoraStatus = AgoraStatus.none;
    // 设置当前状态
    setStatus(status:AgoraStatus){
        if (this.status !== status) {
            this.status = status;
            // 触发status 发生变化
            this.triggerListener(AgoraEvent.status,status);
        }
    }

    // 销毁
    destroy() {
        super.destroy();
        // 执行离开频道
        this.client.leave();
        // 解除绑定事件
        this.client.off("user-published",this.userPublishedWatch);
        // 移除
        this.client = null;
    }


}
