package com.adealink.weparty.call.widget.float.calling

import android.content.Intent
import android.view.View
import com.adealink.frame.log.Log
import com.adealink.frame.router.Router
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.DisplayUtil
import com.adealink.weparty.call.constant.TAG_CALL_FLOAT_VIEW
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
import com.adealink.weparty.commonui.widget.floatview.data.FloatWindowType
import com.adealink.weparty.commonui.widget.floatview.view.BaseDragFloatView
import com.adealink.weparty.module.call.Call
import com.tencent.qcloud.tuikit.tuicallkit.common.utils.CallUtils
import com.tencent.qcloud.tuikit.tuicallkit.manager.CallManager
import io.trtc.tuikit.atomicxcore.api.call.CallParticipantStatus
import io.trtc.tuikit.atomicxcore.api.call.CallStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

class CallingFloatView(floatData: CallingFloatData) :
    BaseDragFloatView(floatData),
    ICalling {

    companion object {
        @JvmStatic
        fun dismiss() {
            WindowManagerProxy.getWindowManager()
                .removeFloatViewByType(FloatWindowType.CALL_1V1_CALLING, "")
        }
    }

    private var subscribeStateJob: Job? = null
    private var callStatus = CallParticipantStatus.None

    private var callingView: CallingView =
        CallingView(context)

    init {
        setContentView(
            callingView, LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT,
            ).apply {
                topToTop = LayoutParams.PARENT_ID
                bottomToBottom = LayoutParams.PARENT_ID
                startToStart = LayoutParams.PARENT_ID
                endToEnd = LayoutParams.PARENT_ID
            }
        )
        callingView.setOnClickListener {
            cancelCallingView()
            if (CallUtils.getSelfCallStatus() != CallParticipantStatus.None) {
                AppUtil.currentActivity?.let {
                    Router.build(context, Call.Call.PATH)
                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        .start()
                }
            }
        }
    }

    override fun showCallingView() {
        if (WindowManagerProxy.getWindowManager()
                .findFloatViewByType(FloatWindowType.CALL_1V1_CALLING) != null
        ) {
            Log.d(
                TAG_CALL_FLOAT_VIEW,
                "CallingFloatView.showCallingView return, for floatView already added."
            )
            return
        }
        Log.d(TAG_CALL_FLOAT_VIEW, "CallingFloatView.showCallingView")
        CallManager.instance.viewState.enterPipMode.set(true)
        addObserver()
        WindowManagerProxy.getWindowManager().addView(this)
    }

    private fun addObserver() {
        subscribeStateJob?.cancel()
        subscribeStateJob = CoroutineScope(Dispatchers.Main).launch {
            launch { observeCallStatus() }
        }
    }

    private suspend fun observeCallStatus() {
        CallStore.shared.observerState.selfInfo.collect { selfInfo ->
            if (callStatus != selfInfo.status) {
                callStatus = selfInfo.status
                onCallStatusChanged()
            }
        }
    }

    private fun removeObserver() {
        subscribeStateJob?.cancel()
    }

    private fun onCallStatusChanged() {
        if (callStatus == CallParticipantStatus.None) {
            cancelCallingView()
        }
    }

    override fun getLayoutParamWidth(): Int {
        return 100.dp()
    }

    override fun getLayoutParamHeight(): Int {
        return 100.dp()
    }

    override fun getClickableViews(): List<View> {
        return listOf(callingView)
    }

    override fun getLayoutParamX(): Int {
        return DisplayUtil.getScreenWidth() - getLayoutParamWidth()
    }

    override fun getLayoutParamY(): Int {
        return DisplayUtil.getScreenWidth() - getLayoutParamHeight() - 80.dp()
    }

    override fun applySnapToEdge(): Boolean {
        return true
    }

    override fun cancelCallingView() {
        Log.d(TAG_CALL_FLOAT_VIEW, "CallingFloatView.cancelCallingView")
        CallManager.instance.viewState.enterPipMode.set(false)
        if (isAttachedToWindow) {
            WindowManagerProxy.getWindowManager()
                .removeView(this, reason = "CallingFloatView.cancelCallingView")
        }
        removeObserver()
    }

}