package com.adealink.weparty.room.minimize.manager

import android.app.Activity
import com.adealink.frame.base.fastLazy
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.log.Log
import com.adealink.frame.room.data.FlowStateInfo
import com.adealink.frame.room.data.LeaveRoomReason
import com.adealink.frame.room.data.RoomState
import com.adealink.frame.router.Router
import com.adealink.frame.util.ActivityLifecycleCallbacksExt
import com.adealink.frame.util.AppUtil
import com.adealink.frame.util.runOnUiThread
import com.adealink.weparty.commonui.widget.floatview.FloatViewFactory
import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
import com.adealink.weparty.commonui.widget.floatview.data.MODE_APPLICATION
import com.adealink.weparty.module.room.Room
import com.adealink.weparty.module.room.data.EnterRoomInfo
import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatData
import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatView
import com.adealink.weparty.room.sdk.listener.IJoinListener
import com.adealink.weparty.room.sdk.service.roomService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

val minimizeRoomManager: IMinimizeRoomManager by lazy { MinimizeRoomManager() }

class MinimizeRoomManager : IMinimizeRoomManager,
    ActivityLifecycleCallbacksExt, IJoinListener {
    private var minimizedRoomFloatView: MinimizedRoomFloatView? = null
    private val floatViewFactory by fastLazy { FloatViewFactory() }

    val show: Boolean
        get() {
            roomService.joinController.joinedRoomInfo ?: return false
            //会所房间不支持最小化
            return AppUtil.currentActivity
                ?.let { !DISMISS_ACTIVITIES.contains(it.javaClass.name) }
                ?: false
        }

    override fun init() {
        roomService.joinController.addListener(this)
        AppUtil.registerActivityLifecycleCallbacks(this)
    }

    override fun onActivityResumed(activity: Activity) {
        super.onActivityResumed(activity)
        Log.d(TAG, "onActivityResumed")
        showMinimizeRoomIfNeed(activity)
    }

    override fun onRoomStateChanged(
        fromState: RoomState,
        toState: RoomState,
        flowStateInfo: FlowStateInfo
    ) {
        when (toState) {
            RoomState.ROOM_IN -> {
                onRoomIn(flowStateInfo.roomId, flowStateInfo)
            }

            RoomState.ROOM_LEAVE -> {
                onRoomLeaved(flowStateInfo.roomId, flowStateInfo)
            }

            else -> {}
        }
    }

    private fun onRoomIn(roomId: String, flowStateInfo: FlowStateInfo) {
        Log.d(TAG, "onRoomIn")
        removeMinimizedRoomView()
    }

    private fun onRoomLeaved(roomId: String, flowStateInfo: FlowStateInfo) {
        Log.d(TAG, "onRoomLeaved")
        removeMinimizedRoomView()
    }

    private fun checkShowOrNot(activity: Activity?): Boolean {
        val roomInfo = roomService.joinController.joinedRoomInfo
        val joinRoomState = roomService.joinController.getJoinRoomState()
        Log.d(
            TAG,
            "checkShowOrNot, roomInfo:$roomInfo, joinRoomState:$joinRoomState, activity:$activity"
        )
        if (roomInfo == null) {
            //无进房信息
            return false
        }

        if (activity != null) {
            return !DISMISS_ACTIVITIES.contains(activity.javaClass.name)
        }

        return true
    }

    private fun showMinimizeRoomIfNeed(activity: Activity?) {
        Log.d(TAG, "showMinimizeRoomIfNeed")
        if (checkShowOrNot(activity)) {
            addMinimizedRoomView()
        } else {
            removeMinimizedRoomView()
        }
    }

    override fun addMinimizedRoomView() {
        Log.d(TAG, "addMinimizedRoomView")
        runOnUiThread {
            if (minimizedRoomFloatView != null) {
                minimizedRoomFloatView?.show()
                return@runOnUiThread
            }
            minimizedRoomFloatView =
                floatViewFactory.createFloatView(MinimizedRoomFloatData(MODE_APPLICATION))
            minimizedRoomFloatView?.let {
                WindowManagerProxy.getWindowManager().addView(it)
            }
            minimizedRoomFloatView?.setOnRoomClick {
                val activity = AppUtil.currentActivity ?: return@setOnRoomClick
                val roomId =
                    roomService.joinController.getJoinedRoomId() ?: return@setOnRoomClick
                Router.build(activity, Room.Room.PATH)
                    .putExtra(
                        Room.Room.EXTRA_ENTER_ROOM_ID,
                        roomId
                    )
                    .start()
            }
            minimizedRoomFloatView?.setOnCloseClick {
                handleExitRoom(LeaveRoomReason.INITIATIVE)
            }
            minimizedRoomFloatView?.show()
        }
    }

    override fun removeMinimizedRoomView() {
        Log.d(TAG, "removeMinimizedRoomView")
        runOnUiThread {
            minimizedRoomFloatView?.let {
                it.hide()
                WindowManagerProxy.getWindowManager().removeView(it)
            }
            minimizedRoomFloatView = null
        }
    }

    // TODO: zhangfei 踢人场景
//    override fun onKickOutRoom(kickReason: Long) {
//        runOnUiThread {
//            if (minimizedRoomFloatView?.isVisible == true) {
//                val activity = AppUtil.currentActivity as? FragmentActivity ?: return@runOnUiThread
//                CommonDialog.Builder()
//                    .message(getCompatString(R.string.room_kick_out_tip))
//                    .onPositive {
//                        handleExitRoom(LeaveRoomReason.KICK_OUT)
//                    }
//                    .build()
//                    .show(activity.supportFragmentManager, "KickedOutTipDialog")
//            }
//        }
//    }

    private fun handleExitRoom(reason: LeaveRoomReason) {
        CoroutineScope(Dispatcher.UI).launch {
            roomService.joinController.leaveRoom(reason)
        }
        removeMinimizedRoomView()
    }

    companion object {
        private const val TAG = "MinimizeRoomManager"

        private val DISMISS_ACTIVITIES = hashSetOf<String>().apply {
            Router.getClazz(Room.Room.PATH)?.let { this.add(it.name) }
        }
    }
}