package com.ydl.audioim

import android.app.Activity
import android.content.Context
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.tencent.mmkv.MMKV
import com.ydl.audioim.http.AudioApiRequestUtil
import com.ydl.audioim.http.RtcEvent
import com.ydl.consultantim.ConsultantAudioHomeActivity
import com.ydl.ydl_av.voice.listener.RtcNetInterface
import com.ydl.ydl_av.voice.manager.YDLVoiceManager
import com.ydl.ydlcommon.utils.log.XLog
import io.agora.rtc.Constants
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import java.io.File
import java.io.FileOutputStream

class NetQuality(
    val activity: Activity,
    val channelId: String?,
    val voiceManage: YDLVoiceManager?,
    val tvNetUp: TextView,
    val ivNetQuality: ImageView,
    val tvNetQuality: TextView,
    val tvNetDown: TextView,
    val tvNetDelay: TextView,
    val layoutQualityGroup: View
) : RtcNetInterface {
    private var lastOnNetQualityDownReport = 0L
    private var lastOnNetQualityUpReport = 0L
    private var lastOnRemoteNetworkCongestion = 0L

    override fun onLocalAudioStats(bitrate: Int, packetLossRate: Int) {
        XLog.i("NetQuality", "bitrate：$bitrate,packetLossRate：$packetLossRate")
        activity.runOnUiThread {
            tvNetUp.text = "${bitrate}Kbps"
        }
    }

    override fun onNetQuality(uid: Int, tx: Int, rx: Int) {
        if (tx in 4..6 || rx in 4..6) {
            XLog.i("NetQuality", "$uid,tx：$tx,rx：$rx")
        }
        activity.runOnUiThread {
            if (uid == 0) {
                when (rx) {
                    1 -> {
                        ivNetQuality.setImageResource(R.drawable.audioim_bg_net_excellent)
                        tvNetQuality.text = "网络优秀"
                    }
                    2, 3 -> {
                        ivNetQuality.setImageResource(R.drawable.audioim_bg_net_good)
                        tvNetQuality.text = "网络良好"
                    }
                    4, 5, 6 -> {
                        ivNetQuality.setImageResource(R.drawable.audioim_bg_net_poor)
                        tvNetQuality.text = "网络极差"
                        if (System.currentTimeMillis() - lastOnNetQualityDownReport > 10 * 1000) {
                            lastOnNetQualityDownReport = System.currentTimeMillis()
                            AudioApiRequestUtil.reportCallEvent(
                                channelId,
                                RtcEvent(RtcEvent.Event.networkDownPoor),
                                retCode = rx
                            )
                        }
                    }
                }
                if (tx in 4..6) {
                    if (System.currentTimeMillis() - lastOnNetQualityUpReport > 10 * 1000) {
                        lastOnNetQualityUpReport = System.currentTimeMillis()
                        AudioApiRequestUtil.reportCallEvent(
                            channelId,
                            RtcEvent(RtcEvent.Event.networkUpPoor),
                            retCode = rx
                        )
                    }
                }
            }
        }

    }

    override fun onNetworkTypeChanged(type: Int) {
        AudioApiRequestUtil.reportCallEvent(channelId, RtcEvent(RtcEvent.Event.networkTypeChanged), retCode = type)
    }

    override fun onRemoteAudioFeel(frozenRate: Int, qoeQuality: Int, reason: Int, mos: Int) {
        XLog.i("NetQuality", "frozenRate：$frozenRate,qoeQuality：$qoeQuality,reason:$reason,mos:$mos")
    }

    override fun onRemoteAudioStateChanged(uid: Int, state: Int, reason: Int, elapsed: Int) {
        XLog.i("NetQuality", "uid：$uid,state：$state,reason:$reason,elapsed：$elapsed")
        if (reason == Constants.REMOTE_AUDIO_REASON_NETWORK_CONGESTION && state == Constants.REMOTE_AUDIO_STATE_FROZEN) {
            val qualityValue = MMKV.defaultMMKV().getString("network_quality_config", "0")
            if (TextUtils.equals(qualityValue, "1")) {
                if (System.currentTimeMillis() - lastOnRemoteNetworkCongestion > 30 * 1000) {
                    lastOnRemoteNetworkCongestion = System.currentTimeMillis()
                    voiceManage?.getVoiceApi()
                        ?.playEffect(3001, getNetLowEffect(activity))
                }
                if (activity is AudioHomeActivity) {
                    activity.showNetStatus("对方的网络状况不佳", 0)
                } else if (activity is ConsultantAudioHomeActivity) {
                    activity.showNetStatus("对方的网络状况不佳", 0)
                }
            }
        }
    }

    override fun onRemoteAudioStats(quality: Int, delay: Int, bitrate: Int, audioLossRate: Int) {
        XLog.i("NetQuality", "quality：$quality,delay：$delay,bitrate:$bitrate,audioLossRate：$audioLossRate")
        activity.runOnUiThread {
            tvNetDown.text = "${bitrate}Kbps"
            tvNetDelay.text = "${delay}ms"
            layoutQualityGroup.visibility = View.VISIBLE
        }
    }

    companion object {
        fun getHandUpEffect(context: Context): String {
            return context.filesDir.absolutePath + "/sounds/effect_hand_up.mp3"
        }

        fun getNetLowEffect(context: Context): String {
            return context.filesDir.absolutePath + "/sounds/effect_net_quality_low.m4a"
        }

        fun copySoundFile(context: Context?) {
            if (context == null) return
            Single.create<Int> {
                val filesDir = context.filesDir
                val soundFile = File(filesDir, "sounds")
                if (!soundFile.exists()) {
                    soundFile.mkdir()
                }
                val filesName = arrayOf("effect_hand_up.mp3", "effect_net_quality_low.m4a")
                filesName.forEach {
                    val file = File(soundFile, it)
                    if (!file.exists()) {
                        file.createNewFile()
                        val fileOutputStream = FileOutputStream(file)
                        context.assets.open(it).copyTo(fileOutputStream)
                        fileOutputStream.close()
                    }
                }
            }
                .observeOn(Schedulers.io())
                .subscribe()
        }
    }
}