import Foundation import UserNotifications /// Schedules local repeating notifications for Gassi-Zeiten so reminders work /// even when the app is offline. One UNCalendarNotificationTrigger per weekday. @MainActor enum GassiZeitenScheduler { static func reschedule(_ z: GassiZeit) async { cancel(forId: z.id) guard z.aktiv != 0 else { return } let parts = z.uhrzeit.split(separator: ":") guard parts.count == 2, let h = Int(parts[0]), let m = Int(parts[1]) else { return } let content = UNMutableNotificationContent() content.title = "Gassi-Zeit" content.body = z.notiz?.isEmpty == false ? z.notiz! : "Zeit für deine Gassi-Runde." content.sound = .default let center = UNUserNotificationCenter.current() for wt in z.wochentage { let weekday = weekdayNumber(for: wt) guard weekday > 0 else { continue } var comps = DateComponents() comps.weekday = weekday comps.hour = h comps.minute = m let trigger = UNCalendarNotificationTrigger(dateMatching: comps, repeats: true) let request = UNNotificationRequest( identifier: "gz-\(z.id)-\(weekday)", content: content, trigger: trigger ) try? await center.add(request) } } static func cancel(forId id: Int) { let ids = (1...7).map { "gz-\(id)-\($0)" } UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ids) } private static func weekdayNumber(for code: String) -> Int { switch code.lowercased() { case "so": return 1 case "mo": return 2 case "di": return 3 case "mi": return 4 case "do": return 5 case "fr": return 6 case "sa": return 7 default: return 0 } } }