package app.furmeet.events.system.notification

import android.Manifest
import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import app.furmeet.events.system.MainActivity
import app.furmeet.events.bff.R
import app.furmeet.events.system.helper.*
import app.furmeet.events.system.schedule.EventActivity
import app.furmeet.events.system.schedule.managers.RemoteAssetsHolder
import app.furmeet.events.system.schedule.managers.ScheduleManagerGetter
import java.util.*

class NotificationFirer {
    fun fire(contextWithSystemLanguage: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
            ActivityCompat.checkSelfPermission(
                contextWithSystemLanguage,
                Manifest.permission.POST_NOTIFICATIONS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            return
        }
        RemoteAssetsHolder.ensureIsBuilt(contextWithSystemLanguage)
        val context =
            nullAndLogIfException { LocaleManager(contextWithSystemLanguage).patchedContext }
                ?: contextWithSystemLanguage
        resourcesAliased = context.resources
        nullAndLogIfException {
            val scheduleManager = ScheduleManagerGetter[context]
            val timeForNotification =
                scheduleManager.convention.notificationFireMinutesBefore * 60 * 1000.toLong() + scheduleManager.conventionTime.timeInMillis
            val dateForNotification =
                GregorianCalendar().apply { timeInMillis = timeForNotification }
            val toNotify =
                scheduleManager.attendeeFavorites
                    .toList()
                    .filter { dateForNotification in it.timeRange }
                    .filterNot { it.notified }
                    .sortedBy { -it.timeRange.start.timeInMillis }
            val notificationManager = NotificationManagerCompat.from(context)
            toNotify.withIndex().forEach {
                val builder =
                    context.notificationBuilderCompat(R.string.defaultNotificationChannel, true)
                        .setDefaults(Notification.DEFAULT_ALL)
                        .setSmallIcon(R.drawable.ic_notificacao)
                        .setContentTitle(it.value.getString())
                        .setContentText(it.value.getSecondaryString())
                        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                        .setTimeoutAfter(
                            it.value.timeRange.let { cal ->
                                cal.finish.timeInMillis - cal.start.timeInMillis
                            }
                        )
                        .setWhen(it.value.timeRange.start.timeInMillis)
                        .setShowWhen(true)
                        .setContentIntent(
                            PendingIntent.getActivity(
                                context,
                                it.value.getString().hashCode(),
                                Intent(context, EventActivity::class.java).apply {
                                    flags =
                                        Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
                                    putExtra("favorite", it.value)
                                    putExtra("fromNotification", true)
                                },
                                0
                            )
                        )
                notificationManager.notify(
                    ((timeForNotification + it.index) % Int.MAX_VALUE).toInt(),
                    builder.build()
                )
            }
            toNotify.forEach {
                it.notified = true
            }
        }
        ///////////////////////
        nullAndLogIfException {
            val notificationManager = NotificationManagerCompat.from(context)
            val scheduleManager = ScheduleManagerGetter[context]
            val announcements = scheduleManager.unreadAnnouncements
            scheduleManager.setAnnouncementsRead()
            announcements.firstOrNull()?.let { announcement ->
                val title = announcement.title[context.runtimeLanguage]
                val body = announcement.body[context.runtimeLanguage]
                val link = announcement.link?.get(context.runtimeLanguage)
                val nt = context.notificationBuilderCompat(
                    R.string.announcementsNotificationChannel,
                    true
                )
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setSmallIcon(R.drawable.ic_notificacao)
                    .setContentTitle(title)
                    .setContentText(body)
                    .let { builder ->
                        if (link == null)
                            builder.setContentIntent(
                                PendingIntent.getActivity(
                                    context,
                                    384,
                                    Intent(context, MainActivity::class.java),
                                    0
                                )
                            )
                        else
                            builder.setContentIntent(
                                PendingIntent.getActivity(
                                    context,
                                    announcement.uuid.hashCode(),
                                    Intent(Intent.ACTION_VIEW, Uri.parse(link)),
                                    0
                                )
                            )
                    }
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                notificationManager.notify(
                    announcement.hashCode(), nt.build()
                )
            }

        }
    }
}