package com.example.smartalarm.service import android.app.AlarmManager import android.app.PendingIntent import android.content.Context import android.content.Intent import android.os.Build import com.example.smartalarm.data.model.Alarm import java.util.* class AlarmScheduler(private val context: Context) { private val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager fun scheduleAlarm(alarm: Alarm) { val intent = Intent(context, AlarmReceiver::class.java).apply { putExtra("ALARM_ID", alarm.id) putExtra("ALARM_LABEL", alarm.label) putExtra("SHAKE_TO_STOP", alarm.shakeToStop) putExtra("SHAKE_INTENSITY", alarm.shakeIntensity) putExtra("GRADUAL_MODE", alarm.gradualMode) putExtra("VIBRATE", alarm.vibrate) putExtra("RINGTONE_URI", alarm.ringtoneUri) } val pendingIntent = PendingIntent.getBroadcast( context, alarm.id.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) val calendar = getAlarmCalendar(alarm) try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (alarmManager.canScheduleExactAlarms()) { alarmManager.setAlarmClock( AlarmManager.AlarmClockInfo(calendar.timeInMillis, pendingIntent), pendingIntent ) } else { // Fallback to inexact alarm alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent ) } } else { alarmManager.setAlarmClock( AlarmManager.AlarmClockInfo(calendar.timeInMillis, pendingIntent), pendingIntent ) } } catch (e: Exception) { e.printStackTrace() // Final fallback alarmManager.set( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent ) } } fun cancelAlarm(alarmId: Long) { val intent = Intent(context, AlarmReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast( context, alarmId.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) alarmManager.cancel(pendingIntent) } private fun getAlarmCalendar(alarm: Alarm): Calendar { val calendar = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, alarm.hour) set(Calendar.MINUTE, alarm.minute) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } // If alarm time has passed today, schedule for tomorrow if (calendar.timeInMillis <= System.currentTimeMillis()) { calendar.add(Calendar.DAY_OF_MONTH, 1) } return calendar } }