package com.adealink.weparty.call

import android.app.Application
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.IError
import com.adealink.frame.base.Rlt
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.media.IMediaOperator
import com.adealink.frame.media.MediaConflictConfig
import com.adealink.frame.media.MediaInfo
import com.adealink.frame.spi.RegisterService
import com.adealink.frame.util.AppUtil
import com.adealink.weparty.call.manager.callManager
import com.adealink.weparty.call.widget.float.calling.CallingFloatData
import com.adealink.weparty.call.widget.float.calling.CallingFloatView
import com.adealink.weparty.commonui.BaseActivity
import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
import com.adealink.weparty.media.MediaConflictDialog
import com.adealink.weparty.module.call.ICallService
import com.tencent.qcloud.tuikit.tuicallkit.common.utils.CallUtils
import com.tencent.qcloud.tuikit.tuicallkit.manager.bridge.CallServiceInitializer
import io.trtc.tuikit.atomicxcore.api.CompletionHandler
import io.trtc.tuikit.atomicxcore.api.call.CallStore
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext

@RegisterService(ICallService::class)
class CallServiceImpl : ICallService {

    override fun appOnCreateMainTask(application: Application) {
        CallServiceInitializer.createInstance(application)
    }


    override fun call(
        uid: String,
        onSuccess: (() -> Unit)?,
        onFail: ((Int, String?) -> Unit)?
    ) {
        val activity = AppUtil.currentActivity as? BaseActivity
        if (activity == null || activity.isDestroyed || activity.isFinishing) {
            return
        }
        activity.showLoading()
        callManager.call(uid, object : CompletionHandler {
            override fun onSuccess() {
                activity.dismissLoading()
                onSuccess?.invoke()
            }

            override fun onFailure(code: Int, desc: String) {
                activity.dismissLoading()
                onFail?.invoke(code, desc)
            }
        })
    }

    override fun getCallingFloatView(data: IFloatData): CallingFloatView {
        return CallingFloatView(data as CallingFloatData)
    }

    override fun getService(): ICallService {
        return this
    }

    override fun getMediaOperator(): IMediaOperator {
        return object : IMediaOperator {

            override suspend fun isMediaIn(): Boolean {
                //当前正在呼叫
                return CallUtils.isSelfInCalling()
            }

            override suspend fun leaveMedia(): Rlt<Any> {
                CallStore.shared.hangup(null)
                return Rlt.Success(Any())
            }

            override suspend fun confirmExitConflictMedia(
                exitMediaInfo: MediaInfo,
                enterMediaInfo: MediaInfo
            ): Rlt<Any> {
                val currentActivity =
                    AppUtil.currentActivity as? BaseActivity ?: return Rlt.Success(Any())
                return withContext(Dispatcher.UI) {
                    suspendCancellableCoroutine { continuation ->
                        var confirm = false
                        MediaConflictDialog.show(
                            exitMediaInfo,
                            enterMediaInfo,
                            currentActivity.supportFragmentManager,
                            onPositive = {
                                confirm = true
                            },
                            onNegative = null,
                            onDismiss = {
                                if (continuation.isActive) {
                                    if (confirm) {
                                        continuation.resume(Rlt.Success(Any()), null)
                                    } else {
                                        continuation.resume(Rlt.Failed(IError()), null)
                                    }
                                }
                            }
                        )
                    }
                }
            }

            override fun getConflictConfig(): MediaConflictConfig {
                return MediaConflictConfig(
                    MediaInfo(
                        com.adealink.weparty.media.MediaType.CALL_1V1.type,
                        getCompatString(R.string.call_chat)
                    ), false
                )
            }

            override fun getJoinedRoomId(): String? {
                return CallStore.shared.observerState.activeCall.value.callId
            }

            override suspend fun rejoinRoom(): Rlt<Any> {
                //1v1不支持重进房
                return Rlt.Success(Any())
            }

        }
    }

    override fun onLogout() {
        callManager.clear()
    }


}