package es.freetimelab.pluriwave

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class PluriWaveAlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val alarmId = intent.getStringExtra(EXTRA_ALARM_ID) ?: return
        val title = intent.getStringExtra(EXTRA_ALARM_TITLE) ?: "PluriWave"

        when (intent.action) {
            ACTION_FIRE -> {
                val launch = Intent(context, MainActivity::class.java).apply {
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                    putExtra(EXTRA_ALARM_ID, alarmId)
                    putExtra(EXTRA_ALARM_TITLE, title)
                    putExtra(EXTRA_ALARM_ACTION, ACTION_FIRE)
                }
                showFireNotification(context, alarmId, title, launch)
                context.startActivity(launch)
            }
            ACTION_PRE_NOTICE -> {
                showPreNoticeNotification(context, alarmId, title)
            }
            ACTION_SKIP_NEXT -> {
                NotificationManagerCompat.from(context).cancel(notificationIdForAlarm(alarmId))
                val launch = Intent(context, MainActivity::class.java).apply {
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                    putExtra(EXTRA_ALARM_ID, alarmId)
                    putExtra(EXTRA_ALARM_TITLE, title)
                    putExtra(EXTRA_ALARM_ACTION, ACTION_SKIP_NEXT)
                }
                context.startActivity(launch)
            }
        }
    }

    private fun showFireNotification(
        context: Context,
        alarmId: String,
        title: String,
        launch: Intent
    ) {
        ensureFireChannel(context)
        val fullScreenIntent = PendingIntent.getActivity(
            context,
            requestCode(alarmId, 10),
            launch,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        val notification = NotificationCompat.Builder(context, FIRE_CHANNEL_ID)
            .setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
            .setContentTitle("Alarma PluriWave")
            .setContentText(title)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setOngoing(true)
            .setAutoCancel(false)
            .setContentIntent(fullScreenIntent)
            .setFullScreenIntent(fullScreenIntent, true)
            .build()

        try {
            NotificationManagerCompat.from(context).notify(
                fireNotificationIdForAlarm(alarmId),
                notification,
            )
        } catch (_: SecurityException) {
        }
    }

    private fun showPreNoticeNotification(context: Context, alarmId: String, title: String) {
        ensureChannel(context)

        val openAppIntent = PendingIntent.getActivity(
            context,
            requestCode(alarmId, 1),
            Intent(context, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                putExtra(EXTRA_ALARM_ID, alarmId)
                putExtra(EXTRA_ALARM_TITLE, title)
                putExtra(EXTRA_ALARM_ACTION, ACTION_PRE_NOTICE)
            },
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val skipNextIntent = PendingIntent.getBroadcast(
            context,
            requestCode(alarmId, 2),
            Intent(context, PluriWaveAlarmReceiver::class.java).apply {
                action = ACTION_SKIP_NEXT
                putExtra(EXTRA_ALARM_ID, alarmId)
                putExtra(EXTRA_ALARM_TITLE, title)
            },
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        val notification = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setContentTitle(title)
            .setContentText("Empieza en 30 minutos")
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setCategory(NotificationCompat.CATEGORY_REMINDER)
            .setSilent(true)
            .setAutoCancel(true)
            .setContentIntent(openAppIntent)
            .addAction(0, "Omitir siguiente", skipNextIntent)
            .build()

        NotificationManagerCompat.from(context).notify(notificationIdForAlarm(alarmId), notification)
    }

    private fun ensureFireChannel(context: Context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val existing = manager.getNotificationChannel(FIRE_CHANNEL_ID)
        if (existing != null) return

        val channel = NotificationChannel(
            FIRE_CHANNEL_ID,
            "Alarmas sonando",
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "Pantalla urgente cuando una alarma musical debe sonar"
            enableVibration(true)
        }
        manager.createNotificationChannel(channel)
    }

    private fun ensureChannel(context: Context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
        val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val existing = manager.getNotificationChannel(CHANNEL_ID)
        if (existing != null) return

        val channel = NotificationChannel(
            CHANNEL_ID,
            "Preavisos de alarmas",
            NotificationManager.IMPORTANCE_LOW
        ).apply {
            description = "Notificaciones silenciosas 30 minutos antes de la alarma"
            setSound(null, null)
            enableVibration(false)
        }
        manager.createNotificationChannel(channel)
    }

    private fun requestCode(id: String, slot: Int): Int = 47 * id.hashCode() + slot

    companion object {
        const val CHANNEL_ID = "pluriwave_alarm_pre_notice"
        const val FIRE_CHANNEL_ID = "pluriwave_alarm_fire"
        const val ACTION_FIRE = "es.freetimelab.pluriwave.alarm.FIRE"
        const val ACTION_PRE_NOTICE = "es.freetimelab.pluriwave.alarm.PRE_NOTICE"
        const val ACTION_SKIP_NEXT = "es.freetimelab.pluriwave.alarm.SKIP_NEXT"
        const val EXTRA_ALARM_ID = "alarmId"
        const val EXTRA_ALARM_TITLE = "alarmTitle"
        const val EXTRA_ALARM_ACTION = "alarmAction"

        fun notificationIdForAlarm(alarmId: String): Int = 53 * alarmId.hashCode() + 7
        fun fireNotificationIdForAlarm(alarmId: String): Int = 59 * alarmId.hashCode() + 9
    }
}
