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

import android.Manifest
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat

sealed interface IncomingCallFullScreenSetupResult {
    data object Ready : IncomingCallFullScreenSetupResult
    data object NeedsPostNotificationsPermission : IncomingCallFullScreenSetupResult
    data class NeedsSystemSettings(
        val detail: String,
        val intent: Intent
    ) : IncomingCallFullScreenSetupResult
}

object IncomingCallFullScreenSetupHelper {
    fun evaluate(context: Context): IncomingCallFullScreenSetupResult {
        AndroidPushBootstrapper.tryInitialize(context)

        if (
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
            ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED
        ) {
            return IncomingCallFullScreenSetupResult.NeedsPostNotificationsPermission
        }

        if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
            return IncomingCallFullScreenSetupResult.NeedsSystemSettings(
                detail = "Для полноэкранного входящего звонка Android требует включённые уведомления для Икар.",
                intent = buildAppNotificationsIntent(context)
            )
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager = context.getSystemService(NotificationManager::class.java)
            val callsChannel = notificationManager?.getNotificationChannel(AndroidPushBootstrapper.callsChannelId())
            if (callsChannel != null && callsChannel.importance < NotificationManager.IMPORTANCE_HIGH) {
                return IncomingCallFullScreenSetupResult.NeedsSystemSettings(
                    detail = "Для полноэкранного входящего звонка Android требует высокий приоритет канала «Звонки».",
                    intent = buildCallsChannelIntent(context)
                )
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            val notificationManager = context.getSystemService(NotificationManager::class.java)
            val canUseFullScreenIntent = notificationManager?.canUseFullScreenIntent() == true
            if (!canUseFullScreenIntent) {
                return IncomingCallFullScreenSetupResult.NeedsSystemSettings(
                detail = "Для полноэкранного входящего звонка Android требует разрешить полноэкранный вызов для Икар.",
                    intent = buildFullScreenIntentSettingsIntent(context)
                )
            }
        }

        return IncomingCallFullScreenSetupResult.Ready
    }

    private fun buildAppNotificationsIntent(context: Context): Intent =
        resolveSettingsIntent(
            context = context,
            primary = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
                putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
                putExtra("android.provider.extra.APP_PACKAGE", context.packageName)
                data = Uri.parse("package:${context.packageName}")
            }
        )

    private fun buildCallsChannelIntent(context: Context): Intent =
        resolveSettingsIntent(
            context = context,
            primary = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
                putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
                putExtra(Settings.EXTRA_CHANNEL_ID, AndroidPushBootstrapper.callsChannelId())
            }
        )

    private fun buildFullScreenIntentSettingsIntent(context: Context): Intent =
        resolveSettingsIntent(
            context = context,
            primary = Intent(Settings.ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT).apply {
                data = Uri.parse("package:${context.packageName}")
            }
        )

    private fun resolveSettingsIntent(context: Context, primary: Intent): Intent {
        val packageManager = context.packageManager
        if (primary.resolveActivity(packageManager) != null) {
            return primary.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }

        return Intent(
            Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
            Uri.parse("package:${context.packageName}")
        ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    }
}
