package com.adealink.weparty.room.interceptor

import android.os.SystemClock
import androidx.fragment.app.FragmentActivity
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.log.Log
import com.adealink.frame.media.MediaInfo
import com.adealink.frame.room.data.JoinRoomReq
import com.adealink.frame.router.RouterDeepLinkActivity
import com.adealink.frame.router.interceptor.UriInterceptor
import com.adealink.frame.router.request.UriRequest
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.isActivityDestroy
import com.adealink.weparty.App
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.ProgressDialog
import com.adealink.weparty.media.MediaType
import com.adealink.weparty.module.gift.GiftModule
import com.adealink.weparty.module.room.Room
import com.adealink.weparty.module.room.Room.Room.Companion.EXTRA_ENTER_ROOM_INFO
import com.adealink.weparty.module.room.data.EnterRoomInfo
import com.adealink.weparty.room.R
import com.adealink.weparty.room.constant.TAG_ROOM_ENTER_ROOM
import com.adealink.weparty.room.constant.enterRoomJoinReqTime
import com.adealink.weparty.room.constant.enterRoomJoinResTime
import com.adealink.weparty.room.constant.enterRoomUILoadTime
import com.adealink.weparty.room.constant.markEnterRoomTime
import com.adealink.weparty.room.datasource.local.RoomLocalService
import com.adealink.weparty.room.sdk.service.roomService
import com.adealink.weparty.util.parcelableExtra
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

class EnterRoomUriInterceptor : UriInterceptor {

    override fun intercept(chain: UriInterceptor.Chain) {
        val request = chain.request()
        val activity = request.ctx as? FragmentActivity
        if (activity == null || isActivityDestroy(activity)) {
            Log.e(TAG_ROOM_ENTER_ROOM, "EnterRoomUriInterceptor, activity is null")
            chain.abort()
            return
        }

        CoroutineScope(Dispatcher.UI).launch {
            enterRoom(activity, chain)
        }
    }

    private suspend fun enterRoom(activity: FragmentActivity, chain: UriInterceptor.Chain) {
        markEnterRoomTime(SystemClock.elapsedRealtime())
        val request = chain.request()
        val intent = request.intent
        //获取activity finish参数
        val finishActivity = intent.getBooleanExtra("extra_success_finish_activity", false)
        val finishDeeplinkActivity = intent.getBooleanExtra("extra_finish_deeplink_activity", false)
                && activity is RouterDeepLinkActivity

        enterRoomInner(activity, object : UriInterceptor.Chain {
            override fun request(): UriRequest {
                return chain.request()
            }

            override fun proceed(innerRequest: UriRequest) {
                if (finishActivity && isActivityDestroy(activity).not()) {
                    activity.finish()
                }
                if (finishDeeplinkActivity && isActivityDestroy(activity).not()) {
                    activity.finish()
                }
                val activityDestroy = isActivityDestroy(activity)
                if (activityDestroy) {
                    request.ctx = AppUtil.currentActivity
                }
                enterRoomUILoadTime = SystemClock.elapsedRealtime()
                chain.proceed(request)
            }

            override fun abort() {
                if (finishActivity && isActivityDestroy(activity).not()) {
                    activity.finish()
                }
                if (finishDeeplinkActivity && isActivityDestroy(activity).not()) {
                    activity.finish()
                }
                chain.abort()
            }
        })
    }

    private suspend fun enterRoomInner(activity: FragmentActivity, chain: UriInterceptor.Chain) {
        val request = chain.request()
        val intent = request.intent


        var enterRoomInfo: EnterRoomInfo?
        //1. 从跳转参数中获取进房信息
        enterRoomInfo = intent.parcelableExtra(EXTRA_ENTER_ROOM_INFO, EnterRoomInfo::class.java)

        Log.d(
            TAG_ROOM_ENTER_ROOM,
            "EnterRoomUriInterceptor, getEnterRoomInfo from enterRoomInfo, $enterRoomInfo"
        )

        //2. 从deepLink进房参数中获取房间ID,合成进房信息
        if (enterRoomInfo == null) {
            //deepLink进房
            val roomId = intent.getStringExtra(Room.Room.EXTRA_ENTER_ROOM_ID)
            if (roomId != null && !roomId.isNullOrEmpty()) {
                enterRoomInfo = EnterRoomInfo(roomId = roomId)
            }
            Log.d(
                TAG_ROOM_ENTER_ROOM,
                "EnterRoomUriInterceptor, getEnterRoomInfo from roomId, $enterRoomInfo"
            )
        }

        //房间信息无效,跳转房间失败
        if (enterRoomInfo == null || enterRoomInfo.roomId.isNullOrEmpty()) {
            chain.abort()
            Log.e(
                TAG_ROOM_ENTER_ROOM,
                "EnterRoomUriInterceptor, enterRoomInfo is null / roomId is 0, abort()"
            )
            return
        }

        if (enterRoomInfo.roomInfo?.isSupportedRoomType() == false) {
            showToast(R.string.room_unsupported_room_type)
            chain.abort()
            Log.e(
                TAG_ROOM_ENTER_ROOM,
                "EnterRoomUriInterceptor, unsupported room type (${enterRoomInfo.roomInfo?.roomType}), abort()"
            )
            return
        }

        //跳转参数补充房间信息
        intent.putExtra(EXTRA_ENTER_ROOM_INFO, enterRoomInfo)

        //当前已经是进房状态,直接进入房间
        val joinedRoomId = roomService.joinController.getJoinedRoomId()
        if (joinedRoomId == enterRoomInfo.roomId) {
            Log.d(TAG_ROOM_ENTER_ROOM, "EnterRoomUriInterceptor, already joined room, proceed()")
            chain.proceed(request)
            return
        }

        //房间媒体冲突处理失败,进房失败
        val conflictRlt = App.instance.mediaManager.conflictHandle(
            MediaInfo(MediaType.CHAT_ROOM.type, getCompatString(R.string.room_chat))
        )
        if (conflictRlt is Rlt.Failed) {
            Log.e(TAG_ROOM_ENTER_ROOM, "EnterRoomUriInterceptor, media conflict fail, abort()")
            chain.abort()
            return
        }

        enterRoomJoinReqTime = SystemClock.elapsedRealtime()
        val progressDialog = ProgressDialog.Builder()
            .text(getCompatString(R.string.room_entering_room))
            .build()
        progressDialog.show(activity.supportFragmentManager, ProgressDialog.TAG)

        val result = roomService.joinController.suspendJoinRoom(
            JoinRoomReq(
                enterRoomInfo.roomId
            )
        )
        progressDialog.dismiss()
        enterRoomJoinResTime = SystemClock.elapsedRealtime()
        when (result) {
            is Rlt.Success -> {
                Log.i(TAG_ROOM_ENTER_ROOM, "EnterRoomUriInterceptor, join room success, proceed()")
                RoomLocalService.lastEnterRoomId = enterRoomInfo.roomId
                GiftModule.getGifts(enterRoomInfo.roomId, true)
                chain.proceed(request)
            }

            is Rlt.Failed -> {
                Log.e(
                    TAG_ROOM_ENTER_ROOM,
                    "EnterRoomUriInterceptor, join room fail(${result.error.serverCode}), abort()"
                )
                showToast(result)
                chain.abort()
            }
        }
    }


}