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

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions

object AndroidPushBootstrapper {
    private const val MessageDefaultChannelId = "ikar_kotlin_messages_default_v2"
    private const val MessageRingtoneChannelId = "ikar_kotlin_messages_ringtone_v2"
    private const val MessageAlarmChannelId = "ikar_kotlin_messages_alarm_v2"
    private const val MessageSilentChannelId = "ikar_kotlin_messages_silent_v2"
    private const val UpdatesChannelId = "ikar_kotlin_updates_v1"
    private const val LegacyCallsChannelId = "ikar_kotlin_calls_v1"
    private const val CallsChannelId = "ikar_kotlin_calls_v2"

    fun tryInitialize(context: Context): Boolean {
        if (tryGetExistingApp() != null) {
            ensureChannels(context)
            return true
        }

        val options = AndroidFirebaseOptionsLoader.tryLoad(context) ?: return false
        val firebaseOptions = FirebaseOptions.Builder()
            .setApplicationId(options.applicationId)
            .setProjectId(options.projectId)
            .setApiKey(options.apiKey)
            .setGcmSenderId(options.senderId)
            .build()

        return runCatching {
            FirebaseApp.initializeApp(context, firebaseOptions)
        }.getOrNull()?.let {
            ensureChannels(context)
            true
        } ?: false
    }

    fun messageChannelId(soundOption: NotificationSoundOption): String = when (soundOption) {
        NotificationSoundOption.Default -> MessageDefaultChannelId
        NotificationSoundOption.Ringtone -> MessageRingtoneChannelId
        NotificationSoundOption.Alarm -> MessageAlarmChannelId
        NotificationSoundOption.Silent -> MessageSilentChannelId
    }

    fun updatesChannelId(): String = UpdatesChannelId

    fun callsChannelId(): String = CallsChannelId

    private fun ensureChannels(context: Context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            return
        }

        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager ?: return
        if (manager.getNotificationChannel(LegacyCallsChannelId) != null) {
            manager.deleteNotificationChannel(LegacyCallsChannelId)
        }

        ensureMessageChannel(
            manager = manager,
            channelId = MessageDefaultChannelId,
            channelName = "Сообщения",
            soundOption = NotificationSoundOption.Default
        )
        ensureMessageChannel(
            manager = manager,
            channelId = MessageRingtoneChannelId,
            channelName = "Сообщения (рингтон)",
            soundOption = NotificationSoundOption.Ringtone
        )
        ensureMessageChannel(
            manager = manager,
            channelId = MessageAlarmChannelId,
            channelName = "Сообщения (сигнал)",
            soundOption = NotificationSoundOption.Alarm
        )
        ensureMessageChannel(
            manager = manager,
            channelId = MessageSilentChannelId,
            channelName = "Сообщения (без звука)",
            soundOption = NotificationSoundOption.Silent
        )

        if (manager.getNotificationChannel(UpdatesChannelId) == null) {
            manager.createNotificationChannel(
                NotificationChannel(
                    UpdatesChannelId,
                    "Обновления",
                    NotificationManager.IMPORTANCE_HIGH
                ).apply {
                    description = "Уведомления о новых версиях приложения."
                    setSound(
                        AndroidMessageNotificationSound.resolveUri(NotificationSoundOption.Default),
                        AndroidMessageNotificationSound.resolveAudioAttributes(NotificationSoundOption.Default)
                    )
                    enableVibration(true)
                }
            )
        }

        if (manager.getNotificationChannel(CallsChannelId) == null) {
            manager.createNotificationChannel(
                NotificationChannel(
                    CallsChannelId,
                    "Звонки",
                    NotificationManager.IMPORTANCE_HIGH
                ).apply {
                    description = "Уведомления о входящих звонках."
                    setSound(
                        AndroidMessageNotificationSound.resolveUri(NotificationSoundOption.Ringtone),
                        AndroidMessageNotificationSound.resolveAudioAttributes(NotificationSoundOption.Ringtone)
                    )
                    enableVibration(true)
                }
            )
        }
    }

    private fun ensureMessageChannel(
        manager: NotificationManager,
        channelId: String,
        channelName: String,
        soundOption: NotificationSoundOption
    ) {
        if (manager.getNotificationChannel(channelId) != null) {
            return
        }

        manager.createNotificationChannel(
            NotificationChannel(
                channelId,
                channelName,
                NotificationManager.IMPORTANCE_HIGH
            ).apply {
                description = "Уведомления о новых сообщениях."
                setSound(
                    AndroidMessageNotificationSound.resolveUri(soundOption),
                    AndroidMessageNotificationSound.resolveAudioAttributes(soundOption)
                )
                enableVibration(soundOption != NotificationSoundOption.Silent)
            }
        )
    }

    private fun tryGetExistingApp(): FirebaseApp? =
        runCatching { FirebaseApp.getInstance() }.getOrNull()
}
