From 77a85a03586a9424801c8891dad8deb717912985 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Wed, 29 Oct 2025 04:19:41 +0000 Subject: [PATCH] refactor(android): extract daily reminder logic to DailyReminderManager Extracted daily reminder functionality from DailyNotificationPlugin into a dedicated DailyReminderManager class to reduce the plugin's size and effortsify responsibilities. Changes: - Created DailyReminderManager class (405 lines) for reminder CRUD - Created DailyReminderInfo data class (moved from inner class) - Delegated reminder methods to the manager - Removed duplicate helper methods from plugin - Added ensureReminderManagerInitialized() helper Impact: - Reduced DailyNotificationPlugin from 2639 to 2430 lines (209 lines) - Clear separation of concerns - Easier to test and maintain reminder functionality - Follows existing manager pattern (PermissionManager, ChannelManager, etc.) All public API methods remain unchanged - this is purely an internal refactoring. --- .../DailyNotificationPlugin.java | 312 +++----------- .../dailynotification/DailyReminderInfo.java | 31 ++ .../DailyReminderManager.java | 403 ++++++++++++++++++ 3 files changed, 486 insertions(+), 260 deletions(-) create mode 100644 android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderInfo.java create mode 100644 android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderManager.java diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java index 8031be6..fed73b3 100644 --- a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java @@ -106,6 +106,9 @@ public class DailyNotificationPlugin extends Plugin { private DailyNotificationJWTManager jwtManager; private EnhancedDailyNotificationFetcher enhancedFetcher; + // Daily reminder management + private DailyReminderManager reminderManager; + /** * Initialize the plugin and create notification channel */ @@ -141,6 +144,7 @@ public class DailyNotificationPlugin extends Plugin { scheduler = new DailyNotificationScheduler(getContext(), alarmManager); fetcher = new DailyNotificationFetcher(getContext(), storage, roomStorage); channelManager = new ChannelManager(getContext()); + reminderManager = new DailyReminderManager(getContext(), scheduler); // Ensure notification channel exists and is properly configured if (!channelManager.ensureChannelExists()) { @@ -2266,18 +2270,28 @@ public class DailyNotificationPlugin extends Plugin { } } - // Static Daily Reminder Methods + // Daily Reminder Methods + + /** + * Ensure reminder manager is initialized + */ + private void ensureReminderManagerInitialized() { + if (reminderManager == null) { + if (scheduler == null) { + alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); + scheduler = new DailyNotificationScheduler(getContext(), alarmManager); + } + reminderManager = new DailyReminderManager(getContext(), scheduler); + } + } + @PluginMethod public void scheduleDailyReminder(PluginCall call) { try { Log.d(TAG, "Scheduling daily reminder"); - // Ensure scheduler is initialized - if (scheduler == null) { - Log.w(TAG, "DN|SCHEDULER_NULL initializing_scheduler"); - alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); - scheduler = new DailyNotificationScheduler(getContext(), alarmManager); - } + // Ensure reminder manager is initialized + ensureReminderManagerInitialized(); // Extract reminder options String id = call.getString("id"); @@ -2296,49 +2310,10 @@ public class DailyNotificationPlugin extends Plugin { return; } - // Parse time (HH:mm format) - String[] timeParts = time.split(":"); - if (timeParts.length != 2) { - call.reject("Invalid time format. Use HH:mm (e.g., 09:00)"); - return; - } - - int hour = Integer.parseInt(timeParts[0]); - int minute = Integer.parseInt(timeParts[1]); - - if (hour < 0 || hour > 23 || minute < 0 || minute > 59) { - call.reject("Invalid time values. Hour must be 0-23, minute must be 0-59"); - return; - } - - // Create reminder content - NotificationContent reminderContent = new NotificationContent(); - reminderContent.setId("reminder_" + id); // Prefix to identify as reminder - reminderContent.setTitle(title); - reminderContent.setBody(body); - reminderContent.setSound(sound); - reminderContent.setPriority(priority); - // fetchedAt is set in constructor, no need to set it again - - // Calculate next trigger time - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.HOUR_OF_DAY, hour); - calendar.set(Calendar.MINUTE, minute); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - - // If time has passed today, schedule for tomorrow - if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { - calendar.add(Calendar.DAY_OF_MONTH, 1); - } - - reminderContent.setScheduledTime(calendar.getTimeInMillis()); - - // Store reminder in database - storeReminderInDatabase(id, title, body, time, sound, vibration, priority, repeatDaily, timezone); - - // Schedule the notification - boolean scheduled = scheduler.scheduleNotification(reminderContent); + // Delegate to reminder manager + boolean scheduled = reminderManager.scheduleReminder(id, title, body, time, + sound, vibration, priority, + repeatDaily, timezone); if (scheduled) { Log.i(TAG, "Daily reminder scheduled successfully: " + id); @@ -2358,12 +2333,8 @@ public class DailyNotificationPlugin extends Plugin { try { Log.d(TAG, "Cancelling daily reminder"); - // Ensure scheduler is initialized - if (scheduler == null) { - Log.w(TAG, "DN|SCHEDULER_NULL initializing_scheduler"); - alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); - scheduler = new DailyNotificationScheduler(getContext(), alarmManager); - } + // Ensure reminder manager is initialized + ensureReminderManagerInitialized(); String reminderId = call.getString("reminderId"); if (reminderId == null) { @@ -2371,14 +2342,15 @@ public class DailyNotificationPlugin extends Plugin { return; } - // Cancel the scheduled notification (use prefixed ID) - scheduler.cancelNotification("reminder_" + reminderId); - - // Remove from database - removeReminderFromDatabase(reminderId); + // Delegate to reminder manager + boolean cancelled = reminderManager.cancelReminder(reminderId); - Log.i(TAG, "Daily reminder cancelled: " + reminderId); - call.resolve(); + if (cancelled) { + Log.i(TAG, "Daily reminder cancelled: " + reminderId); + call.resolve(); + } else { + call.reject("Failed to cancel daily reminder"); + } } catch (Exception e) { Log.e(TAG, "Error cancelling daily reminder", e); @@ -2391,8 +2363,11 @@ public class DailyNotificationPlugin extends Plugin { try { Log.d(TAG, "Getting scheduled reminders"); - // Get reminders from database - java.util.List reminders = getRemindersFromDatabase(); + // Ensure reminder manager is initialized + ensureReminderManagerInitialized(); + + // Delegate to reminder manager + java.util.List reminders = reminderManager.getReminders(); // Convert to JSObject array JSObject result = new JSObject(); @@ -2411,12 +2386,8 @@ public class DailyNotificationPlugin extends Plugin { try { Log.d(TAG, "Updating daily reminder"); - // Ensure scheduler is initialized - if (scheduler == null) { - Log.w(TAG, "DN|SCHEDULER_NULL initializing_scheduler"); - alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); - scheduler = new DailyNotificationScheduler(getContext(), alarmManager); - } + // Ensure reminder manager is initialized + ensureReminderManagerInitialized(); String reminderId = call.getString("reminderId"); if (reminderId == null) { @@ -2438,201 +2409,22 @@ public class DailyNotificationPlugin extends Plugin { scheduler.cancelNotification("reminder_" + reminderId); // Update in database - updateReminderInDatabase(reminderId, title, body, time, sound, vibration, priority, repeatDaily, timezone); - - // Reschedule with new settings - if (title != null && body != null && time != null) { - // Create new reminder content - NotificationContent reminderContent = new NotificationContent(); - reminderContent.setId("reminder_" + reminderId); // Prefix to identify as reminder - reminderContent.setTitle(title); - reminderContent.setBody(body); - reminderContent.setSound(sound != null ? sound : true); - reminderContent.setPriority(priority != null ? priority : "normal"); - // fetchedAt is set in constructor, no need to set it again - - // Calculate next trigger time - String[] timeParts = time.split(":"); - int hour = Integer.parseInt(timeParts[0]); - int minute = Integer.parseInt(timeParts[1]); - - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.HOUR_OF_DAY, hour); - calendar.set(Calendar.MINUTE, minute); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - - if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { - calendar.add(Calendar.DAY_OF_MONTH, 1); - } - - reminderContent.setScheduledTime(calendar.getTimeInMillis()); - - // Schedule the updated notification - boolean scheduled = scheduler.scheduleNotification(reminderContent); - - if (!scheduled) { - call.reject("Failed to reschedule updated reminder"); - return; - } + // Delegate to reminder manager + boolean updated = reminderManager.updateReminder(reminderId, title, body, time, + sound, vibration, priority, + repeatDaily, timezone); + + if (updated) { + Log.i(TAG, "Daily reminder updated: " + reminderId); + call.resolve(); + } else { + call.reject("Failed to update daily reminder"); } - Log.i(TAG, "Daily reminder updated: " + reminderId); - call.resolve(); - } catch (Exception e) { Log.e(TAG, "Error updating daily reminder", e); call.reject("Daily reminder update failed: " + e.getMessage()); } } - // Helper methods for reminder database operations - private void storeReminderInDatabase(String id, String title, String body, String time, - boolean sound, boolean vibration, String priority, - boolean repeatDaily, String timezone) { - try { - SharedPreferences prefs = getContext().getSharedPreferences("daily_reminders", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - editor.putString(id + "_title", title); - editor.putString(id + "_body", body); - editor.putString(id + "_time", time); - editor.putBoolean(id + "_sound", sound); - editor.putBoolean(id + "_vibration", vibration); - editor.putString(id + "_priority", priority); - editor.putBoolean(id + "_repeatDaily", repeatDaily); - editor.putString(id + "_timezone", timezone); - editor.putLong(id + "_createdAt", System.currentTimeMillis()); - editor.putBoolean(id + "_isScheduled", true); - - editor.apply(); - Log.d(TAG, "Reminder stored in database: " + id); - - } catch (Exception e) { - Log.e(TAG, "Error storing reminder in database", e); - } - } - - private void removeReminderFromDatabase(String id) { - try { - SharedPreferences prefs = getContext().getSharedPreferences("daily_reminders", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - editor.remove(id + "_title"); - editor.remove(id + "_body"); - editor.remove(id + "_time"); - editor.remove(id + "_sound"); - editor.remove(id + "_vibration"); - editor.remove(id + "_priority"); - editor.remove(id + "_repeatDaily"); - editor.remove(id + "_timezone"); - editor.remove(id + "_createdAt"); - editor.remove(id + "_isScheduled"); - editor.remove(id + "_lastTriggered"); - - editor.apply(); - Log.d(TAG, "Reminder removed from database: " + id); - - } catch (Exception e) { - Log.e(TAG, "Error removing reminder from database", e); - } - } - - private java.util.List getRemindersFromDatabase() { - java.util.List reminders = new java.util.ArrayList<>(); - - try { - SharedPreferences prefs = getContext().getSharedPreferences("daily_reminders", Context.MODE_PRIVATE); - java.util.Map allEntries = prefs.getAll(); - - java.util.Set reminderIds = new java.util.HashSet<>(); - for (String key : allEntries.keySet()) { - if (key.endsWith("_title")) { - String id = key.substring(0, key.length() - 6); // Remove "_title" - reminderIds.add(id); - } - } - - for (String id : reminderIds) { - DailyReminderInfo reminder = new DailyReminderInfo(); - reminder.id = id; - reminder.title = prefs.getString(id + "_title", ""); - reminder.body = prefs.getString(id + "_body", ""); - reminder.time = prefs.getString(id + "_time", ""); - reminder.sound = prefs.getBoolean(id + "_sound", true); - reminder.vibration = prefs.getBoolean(id + "_vibration", true); - reminder.priority = prefs.getString(id + "_priority", "normal"); - reminder.repeatDaily = prefs.getBoolean(id + "_repeatDaily", true); - reminder.timezone = prefs.getString(id + "_timezone", null); - reminder.isScheduled = prefs.getBoolean(id + "_isScheduled", false); - reminder.createdAt = prefs.getLong(id + "_createdAt", 0); - reminder.lastTriggered = prefs.getLong(id + "_lastTriggered", 0); - - // Calculate next trigger time - String[] timeParts = reminder.time.split(":"); - int hour = Integer.parseInt(timeParts[0]); - int minute = Integer.parseInt(timeParts[1]); - - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.HOUR_OF_DAY, hour); - calendar.set(Calendar.MINUTE, minute); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - - if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { - calendar.add(Calendar.DAY_OF_MONTH, 1); - } - - reminder.nextTriggerTime = calendar.getTimeInMillis(); - - reminders.add(reminder); - } - - } catch (Exception e) { - Log.e(TAG, "Error getting reminders from database", e); - } - - return reminders; - } - - private void updateReminderInDatabase(String id, String title, String body, String time, - Boolean sound, Boolean vibration, String priority, - Boolean repeatDaily, String timezone) { - try { - SharedPreferences prefs = getContext().getSharedPreferences("daily_reminders", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - if (title != null) editor.putString(id + "_title", title); - if (body != null) editor.putString(id + "_body", body); - if (time != null) editor.putString(id + "_time", time); - if (sound != null) editor.putBoolean(id + "_sound", sound); - if (vibration != null) editor.putBoolean(id + "_vibration", vibration); - if (priority != null) editor.putString(id + "_priority", priority); - if (repeatDaily != null) editor.putBoolean(id + "_repeatDaily", repeatDaily); - if (timezone != null) editor.putString(id + "_timezone", timezone); - - editor.apply(); - Log.d(TAG, "Reminder updated in database: " + id); - - } catch (Exception e) { - Log.e(TAG, "Error updating reminder in database", e); - } - } - - // Data class for reminder info - public static class DailyReminderInfo { - public String id; - public String title; - public String body; - public String time; - public boolean sound; - public boolean vibration; - public String priority; - public boolean repeatDaily; - public String timezone; - public boolean isScheduled; - public long nextTriggerTime; - public long createdAt; - public long lastTriggered; - } } diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderInfo.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderInfo.java new file mode 100644 index 0000000..a040000 --- /dev/null +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderInfo.java @@ -0,0 +1,31 @@ +/** + * DailyReminderInfo.java + * + * Data class representing a daily reminder configuration + * and its current state. + * + * @author Matthew Raymer + * @version 1.0.0 + */ + +package com.timesafari.dailynotification; + +/** + * Information about a scheduled daily reminder + */ +public class DailyReminderInfo { + public String id; + public String title; + public String body; + public String time; + public boolean sound; + public boolean vibration; + public String priority; + public boolean repeatDaily; + public String timezone; + public boolean isScheduled; + public long nextTriggerTime; + public long createdAt; + public long lastTriggered; +} + diff --git a/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderManager.java b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderManager.java new file mode 100644 index 0000000..592ce79 --- /dev/null +++ b/android/plugin/src/main/java/com/timesafari/dailynotification/DailyReminderManager.java @@ -0,0 +1,403 @@ +/** + * DailyReminderManager.java + * + * Manages daily reminder functionality including creation, updates, + * cancellation, and retrieval. Handles persistent storage and + * notification scheduling. + * + * @author Matthew Raymer + * @version 1.0.0 + */ + +package com.timesafari.dailynotification; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +import com.getcapacitor.JSObject; +import com.getcapacitor.PluginCall; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Manager class for daily reminder operations + * + * Responsibilities: + * - Schedule daily reminders + * - Cancel scheduled reminders + * - Update existing reminders + * - Retrieve reminder list + * - Manage persistent storage + */ +public class DailyReminderManager { + private static final String TAG = "DailyReminderManager"; + private static final String PREF_NAME = "daily_reminders"; + private static final String REMINDER_ID_PREFIX = "reminder_"; + + private final Context context; + private final DailyNotificationScheduler scheduler; + + /** + * Initialize the DailyReminderManager + * + * @param context Android context + * @param scheduler Notification scheduler instance + */ + public DailyReminderManager(Context context, + DailyNotificationScheduler scheduler) { + this.context = context; + this.scheduler = scheduler; + Log.d(TAG, "DailyReminderManager initialized"); + } + + /** + * Schedule a new daily reminder + * + * @param id Unique identifier for the reminder + * @param title Reminder title + * @param body Reminder body text + * @param time Time in HH:mm format + * @param sound Whether to play sound + * @param vibration Whether to vibrate + * @param priority Notification priority + * @param repeatDaily Whether to repeat daily + * @param timezone Optional timezone string + * @return true if scheduled successfully + */ + public boolean scheduleReminder(String id, String title, String body, + String time, boolean sound, + boolean vibration, String priority, + boolean repeatDaily, String timezone) { + try { + Log.d(TAG, "Scheduling daily reminder: " + id); + + // Validate time format + String[] timeParts = time.split(":"); + if (timeParts.length != 2) { + Log.e(TAG, "Invalid time format: " + time); + return false; + } + + int hour = Integer.parseInt(timeParts[0]); + int minute = Integer.parseInt(timeParts[1]); + + if (hour < 0 || hour > 23 || minute < 0 || minute > 59) { + Log.e(TAG, "Invalid time values"); + return false; + } + + // Create reminder content + NotificationContent reminderContent = new NotificationContent(); + reminderContent.setId(REMINDER_ID_PREFIX + id); + reminderContent.setTitle(title); + reminderContent.setBody(body); + reminderContent.setSound(sound); + reminderContent.setPriority(priority); + + // Calculate next trigger time + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + // If time has passed today, schedule for tomorrow + if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + + reminderContent.setScheduledTime(calendar.getTimeInMillis()); + + // Store reminder in database + storeReminderInDatabase(id, title, body, time, sound, + vibration, priority, repeatDaily, timezone); + + // Schedule the notification + boolean scheduled = scheduler.scheduleNotification(reminderContent); + + if (scheduled) { + Log.i(TAG, "Daily reminder scheduled successfully: " + id); + } else { + Log.e(TAG, "Failed to schedule daily reminder: " + id); + } + + return scheduled; + + } catch (Exception e) { + Log.e(TAG, "Error scheduling daily reminder", e); + return false; + } + } + + /** + * Cancel a scheduled reminder + * + * @param reminderId Reminder ID to cancel + * @return true if cancelled successfully + */ + public boolean cancelReminder(String reminderId) { + try { + Log.d(TAG, "Cancelling daily reminder: " + reminderId); + + // Cancel the scheduled notification + scheduler.cancelNotification(REMINDER_ID_PREFIX + reminderId); + + // Remove from database + removeReminderFromDatabase(reminderId); + + Log.i(TAG, "Daily reminder cancelled: " + reminderId); + return true; + + } catch (Exception e) { + Log.e(TAG, "Error cancelling daily reminder", e); + return false; + } + } + + /** + * Update an existing reminder + * + * @param reminderId Reminder ID to update + * @param title Optional new title + * @param body Optional new body + * @param time Optional new time in HH:mm format + * @param sound Optional new sound setting + * @param vibration Optional new vibration setting + * @param priority Optional new priority + * @param repeatDaily Optional new repeat setting + * @param timezone Optional new timezone + * @return true if updated successfully + */ + public boolean updateReminder(String reminderId, String title, + String body, String time, Boolean sound, + Boolean vibration, String priority, + Boolean repeatDaily, String timezone) { + try { + Log.d(TAG, "Updating daily reminder: " + reminderId); + + // Cancel existing reminder + scheduler.cancelNotification(REMINDER_ID_PREFIX + reminderId); + + // Update in database + updateReminderInDatabase(reminderId, title, body, time, + sound, vibration, priority, + repeatDaily, timezone); + + // Reschedule with new settings + if (title != null && body != null && time != null) { + // Parse time + String[] timeParts = time.split(":"); + int hour = Integer.parseInt(timeParts[0]); + int minute = Integer.parseInt(timeParts[1]); + + // Create new reminder content + NotificationContent reminderContent = new NotificationContent(); + reminderContent.setId(REMINDER_ID_PREFIX + reminderId); + reminderContent.setTitle(title); + reminderContent.setBody(body); + reminderContent.setSound(sound != null ? sound : true); + reminderContent.setPriority(priority != null ? priority : "normal"); + + // Calculate next trigger time + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + + reminderContent.setScheduledTime(calendar.getTimeInMillis()); + + // Schedule the updated notification + boolean scheduled = scheduler.scheduleNotification(reminderContent); + + if (!scheduled) { + Log.e(TAG, "Failed to reschedule updated reminder"); + return false; + } + } + + Log.i(TAG, "Daily reminder updated: " + reminderId); + return true; + + } catch (Exception e) { + Log.e(TAG, "Error updating daily reminder", e); + return false; + } + } + + /** + * Get all scheduled reminders + * + * @return List of DailyReminderInfo objects + */ + public List getReminders() { + try { + Log.d(TAG, "Getting scheduled reminders"); + return getRemindersFromDatabase(); + } catch (Exception e) { + Log.e(TAG, "Error getting reminders from database", e); + return new ArrayList<>(); + } + } + + /** + * Store reminder in SharedPreferences database + */ + private void storeReminderInDatabase(String id, String title, String body, + String time, boolean sound, + boolean vibration, String priority, + boolean repeatDaily, String timezone) { + try { + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + + editor.putString(id + "_title", title); + editor.putString(id + "_body", body); + editor.putString(id + "_time", time); + editor.putBoolean(id + "_sound", sound); + editor.putBoolean(id + "_vibration", vibration); + editor.putString(id + "_priority", priority); + editor.putBoolean(id + "_repeatDaily", repeatDaily); + editor.putString(id + "_timezone", timezone); + editor.putLong(id + "_createdAt", System.currentTimeMillis()); + editor.putBoolean(id + "_isScheduled", true); + + editor.apply(); + Log.d(TAG, "Reminder stored in database: " + id); + + } catch (Exception e) { + Log.e(TAG, "Error storing reminder in database", e); + } + } + + /** + * Remove reminder from SharedPreferences database + */ + private void removeReminderFromDatabase(String id) { + try { + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + + editor.remove(id + "_title"); + editor.remove(id + "_body"); + editor.remove(id + "_time"); + editor.remove(id + "_sound"); + editor.remove(id + "_vibration"); + editor.remove(id + "_priority"); + editor.remove(id + "_repeatDaily"); + editor.remove(id + "_timezone"); + editor.remove(id + "_createdAt"); + editor.remove(id + "_isScheduled"); + editor.remove(id + "_lastTriggered"); + + editor.apply(); + Log.d(TAG, "Reminder removed from database: " + id); + + } catch (Exception e) { + Log.e(TAG, "Error removing reminder from database", e); + } + } + + /** + * Get reminders from SharedPreferences database + */ + private List getRemindersFromDatabase() { + List reminders = new ArrayList<>(); + + try { + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, + Context.MODE_PRIVATE); + Map allEntries = prefs.getAll(); + + Set reminderIds = new HashSet<>(); + for (String key : allEntries.keySet()) { + if (key.endsWith("_title")) { + String id = key.substring(0, key.length() - 6); // Remove "_title" + reminderIds.add(id); + } + } + + for (String id : reminderIds) { + DailyReminderInfo reminder = new DailyReminderInfo(); + reminder.id = id; + reminder.title = prefs.getString(id + "_title", ""); + reminder.body = prefs.getString(id + "_body", ""); + reminder.time = prefs.getString(id + "_time", ""); + reminder.sound = prefs.getBoolean(id + "_sound", true); + reminder.vibration = prefs.getBoolean(id + "_vibration", true); + reminder.priority = prefs.getString(id + "_priority", "normal"); + reminder.repeatDaily = prefs.getBoolean(id + "_repeatDaily", true); + reminder.timezone = prefs.getString(id + "_timezone", null); + reminder.isScheduled = prefs.getBoolean(id + "_isScheduled", false); + reminder.createdAt = prefs.getLong(id + "_createdAt", 0); + reminder.lastTriggered = prefs.getLong(id + "_lastTriggered", 0); + + // Calculate next trigger time + String[] timeParts = reminder.time.split(":"); + int hour = Integer.parseInt(timeParts[0]); + int minute = Integer.parseInt(timeParts[1]); + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + if (calendar.getTimeInMillis() <= System.currentTimeMillis()) { + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + + reminder.nextTriggerTime = calendar.getTimeInMillis(); + + reminders.add(reminder); + } + + } catch (Exception e) { + Log.e(TAG, "Error getting reminders from database", e); + } + + return reminders; + } + + /** + * Update reminder in SharedPreferences database + */ + private void updateReminderInDatabase(String id, String title, String body, + String time, Boolean sound, + Boolean vibration, String priority, + Boolean repeatDaily, String timezone) { + try { + SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + + if (title != null) editor.putString(id + "_title", title); + if (body != null) editor.putString(id + "_body", body); + if (time != null) editor.putString(id + "_time", time); + if (sound != null) editor.putBoolean(id + "_sound", sound); + if (vibration != null) editor.putBoolean(id + "_vibration", vibration); + if (priority != null) editor.putString(id + "_priority", priority); + if (repeatDaily != null) editor.putBoolean(id + "_repeatDaily", repeatDaily); + if (timezone != null) editor.putString(id + "_timezone", timezone); + + editor.apply(); + Log.d(TAG, "Reminder updated in database: " + id); + + } catch (Exception e) { + Log.e(TAG, "Error updating reminder in database", e); + } + } +} +