package com.za.common.speech

import android.app.Application
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.MediaPlayer
import androidx.core.content.ContextCompat
import com.za.base.AppConfig
import com.za.bean.request.AppNewOrderVoiceRequest
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.net.BaseObserver
import com.za.net.RetrofitHelper
import com.za.room.RoomHelper
import com.za.room.db.user.LocalResourceBean
import com.za.servicing.R
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

object SpeechManager {
	private var mContext : Application? = null


	fun init(context : Application?) {
		mContext = context //语音合成初始化|

		TTSManager.init(context, object : OnTTSListener {
			override fun onTTSInitialized() { // TTS初始化成功，可以开始播放语音
				LogUtil.print("TTS", "TTS initialized successfully")
			}

			override fun onTTSSuccess() {
				LogUtil.print("TTS", "TTS speech completed successfully")
				resetAudioVolume()
			}

			override fun onTTSFailed(errorMessage : String?) {
				resetAudioVolume() // TTS初始化失败或语音播放失败，使用科大讯飞进行播放
				LogUtil.print("TTS", "TTS failed: $errorMessage")
				if (lastFailedText != null && ! lastFailedText.isNullOrBlank()) {
					speechKDXF(lastFailedText)
					lastFailedText = null
				}
			}
		})
	}

	private var lastFailedText : String? = null
	fun speech(msg : String?) {
		setMaxAudioVolume()
		lastFailedText = msg
		TTSManager.speak(msg)
	}

	private fun speechKDXF(msg : String?) {

	}

