package ru.forbion.f7cloud.mobile

import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.addCallback
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import ru.forbion.f7cloud.core.auth.AuthStore
import ru.forbion.f7cloud.core.designsystem.F7Theme
import ru.forbion.f7cloud.core.push.F7IncomingCallQueue
import ru.forbion.f7cloud.core.push.F7IncomingCallRinger
import ru.forbion.f7cloud.core.push.PushIntents
import ru.forbion.f7cloud.core.push.TalkCallPushLabels
import ru.forbion.f7cloud.feature.talknative.TalkNativeCallLauncher

/**
 * Full-screen incoming call UI (Telegram-style).
 * Notification body tap / lock-screen → preview with Accept/Decline.
 * Notification Accept button → joins call immediately.
 */
class CallIncomingActivity : ComponentActivity() {

    private var callEndedListener: ((String) -> Unit)? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
        }
        @Suppress("DEPRECATION")
        window.addFlags(
            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
        )

        val launch = parseLaunch(intent)
        if (launch == null) {
            finish()
            return
        }
        if (launch.autoAccept) {
            acceptCall(launch)
            finish()
            return
        }

        onBackPressedDispatcher.addCallback(this) {
            declineCall(launch)
            finish()
        }

        // Звонок сняли извне (30-с таймаут «не берут трубку», принят/отклонён из
        // уведомления) — закрываем полноэкранный входящий.
        launch.roomToken?.takeIf { it.isNotBlank() }?.let { token ->
            val listener: (String) -> Unit = { ended ->
                if (ended == token) {
                    runOnUiThread {
                        if (!isFinishing) finish()
                    }
                }
            }
            callEndedListener = listener
            F7IncomingCallQueue.addCallEndedListener(listener)
        }

        setContent {
            F7Theme {
                IncomingCallScreen(
                    modifier = Modifier.fillMaxSize(),
                    callerName = launch.displayName,
                    subtitle = launch.subtitle,
                    onAccept = {
                        acceptCall(launch)
                        finish()
                    },
                    onDecline = {
                        declineCall(launch)
                        finish()
                    },
                )
            }
        }
    }

    override fun onDestroy() {
        callEndedListener?.let(F7IncomingCallQueue::removeCallEndedListener)
        callEndedListener = null
        super.onDestroy()
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        val launch = parseLaunch(intent) ?: return
        if (launch.autoAccept) {
            acceptCall(launch)
            finish()
        }
    }

    private fun acceptCall(launch: IncomingCallLaunch) {
        F7IncomingCallRinger.stop()
        val session = AuthStore(this).load() ?: return
        F7IncomingCallQueue.dismissAndShowNext(this, launch.roomToken)
        TalkNativeCallLauncher.launchIncomingCall(
            this,
            session,
            launch.acceptUrl,
            roomDisplayName = launch.displayName,
        )
    }

    private fun declineCall(launch: IncomingCallLaunch) {
        F7IncomingCallQueue.dismissAndShowNext(this, launch.roomToken)
    }

    private fun parseLaunch(intent: Intent?): IncomingCallLaunch? {
        if (intent == null) return null
        val acceptUrl = intent.getStringExtra(PushIntents.EXTRA_ACCEPT_URL)?.takeIf { it.isNotBlank() }
            ?: return null
        return IncomingCallLaunch(
            acceptUrl = acceptUrl,
            roomToken = intent.getStringExtra(PushIntents.EXTRA_ROOM_TOKEN),
            title = intent.getStringExtra(PushIntents.EXTRA_CALL_TITLE).orEmpty(),
            displayName = intent.getStringExtra(PushIntents.EXTRA_ROOM_DISPLAY_NAME)
                ?.takeIf { it.isNotBlank() }
                ?: TalkCallPushLabels.resolveRoomDisplayName(
                    intent.getStringExtra(PushIntents.EXTRA_CALL_TITLE).orEmpty(),
                    intent.getStringExtra(PushIntents.EXTRA_CALL_BODY).orEmpty(),
                    null,
                ),
            subtitle = intent.getStringExtra(PushIntents.EXTRA_CALL_BODY)
                ?.takeIf { it.isNotBlank() }
                ?: getString(ru.forbion.f7cloud.core.push.R.string.incoming_call_subtitle),
            autoAccept = intent.getBooleanExtra(PushIntents.EXTRA_AUTO_ACCEPT, false),
        )
    }
}

private data class IncomingCallLaunch(
    val acceptUrl: String,
    val roomToken: String?,
    val title: String,
    val displayName: String,
    val subtitle: String,
    val autoAccept: Boolean,
)
