package com.ydl.audioim

import android.Manifest
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Paint
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.media.MediaPlayer
import android.net.Uri
import android.os.Handler
import android.os.PowerManager
import android.os.Vibrator
import android.provider.Settings
import android.support.v4.content.ContextCompat
import android.text.TextUtils
import android.view.View
import android.view.animation.AccelerateInterpolator
import com.alibaba.android.arouter.facade.annotation.Route
import com.google.gson.Gson
import com.tbruyelle.rxpermissions2.RxPermissions
import com.ydl.ydl_av.messge_service.ChannelManager
import com.ydl.ydl_av.messge_service.YDLRTMClient
import com.ydl.ydl_av.messge_service.bean.RTMMesssage
import com.ydl.ydl_av.messge_service.callback.CallListener
import com.ydl.ydl_av.messge_service.callback.ChannelListener
import com.ydl.ydl_av.messge_service.response.CallLocalResponse
import com.ydl.ydl_av.messge_service.response.CallRemoteResponse
import com.ydl.ydl_av.messge_service.response.ChannelMember
import com.ydl.ydl_av.voice.listener.IYDLVoiceEventHandler
import com.ydl.ydl_av.voice.manager.YDLVoiceManager
import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydl_image.manager.YDLImageCacheManager
import com.ydl.ydl_av.chat.bean.AudioMessageBean
import com.ydl.audioim.contract.IAudioHomeActivityContract
import com.ydl.audioim.http.command.ConnectCommand
import com.ydl.audioim.http.command.ConnectFinishCommand
import com.ydl.audioim.http.command.ConnectStartCommand
import com.ydl.audioim.http.command.NoticePushCommand
import com.ydl.audioim.player.AudioPlayer
import com.ydl.audioim.presenter.AudioHomePresenterImpl
import com.ydl.audioim.utils.DateUtils
import com.ydl.audioim.widget.AxbConfirmDialog
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.webview.RefreshWebEvent
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.base.BaseMvpActivity
import com.ydl.ydlcommon.mvp.lce.BaseLceActivity
import com.ydl.ydlcommon.router.YdlCommonRouterManager
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import de.greenrobot.event.EventBus
import io.agora.rtc.IRtcEngineEventHandler
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.audioim_activity_audio_home.*
import java.util.concurrent.TimeUnit


/**
 * @author jiucheng
 * @描述: 声网通话页面
 * @Copyright Copyright (c) 2018
 * @Company 壹点灵
 * @date 2018/10/30
 */
@Route(path = "/av/AudioHomeActivity")
class AudioHomeActivity : BaseMvpActivity<IAudioHomeActivityContract.View, IAudioHomeActivityContract.Presenter>(),IAudioHomeActivityContract.View, SensorEventListener {

    /**
     * 专家头像地址
     */
    private var expertHeadUrl: String? = null
    /**
     * 专家姓名
     */
    private var expertName: String? = null
    /**
     * 专家文案
     */
    private var expertTips: String? = null
    /**
     * 声网点对点聊天房间id
     */
    private var channelId: String? = null
    /**
     * 通话开始时间（接通）
     */
    private var callStartTime:Long? = null
    /**
     * 倾诉剩余时长（时长单位s，eg：剩余2min15s，返回135）
     */
    private var remainTime: String? = null
    /**
     *聆听者id（不是聆听者的uid）
     */
    private var listenId: String? = null
    /**
     * token
     */
    private var token: String? = null
    /**
     * commentUrl 评价页URL
     */
    private var commentUrl: String? = null
    /**
     * callId
     */
    private var callId: String? = null
    /**
     * relation_id
     */
    private var relationId: String? = null
    /**
     * listenerUid专家uid
     */
    private var listenerUid: String? = null
    /**
     * 倾述总时长
     */
    private var totalDuration: Int? = 0
    /**
     * 本地记录的当前剩余时间
     */
    private var localRemainTime: Int? = 0
    /**
     * 60s自动挂断倒计时
     */
    private var waitDisposable: Disposable? = null
    /**
     * 45s倒计时
     */
    private var disposable: Disposable? = null
    /**
     * 本次倾述倒计时
     */
    private var totalDisposable: Disposable? = null
    /**
     * 是否连接成功
     */
    private var isConnectSuccess: Boolean = false
    //电源管理对象
    private var localPowerManager: PowerManager? = null
    //电源锁
    private var localWakeLock: PowerManager.WakeLock? = null
    private var sensorManager: SensorManager? = null
    private var axbPhone: String? = null
    //是否跳转到拨号页面
    private var isJumpDail: Boolean = false
    private var mPlayer: AudioPlayer? = null
    private var vibrator: Vibrator? = null
    private var handler: Handler? = null
    //声网
    private var voiceManage: YDLVoiceManager? = null

