package com.seven.ikar.kotlin.core.push

import android.app.KeyguardManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PowerManager
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.Person
import com.seven.ikar.kotlin.feature.call.IncomingCallActivity

object IncomingCallNotificationManager {
    fun showIncomingCall(context: Context, invite: PendingIncomingCallInvite) {
        val notificationId = notificationIdFor(invite.callId)
        val contentIntent = IncomingCallActivity.createLaunchIntent(context, invite)
        val contentPendingIntent = PendingIntent.getActivity(
            context,
            notificationId,
            contentIntent,
            pendingIntentFlags(updateCurrent = true)
        )
        val answerPendingIntent = PendingIntent.getActivity(
            context,
            notificationId + 1,
            IncomingCallActivity.createLaunchIntent(context, invite, autoAccept = true),
            pendingIntentFlags(updateCurrent = true)
        )
        val declinePendingIntent = PendingIntent.getBroadcast(
            context,
            notificationId + 2,
            invite.applyToIntent(
                Intent(context, NotificationActionReceiver::class.java).apply {
                    action = NotificationAction.DeclineIncomingCallAction
                }
            ),
            pendingIntentFlags(updateCurrent = true)
        )

        val title = invite.callerDisplayName
        val body = if (invite.mediaType == com.seven.ikar.kotlin.core.model.CallMediaType.Video) {
            "Видеозвонок в Икар"
        } else {
            "Аудиозвонок в Икар"
        }

        val useFullScreenIntent = shouldUseFullScreenIntent(context)
        val notificationBuilder = NotificationCompat.Builder(context, AndroidPushBootstrapper.callsChannelId())
            .setSmallIcon(android.R.drawable.sym_call_incoming)
            .setContentTitle(title)
            .setContentText(body)
            .setCategory(NotificationCompat.CATEGORY_CALL)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setOngoing(true)
            .setAutoCancel(false)
            .setContentIntent(contentPendingIntent)
        if (useFullScreenIntent) {
            notificationBuilder
                .setColorized(true)
                .setStyle(
                    NotificationCompat.CallStyle.forIncomingCall(
                        Person.Builder().setName(invite.callerDisplayName).build(),
                        declinePendingIntent,
                        answerPendingIntent
                    )
                )
            notificationBuilder.setFullScreenIntent(contentPendingIntent, true)
        } else {
            notificationBuilder
                .setStyle(NotificationCompat.BigTextStyle().bigText(body))
                .addAction(android.R.drawable.ic_menu_close_clear_cancel, "Отклонить", declinePendingIntent)
                .addAction(android.R.drawable.sym_call_incoming, "Принять", answerPendingIntent)
        }

        NotificationManagerCompat.from(context).notify(notificationId, notificationBuilder.build())
    }

    fun cancelIncomingCall(context: Context, callId: String?) {
        val normalizedCallId = callId?.takeIf { it.isNotBlank() } ?: return
        NotificationManagerCompat.from(context).cancel(notificationIdFor(normalizedCallId))
    }

    fun openIncomingCallScreen(
        context: Context,
        invite: PendingIncomingCallInvite,
        autoAccept: Boolean = false
    ) {
        context.startActivity(IncomingCallActivity.createLaunchIntent(context, invite, autoAccept))
    }

    private fun shouldUseFullScreenIntent(context: Context): Boolean {
        val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager
        val powerManager = context.getSystemService(Context.POWER_SERVICE) as? PowerManager
        val isKeyguardLocked = keyguardManager?.isKeyguardLocked == true
        val isInteractive = powerManager?.isInteractive ?: true
        return isKeyguardLocked || !isInteractive
    }

    private fun notificationIdFor(callId: String): Int = callId.hashCode()

    private fun pendingIntentFlags(updateCurrent: Boolean): Int {
        val mutableFlags = if (updateCurrent) PendingIntent.FLAG_UPDATE_CURRENT else 0
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mutableFlags or PendingIntent.FLAG_IMMUTABLE
        } else {
            mutableFlags
        }
    }
}