	private var originVolume = 0
	private fun setMaxAudioVolume() {
		try {
			if (! AppConfig.isRelease) {
				return
			}
			val audioManager =
				ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
			originVolume = audioManager?.getStreamVolume(AudioManager.STREAM_MUSIC) ?: 0
			val maxVolume = audioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
			audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
				maxVolume ?: 1,
				AudioManager.FLAG_PLAY_SOUND)
		} catch (e : Exception) {
			LogUtil.print("setMaxAudioVolume", e)
		}
	}

	private fun resetAudioVolume() {
		try {
			if (! AppConfig.isRelease) {
				return
			}
			val audioManager =
				ContextCompat.getSystemService(GlobalData.application, AudioManager::class.java)
			audioManager?.setStreamVolume(AudioManager.STREAM_MUSIC,
				originVolume,
				AudioManager.FLAG_PLAY_SOUND)
		} catch (e : Exception) {
			LogUtil.print("resetAudioVolume", e)
		}
	}

	fun stopSpeech() {
		TTSManager.stop()
		lastFailedText = null
	}

	private var mediaPlayer : MediaPlayer? = null

	// 当前订单被取消
	fun playCurrentOrderCanceled() {
		mediaPlayer = MediaPlayer.create(mContext, R.raw.current_order_cancel)
		mediaPlayer?.start()
	}

	// 订单被取消
	fun playOrderCanceled() {
		mediaPlayer = MediaPlayer.create(mContext, R.raw.cancel_order)
		mediaPlayer?.start()
	}

	// 面部居中
	fun playFaceCenter() {
		mediaPlayer = MediaPlayer.create(mContext, R.raw.face_center)
		mediaPlayer?.start()
	}

	// 面部居中
	fun playFaceLeft() {
		mediaPlayer = MediaPlayer.create(mContext, R.raw.face_left)
		mediaPlayer?.start()
	}

	// 面部居中
	fun playFaceRight() {
		mediaPlayer = MediaPlayer.create(mContext, R.raw.face_right)
		mediaPlayer?.start()
	}

	private fun playNewOrder() {
		try {            // 先释放之前的MediaPlayer实例，避免资源泄漏
			releaseMediaPlayer()

			// 创建新的MediaPlayer实例
			mediaPlayer = MediaPlayer.create(GlobalData.application, R.raw.neworder)
			mediaPlayer?.setOnCompletionListener {                // 播放完成后释放资源
				releaseMediaPlayer()
			}
			mediaPlayer?.setOnErrorListener { mp, what, extra ->
				LogUtil.print("playNewOrder", "MediaPlayer错误: what=$what, extra=$extra")
				releaseMediaPlayer()
				true
			}

			// 设置最大音量
			setMaxAudioVolume()

			// 开始播放
			mediaPlayer?.start()
		} catch (e : Exception) {
			LogUtil.print("playNewOrder", "播放出错: ${e.message}")
			releaseMediaPlayer()
		}
	}

	private fun playNewOrderFromNet(url : String) {
		try {            // 先释放之前的MediaPlayer实例
			LogUtil.print("playNewOrderFromNet", "播放新订单语音: $url")
			releaseMediaPlayer()            // 创建新的MediaPlayer实例
			mediaPlayer = MediaPlayer()
			mediaPlayer?.setAudioAttributes(AudioAttributes.Builder()
				.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
				.setUsage(AudioAttributes.USAGE_MEDIA).build())

			mediaPlayer?.setDataSource(url)
			mediaPlayer?.setOnPreparedListener {                // 设置最大音量
				setMaxAudioVolume()                // 准备完成后开始播放
				it.start()
			}
			mediaPlayer?.setOnCompletionListener {                // 播放完成后释放资源
				releaseMediaPlayer()
			}
			mediaPlayer?.setOnErrorListener { mp, what, extra ->
				LogUtil.print("playNewOrderFromNet", "MediaPlayer错误: what=$what, extra=$extra")
				releaseMediaPlayer()
				true
			}

			// 异步准备，避免阻塞UI线程
			mediaPlayer?.prepareAsync()
		} catch (e : Exception) {
			LogUtil.print("playNewOrderFromNet", "播放出错: ${e.message}")
			releaseMediaPlayer()
		}
	}

	// 安全释放MediaPlayer资源
	fun releaseMediaPlayer() {
		try {
			mediaPlayer?.let {
				if (it.isPlaying) {
					it.stop()
				}
				it.reset()
				it.release()
			}
			mediaPlayer = null            // 恢复原始音量
			resetAudioVolume()
		} catch (e : Exception) {
			LogUtil.print("releaseMediaPlayer", "释放MediaPlayer出错: ${e.message}")
		}
	}

	fun speechNewOrderSound(content : String?) {
		if (content.isNullOrBlank()) {
			speechNewOrderLocalSoundLooper()
			return
		}

		val localResourceDao = RoomHelper.db?.localResourceDao()
		val localUrlResource = localResourceDao?.getLocalResourceByName(content)
		if (localUrlResource != null && ! localUrlResource.resourceUrl.isNullOrBlank()) {
			speechNewOrderNetLooper(content, localUrlResource.resourceUrl ?: "")
			LogUtil.print("handlerNewOrderVoice", "播放本地语音");
			return
		}

		val appNewOrderVoiceRequest = AppNewOrderVoiceRequest(content)
		RetrofitHelper.getDefaultService().getVoiceUrl(appNewOrderVoiceRequest)
			.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
			.subscribe(object : BaseObserver<String>() {
				override fun doSuccess(it : String?) {
					if (it == null) {
						speechNewOrderLocalSoundLooper()
						return
					}
					localResourceDao?.insert(LocalResourceBean(resourceName = content,
						resourceType = 1,
						resourceUrl = it))
					speechNewOrderNetLooper(content, it)
				}

				override fun doFailure(code : Int, msg : String?) {
					speechNewOrderLocalSoundLooper()
				}
			})
	}


	private fun speechNewOrderLocalSoundLooper() {
		CoroutineScope(Dispatchers.IO).launch {
			val startTime = System.currentTimeMillis()
			while (System.currentTimeMillis() - startTime < 1000 * 60 * 3 && GlobalData.isHandlerNewOrder == false) {
				try {
					delay(250L * "您有新的中道救援订单，请尽快接单！".length)
					withContext(Dispatchers.Main) {
						playNewOrder()
					}
				} catch (e : Exception) {
					LogUtil.print("speechNewOrderLooper",
						"播放循环出错: ${e.message}")                    // 出错时也要等待一下，避免无限循环
					delay(1000)
				}
			}
			GlobalData.isHandlerNewOrder = false
		}
	}

	private fun speechNewOrderNetLooper(content : String, url : String) {
		val url = url.replace("http://", "https://")
		GlobalData.isHandlerNewOrder = false
		CoroutineScope(Dispatchers.IO).launch {
			val startTime = System.currentTimeMillis()
			while (System.currentTimeMillis() - startTime < 1000 * 60 * 3 && GlobalData.isHandlerNewOrder == false) {
				try {
					withContext(Dispatchers.Main) {
						playNewOrderFromNet(url)
					}
					delay(250L * content.length)
				} catch (e : Exception) {
					LogUtil.print("speechNewOrderLooper",
						"播放循环出错: ${e.message}")                    // 出错时也要等待一下，避免无限循环
					delay(1000)
				}
			}
			GlobalData.isHandlerNewOrder = false
		}
	}
}