    //频道管理器
    private var channelManager : ChannelManager? = null

    /**
     * 声网事件回调 （SDK 通过指定的事件通知应用程序 SDK 的运行事件，如: 加入或离开频道，新用户加入频道等）
     */
    private val mRtcEventHandler = object : IYDLVoiceEventHandler() {

        override fun onUserMuteAudio(uid: Int, muted: Boolean) {
        }

        override fun onWarning(warn: Int) {
            super.onWarning(warn)
            //103：没有可用的频道资源。可能是因为服务端没法分配频道资源
            //104：查找频道超时。在加入频道时 SDK 先要查找指定的频道，出现该警告一般是因为网络太差，连接不到服务器
            //105：查找频道请求被服务器拒绝。服务器可能没有办法处理这个请求或请求是非法的
            //106：打开频道超时。查找到指定频道后，SDK 接着打开该频道，超时一般是因为网络太差，连接不到服务器
            //107：打开频道请求被服务器拒绝。服务器可能没有办法处理该请求或该请求是非法的
            LogUtil.e("[agora]发生警告回调$warn")
            runOnUiThread {
                when (warn) {
                    103, 104, 105, 106, 107 -> {
                        showToast("当前网络较差，请更换网络!")
                        leaveChannel()
                    }
                }
            }
        }

        override fun onError(err: Int) {
            super.onError(err)
            //3：SDK 初始化失败。Agora 建议尝试以下处理方法
            //7：SDK 尚未初始化，就调用其 API。请确认在调用 API 之前已创建 RtcEngine 对象并完成初始化
            //10：API 调用超时。有些 API 调用需要 SDK 返回结果，如果 SDK 处理时间过长，超过 10 秒没有返回，会出现此错误
            //17：加入频道被拒绝。一般有以下原因：
            //用户已进入频道，再次调用加入频道的 API，例如 joinChannel，会返回此错误。停止调用该方法即可。
            //用户在做 Echo 测试时尝试加入频道。等待 Echo test 结束后再加入频道即可。
            //101：不是有效的 APP ID。请更换有效的 APP ID 重新加入频道
            //102：不是有效的 频道名。请更换有效的频道名重新加入频道
            //109：当前使用的 Token 过期，不再有效
            //110：生成的 Token 无效
            //123：此用户被服务器禁止
            LogUtil.e("[agora]发生错误回调$err")
            runOnUiThread {
                when (err) {
                    3, 7, 109, 110 -> {
                        showToast("请退出应用，重新打开")
                        leaveChannel()
                    }
                    10, 17 -> {
                        showToast("当前网络较差，请更换网络")
                        leaveChannel()
                    }
                    101 -> {
                        showToast("安装包有问题，请联系技术")
                        leaveChannel()
                    }
                    102 -> {
                        showToast("频道错误，请联系技术")
                        leaveChannel()
                    }
                    123 -> {
                        showToast("当前用户不允许接听电话，请联系客服")
                        leaveChannel()
                    }
                    else -> {
                        //异常关闭
                        leaveChannel()
                    }
                }
            }
        }

        override fun onApiCallExecuted(error: Int, api: String?, result: String?) {
            super.onApiCallExecuted(error, api, result)
            LogUtil.e("[agora]$api 已执行回调 $result")
        }


        override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) {
            super.onJoinChannelSuccess(channel, uid, elapsed)
            LogUtil.e("[agora]$uid 用户声网加入频道成功:channel=$channel")
            //更新ui
            onJoinChannelSuccess()
        }

        override fun onLeaveChannel(stats: IRtcEngineEventHandler.RtcStats?) {
            super.onLeaveChannel(stats)
            LogUtil.e("[agora]离开频道回调")
        }

        override fun onLastmileQuality(quality: Int) {
            super.onLastmileQuality(quality)
            LogUtil.e("[agora]网络质量报告回调${quality}")
        }

        override fun onConnectionInterrupted() {
            super.onConnectionInterrupted()
            LogUtil.e("[agora]连接中断回调")
        }

        override fun onUserJoined(uid: Int, elapsed: Int) {
            super.onUserJoined(uid, elapsed)
            LogUtil.e("[agora]远端用户/主播加入频道回调")
            runOnUiThread {
                //另一方加入频道成功
                connectSuccess()
            }

        }

        override fun onUserOffline(uid: Int, elapsed: Int) {
            super.onUserOffline(uid, elapsed)
            LogUtil.e("[agora]远端用户$uid 离开频道回调")
            showToast("专家已挂断")

            if (totalDisposable != null) {
                totalDisposable!!.dispose()
            }
            handler!!.postDelayed({
                //另一方离开频道
                updateExpertStatus(false, 1)
            }, 500)
        }
    }
    //

    override fun createPresenter(): IAudioHomeActivityContract.Presenter {
        return AudioHomePresenterImpl()
    }

    override fun layoutResId(): Int {
        return R.layout.audioim_activity_audio_home
    }

    override fun initDataAndEvent() {
        //状态栏颜色
        setWindowStatusBarColor()
        //初始化传感器
        initSensorManager()
        //页面传递数据初始化
        initIntentData()
        //view初始化
        initView()
        //设置信令的回调
        setCallBack()
        //点击事件
        setClickEvent()
        //权限申请
        requestPermission()
    }

    private fun setWindowStatusBarColor() {
        StatusBarUtils.setWindowStatusBarColor(this, R.color.audioim_color_40353535)
    }

    @SuppressLint("InvalidWakeLockTag")
    private fun initSensorManager() {
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager?

        localPowerManager = getSystemService(POWER_SERVICE) as PowerManager?
        localWakeLock = localPowerManager!!.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "yidianling")
    }

    private fun initIntentData() {
        expertHeadUrl = intent.getStringExtra(IntentConstants.INTENT_EXPERT_HEAD_URL)
        expertName = intent.getStringExtra(IntentConstants.INTENT_EXPERT_NAME)
        expertTips = intent.getStringExtra(IntentConstants.INTENT_EXPERT_TIPS)
        totalDuration = intent.getStringExtra(IntentConstants.INTENT_TOTAL_DURATION).toInt()
        channelId = intent.getStringExtra(IntentConstants.INTENT_ROOM_ID)
        remainTime = intent.getStringExtra(IntentConstants.INTENT_REMAIN_TIME)
        callId = intent.getStringExtra(IntentConstants.INTENT_CALL_ID)
        relationId = intent.getStringExtra(IntentConstants.INTENT_RELATION_ID)
        token = intent.getStringExtra(IntentConstants.INTENT_TOKEN)
        listenerUid = intent.getStringExtra(IntentConstants.INTENT_LISTENER_UID)
        listenId = intent.getStringExtra(IntentConstants.INTENT_LISTEN_ID)
        commentUrl = intent.getStringExtra(IntentConstants.INTENT_COMMENT_URL)

        localRemainTime = remainTime?.toInt()
        handler = Handler()
        vibrator = getSystemService(Service.VIBRATOR_SERVICE) as Vibrator?
    }

    private fun initView() {
        tv_change_route.isEnabled = false
        //水波纹view初始化
        wave_view.setDuration(6000)
        wave_view.setStyle(Paint.Style.STROKE)
        wave_view.setSpeed(1000)
        wave_view.setColor(Color.WHITE)
        wave_view.setInitialRadius(140f)
        wave_view.setInterpolator(AccelerateInterpolator(1.2f))
        //挂断按钮默认不可点击
        iv_hang_up.isEnabled = false
        //设置默认关闭扬声器
        iv_hands_free.isSelected = false

        tv_name.text = expertName
        tv_tips.text = expertTips

        tv_remain_time.text = DateUtils.formatTime(remainTime)

        if (!TextUtils.isEmpty(expertHeadUrl)) {
            var option = SimpleImageOpConfiger()
            option.errorPic = R.drawable.audioim_head_place_hold_pic
            option.loadingPic = R.drawable.audioim_head_place_hold_pic
            option.transform = 0
            YDLImageCacheManager.showImage(this, expertHeadUrl, iv_head, option)
        }
    }

    private fun setClickEvent() {
        //切换线路
        tv_change_route.setOnClickListener { showChooseDialog() }
        //挂断
        iv_hang_up.setOnClickListener {
            if (isConnectSuccess) {
                updateExpertStatus(false, 1)
            } else {
                userCloseCalling()
            }
        }
        //免提
        iv_hands_free.setOnClickListener {
            if (iv_hands_free.isSelected) {
                iv_hands_free.isSelected = false
                iv_hands_free.setImageResource(R.drawable.audioim_img_hands_free_unuse)
            } else {
                iv_hands_free.isSelected = true
                iv_hands_free.setImageResource(R.drawable.audioim_img_hands_free)
            }

            //已经接通
            if (isConnectSuccess) {
                //是否开启外放
                voiceManage!!.getVoiceApi().setEnableSpeakerphone(iv_hands_free.isSelected)
            } else {
                //未接通
                if (mPlayer != null) {
                    mPlayer!!.switchPlayType(iv_hands_free.isSelected)
                }
            }
        }
    }

    private fun setCallBack() {

        YDLRTMClient.instances.setCallListener(object :CallListener{
            override fun onCallRecivedByPeer(response: CallLocalResponse?) {
                //返回给主叫：被叫已收到呼叫邀请
                LogUtil.i("[agora]${response?.calleeId}已收到呼叫邀请，频道号${response?.ChannelId}")
            }

            override fun onCallAccepted(response: CallLocalResponse?) {
                //返回给主叫
                LogUtil.i("[agora]${response?.calleeId}已接收呼叫邀请")
            }

            override fun onCallRefused(response: CallLocalResponse?) {
                //返回给主叫
                LogUtil.i("[agora]${response?.calleeId}已拒绝呼叫邀请")
                ToastUtil.toastShort("对方已拒绝")
                leaveChannel()
            }

            override fun onCallCanceled(response: CallLocalResponse?) {
                //返回给主叫
                LogUtil.i("[agora]主叫已取消呼叫邀请")
            }

            override fun onCallFailure(response: CallLocalResponse?) {
                //返回给主叫
                LogUtil.i("[agora]呼叫${response?.calleeId}用户失败：${response?.response}")
            }

            override fun onRemoteInvitationReceived(response: CallRemoteResponse?) {
                //返回给被叫
                LogUtil.i("[agora]收到来自${response?.callerId}的呼叫邀请")
            }

            override fun onRemoteInvitationAccepted(response: CallRemoteResponse?) {
                //返回给被叫
                LogUtil.i("[agora]接受来自${response?.callerId}的呼叫成功")
            }

            override fun onRemoteInvitationRefused(response: CallRemoteResponse?) {
                //返回给被叫
                LogUtil.i("[agora]已拒绝来自${response?.callerId}的呼叫")
            }

            override fun onRemoteInvitationCanceled(response: CallRemoteResponse?) {
                //返回给被叫
                LogUtil.i("[agora]主叫${response?.callerId}已取消呼叫邀请")
            }

            override fun onRemoteInvitationFailure(response: CallRemoteResponse?) {
                //返回给被叫
                LogUtil.i("[agora]来自主叫${response?.callerId}的呼叫邀请进程失败:${response?.response}")
            }

            override fun onOtherMsg(error: String?) {
                LogUtil.i("[agora]其它消息：${error}")
            }
        })
        channelManager = YDLRTMClient.instances.createChannelManager(channelId,object :ChannelListener{
            override fun onMemberCountUpdated(memberCount: Int) {
                //频道人数更新
                LogUtil.i("[agora]当前频道人数：$memberCount")
            }

            override fun onMessageReceived(message: RTMMesssage?, member: ChannelMember?) {
                //接到频道消息
                LogUtil.i("[agora]接到${member?.channelId}频道${member?.userId}的消息："+message?.text)
            }

            override fun onMemberJoined(member: ChannelMember?) {
                //新用户加入频道
                LogUtil.i("[agora]新用户加入${member?.channelId}频道：${member?.userId}")
            }

            override fun onMemberLeft(member: ChannelMember?) {
                LogUtil.i("[agora]有用户离开${member?.channelId}频道：${member?.userId}")
            }
        })
    }

    /**
     * 请求权限
     */
    @SuppressLint("CheckResult")
    private fun requestPermission() {
        val rxPermissions = RxPermissions(this)
        rxPermissions.requestEach(Manifest.permission.RECORD_AUDIO)
                .subscribe { permission ->
                    if (permission.granted) {
                        init()
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        requestPermission()
                    } else {
                        ToastUtil.toastLong(this, getString(R.string.audioim_need_storage_permission_hint))
                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        val uri = Uri.fromParts("package", packageName, null)
                        intent.data = uri
                        startActivity(intent)
                        finish()
                    }
                }
    }

    @SuppressLint("CheckResult")
    private fun init() {
        wave_view.start()
        //初始化声网
        initializeAgoraEngine()
        //发起呼叫
        var msgBean = AudioMessageBean(
                1,
                channelId!!,
                YdlCommonRouterManager.getYdlCommonRoute().getUid().toString(),
                YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()!!.headUrl,
                YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()!!.userName,
                remainTime!!.toInt(),
                relationId,
                callId,
                null,
                channelId
        )
        YDLRTMClient.instances.call(listenerUid!!,channelId,Gson().toJson(msgBean))
        //开始25s等待倒计时
        Observable.interval(0, 100, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.computation())
                .take(253)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    progress_view.setProgress(it.toFloat() / 2.5f)
                }, {
                    LogUtil.d(it.message)
                }, {
                    waittingStatus()
                    if (!isConnectSuccess){
                        iv_hang_up.setImageResource(R.mipmap.ico_close)
                        //关闭音乐
                        stopPlaying()
                        //提示切换传统线路
                        //发送消息通知专家用户已挂断
                        YDLRTMClient.instances.cancelCall(listenerUid,channelId)
                        showChooseDialog()
                    }
                })
        //加入频道
        joinChannel()
        //双重保险：加入频道成功，通过服务端发推送给专家
        noticeServerPush(true)
    }

    /**
     * 声网初始化
     */
    private fun initializeAgoraEngine() {
        /**
         * 创建一个实例
         * param appId            应用id
         * param mRtcEventHandler 事件回调（SDK 通过指定的事件通知应用程序 SDK 的运行事件，如: 加入或离开频道，新用户加入频道等）
         */
        voiceManage = YDLVoiceManager(this, BuildConfig.AGORA_APPID, mRtcEventHandler)
        voiceManage!!.init()
        voiceManage!!.getVoiceApi().enableLastmileTest()
        //默认听筒模式
        voiceManage!!.getVoiceApi().setEnableSpeakerphone(false)
    }

    /**
     * 声网加入频道
     */
    private fun joinChannel() {
        voiceManage!!.getVoiceApi().joinChannel(token!!, channelId!!, "Extra Optional Data", YdlCommonRouterManager.getYdlCommonRoute().getUid())
    }

    /**
     * 用户主动挂断（包括：60s专家未接听自动挂断）
     * 注意：这个方法只在专家还未接听的状态才能调用
     *
     */
    private fun userCloseCalling() {
        //发送消息通知专家用户已挂断
        YDLRTMClient.instances.cancelCall(listenerUid,channelId)
        handler!!.postDelayed({
            leaveChannel()
        }, 100)
    }

    /**
     * 更新专家状态
     *@param isSwitchAxb 是否切换axb
     * @param finishStatus 状态值：     0：开始         1：结束
     */
    private fun updateExpertStatus(isSwitchAxb: Boolean, finishStatus: Int) {
        if (isSwitchAxb){
            dialPhone()
        }

        if(finishStatus==1){
            var param = ConnectFinishCommand(listenerUid!!, relationId!!, "0",
                    remainTime!!.toInt() - localRemainTime!!, callId!!,
                    "0","0","$callStartTime",
                    "${System.currentTimeMillis()}",3)
            mPresenter.connectFinish(param)
        }else{
            //接通开始回调
            callStartTime = System.currentTimeMillis()
            var param = ConnectStartCommand(listenerUid!!, relationId!!,  callId!!,
                    "${System.currentTimeMillis()}","3","0","0","0","0")
            mPresenter.connectStart(param)
        }
    }

    /**
     * 线路选择弹窗
     */
    private fun showChooseDialog() {

        val dialog = AxbConfirmDialog(mContext, object : AxbConfirmDialog.OnClickEnsureListener {
            override fun onClickEnsure() {
                switchAXB()
            }
        })
        dialog.show()
    }

    /**
     * 切换成axb路线请求
     */
    private fun switchAXB() {
        mPresenter.getAXBPhone(ConnectCommand(listenId!!,"1"))
    }

    /**
     * 切换axb网络请求结果:axb电话
     *w
     */
    override fun switchAXBResponse(axbPhone: String) {
        this.axbPhone = axbPhone
        isJumpDail = true
        if (isConnectSuccess) {
            //已经连接成功，切换axb时需要更新专家状态
            updateExpertStatus(true, 1)
        } else {
            //未连接成功，切换axb时：需发送消息通知专家端用户已挂断
            //发送消息通知专家用户已挂断
            YDLRTMClient.instances.cancelCall(listenerUid,channelId)
            leaveChannel()
        }
    }


    /**
     * 跳转拨号界面
     */
    override fun dialPhone() {
        var phoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$axbPhone"))
        startActivity(phoneIntent)
    }


    /**
     * 30s等待完成，专家未接听
     */
    private fun waittingStatus() {
        //挂断按钮可点击
        iv_hang_up.isEnabled = true
        iv_hang_up.setImageResource(R.drawable.audioim_img_hang_up)
        if (!isConnectSuccess) {
            //页面等待文案调整
            tv_waiting.visibility = View.GONE
            tv_change_doctor.text = "对方暂无应答，正在为您切换线路重播"
            tv_change_doctor.visibility = View.VISIBLE
        }
        //切换线路按钮可见
        tv_change_route.isEnabled = true
        tv_change_route.setTextColor(ContextCompat.getColor(this, R.color.white))
        tv_change_route.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(this, R.drawable.audioim_img_choose_arrow), null)
    }

    /**
     * 加入语音聊天频道成功
     */
    private fun onJoinChannelSuccess() {
        dismissProgressView()

        playWaitingMusic()

        //45s倒计时逻辑
//        disposable = Observable.interval(0, 1, TimeUnit.SECONDS)
//                .subscribeOn(Schedulers.computation())
//                .take(45)
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe({
//                }, {
//                    LogUtil.d(it.message)
//                }, {
//                    if (!isConnectSuccess) {
//                        tv_change_doctor.visibility = View.VISIBLE
//                    }
//                })

        //60超时倒计时逻辑
//        waitDisposable = Observable.interval(0, 1, TimeUnit.SECONDS)
//                .subscribeOn(Schedulers.computation())
//                .take(60)
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe({
//                }, {
//                    LogUtil.d(it.message)
//                }, {
//                    if (!isConnectSuccess) {
//                        ActivityManager.getInstance().finishActivity(NewH5Activity::class.java!!)
//                        showToast("专家未接听")
//                        userCloseCalling()
//                    }
//                })
    }

    /**
     * 播放等待音频
     */
    private fun playWaitingMusic() {
        if (mPlayer == null) {
            mPlayer = AudioPlayer(this)
        }
        if ((Math.random() * 10 + 1).toInt() >= 5) {
            mPlayer!!.setTwoDataAndStart(R.raw.audioim_audio_music_1, R.raw.audioim_loop_music)
        } else {
            mPlayer!!.setTwoDataAndStart(R.raw.audioim_audio_music_2, R.raw.audioim_loop_music)
        }
    }

    /**
     * 播放结束音频，音频播放结束后，自动关闭页面
     */
    private fun playFinishMusic() {
        if (mPlayer == null) {
            mPlayer = AudioPlayer(this)
        }
        mPlayer!!.setDataSource(R.raw.audioim_hand_down_music)
        mPlayer!!.switchPlayType(iv_hands_free.isSelected)
        mPlayer!!.setCompletionListener(MediaPlayer.OnCompletionListener {
            //通话剩余时间不足60s时，默认
            if (localRemainTime!! < 60 && !TextUtils.isEmpty(commentUrl)) {
                val h5Params = H5Params(commentUrl!!, "评价")
                NewH5Activity.start(this@AudioHomeActivity, h5Params)
            }
            if (isJumpDail) {
                //跳转拨号界面
                dialPhone()
            }
            finish()
        })
        mPlayer!!.start(false, true)
    }

    /**
     * 停止播放
     */
    private fun stopPlaying() {
        if (mPlayer != null) {
            mPlayer!!.pause()
        }
    }

    /**
     * sdk通话链接成功
     */
    private fun connectSuccess() {
        isConnectSuccess = true

        //通知服务端，此次通话已经接通，服务端开始订单
        updateExpertStatus(false, 0)

        if (waitDisposable != null) {
            waitDisposable!!.dispose()
        }
        if (disposable != null) {
            disposable!!.dispose()
        }

        stopPlaying()
        vibrator!!.vibrate(1000)

        //等待状态的相关ui隐藏(挂断按钮的倒计时不清除，挂断按钮必须在30s后才能点击)
        tv_change_doctor.visibility = View.GONE
        tv_waiting.visibility = View.GONE
        //显示通话相关ui
        rl_remain_time.visibility = View.VISIBLE

        showToast("已接通")

        tv_tips.visibility = View.GONE

        //剩余倾诉时长倒计时
        totalDisposable = Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.computation())
                .take(remainTime!!.toLong() + 1)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    localRemainTime = remainTime!!.toInt() - it.toInt()
                    if (localRemainTime == 180) {
                        playNoticeMusic(3)
                    }
                    if (localRemainTime == 60) {
                        playNoticeMusic(1)
                    }
                    if (localRemainTime!! <= 60) {
                        if (tv_change_route.isEnabled) {
                            tv_change_route.isEnabled = false
                            tv_change_route.setTextColor(ContextCompat.getColor(this, R.color.audioim_color_50ffffff))
                            tv_change_route.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(this, R.drawable.audioim_img_choose_arrow_unuse), null)
                        }
                    }
                    tv_remain_time.text = DateUtils.formatTime(localRemainTime.toString())
                }, {
                    LogUtil.d(it.message)
                }, {
                    //注意：自动挂断时，如果对方离开频道的回调已经触发，就不要再重复调用接口
                    showToast("通话已结束")
                    updateExpertStatus(false, 1)
                })
    }

    /**
     * 剩余3min和1min时提示音
     * @param min 1 ：还剩1min   3：还剩3min
     *
     */
    private fun playNoticeMusic(min: Int) {
        if (mPlayer == null) {
            mPlayer = AudioPlayer(this)
        }
        if (3 == min) {
            mPlayer!!.setDataSource(R.raw.audioim_last_3_min)
        } else {
            mPlayer!!.setDataSource(R.raw.audioim_last_1_min)
        }
        mPlayer!!.switchPlayType(iv_hands_free.isSelected)
        mPlayer!!.start(false, false)
    }

    /**
     * 用户加入频道后
     *通知服务端发送推送
     * 通知专家加入频道
     * 这个功能已经有用信令通知，为了解决专家信令掉线的问题，增加推送逻辑
     *
     * @param isCall true 拨打   false 取消拨打
     */
    private fun noticeServerPush(isCall: Boolean) {
        var msgBean = AudioMessageBean(
                1,
                channelId!!,
                YdlCommonRouterManager.getYdlCommonRoute().getUid().toString(),
                YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()!!.headUrl,
                YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()!!.userName,
                remainTime!!.toInt(),
                relationId,
                callId,
                null,
                channelId
        )
        var cmd = NoticePushCommand()
        cmd.data = Gson().toJson(msgBean)
        cmd.pushId = listenerUid
        if (isCall) {
            cmd.status = "CALL"
        } else {
            cmd.status = "CALL_OFF"
        }
        mPresenter.noticeServerPush(cmd)
    }


    /**
     * 声网离开频道
     */
    private fun leaveChannel() {
        //刷新h5页面
        EventBus.getDefault().post(RefreshWebEvent(false))
        stopPlaying()
        //播放结束音频
        playFinishMusic()
    }

    override fun onResume() {
        super.onResume()
        sensorManager!!.registerListener(this, sensorManager!!.getDefaultSensor(Sensor.TYPE_PROXIMITY), SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {

    }

    override fun onSensorChanged(event: SensorEvent?) {
        val values = event!!.values
        when (event.sensor.type) {
            Sensor.TYPE_PROXIMITY -> {
                if (values[0] == 0.0f) {
                    //贴近手机
                    if (!localWakeLock!!.isHeld) {
                        localWakeLock!!.acquire()
                    }
                } else {
                    //离开手机
                    //唤醒设备
                    if (localWakeLock!!.isHeld) {
                        localWakeLock!!.release()
                    }
                }
            }
        }
    }


    /**
     * 显示自定义弹窗
     */
    private fun showToast(msg: String?) {
        runOnUiThread {
            //  tv_toast.visibility = View.VISIBLE
////            tv_toast.text = msg
////            tv_toast.postDelayed({
////                tv_toast.visibility = View.GONE
////            }, 1000)
            ToastUtil.toastShort(msg)
        }
    }

    override fun showProgressView() {
        try {
            showProgressDialog()
        }catch (e : Exception){
            e.printStackTrace()
        }

    }

    override fun dismissProgressView() {
        try {
            dismissProgressDialog()
        }catch (e:Exception){
            e.printStackTrace()
        }

    }

    override fun finishActivity() {
        leaveChannel()
    }

    override fun onDestroy() {
        super.onDestroy()
        if (handler != null) {
            handler = null
        }

        if (waitDisposable != null) {
            waitDisposable!!.dispose()
        }
        if (disposable != null) {
            disposable!!.dispose()
        }
        if (totalDisposable != null) {
            totalDisposable!!.dispose()
        }
        if (sensorManager != null) {
            sensorManager!!.unregisterListener(this)
        }
        //唤醒设备
        if (localWakeLock != null && localWakeLock!!.isHeld) {
            localWakeLock!!.release()
        }
        sensorManager = null
        localWakeLock = null
        localPowerManager = null

        if (null != voiceManage && null != voiceManage!!.getVoiceApi()) {
            voiceManage!!.getVoiceApi().leaveChannel()
            voiceManage!!.getVoiceApi().destroy()
            voiceManage = null
        }

        if (mPlayer != null) {
            mPlayer!!.clear()
        }
    }

    //重写物理返回按钮
    override fun onBackPressed() {
    }
}
