import Foundation
import UserNotifications

final class MeetingReminderManager: NSObject {

    static let shared = MeetingReminderManager()

    private let center = UNUserNotificationCenter.current()

    private struct Interval {
        let offset: TimeInterval
        let label: String
        let suffix: String
        let isEnabled: () -> Bool
    }

    private var intervals: [Interval] {
        [
            Interval(offset: 86400, label: "Starts in 1 day", suffix: "1d", isEnabled: { ReminderPreferences.remind1Day }),
            Interval(offset: 43200, label: "Starts in 12 hours", suffix: "12h", isEnabled: { ReminderPreferences.remind12Hours }),
            Interval(offset: 3600, label: "Starts in 1 hour", suffix: "1h", isEnabled: { ReminderPreferences.remind1Hour })
        ]
    }

    private override init() { super.init() }

    func requestPermissionIfNeeded(completion: ((Bool) -> Void)? = nil) {
        center.getNotificationSettings { [weak self] settings in
            guard let self else { return }
            switch settings.authorizationStatus {
            case .notDetermined:
                self.center.requestAuthorization(options: [.alert, .sound]) { granted, _ in
                    DispatchQueue.main.async { completion?(granted) }
                }
            case .authorized, .provisional, .ephemeral:
                DispatchQueue.main.async { completion?(true) }
            default:
                DispatchQueue.main.async { completion?(false) }
            }
        }
    }

    func scheduleReminders(for meetings: [ScheduledMeeting]) {
        guard ReminderPreferences.remindersEnabled else {
            cancelAllReminders()
            return
        }

        let now = Date()
        var requests: [UNNotificationRequest] = []

        for meeting in meetings {
            let title = meeting.title.trimmingCharacters(in: .whitespacesAndNewlines)
            guard !title.isEmpty else { continue }

            for interval in intervals where interval.isEnabled() {
                let triggerDate = meeting.startDate.addingTimeInterval(-interval.offset)
                guard triggerDate > now else { continue }

                let content = UNMutableNotificationContent()
                content.title = "📅 \(title)"
                content.subtitle = meeting.subtitle ?? "Google Meet"
                content.body = interval.label
                content.sound = .default

                let components = Calendar.current.dateComponents(
                    [.year, .month, .day, .hour, .minute, .second],
                    from: triggerDate
                )
                let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
                let id = notificationID(meetingID: meeting.id, suffix: interval.suffix)
                requests.append(UNNotificationRequest(identifier: id, content: content, trigger: trigger))
            }
        }

        center.removeAllPendingNotificationRequests()
        for request in requests {
            center.add(request, withCompletionHandler: nil)
        }
    }

    func cancelAllReminders() {
        center.removeAllPendingNotificationRequests()
    }

    private func notificationID(meetingID: String, suffix: String) -> String {
        "meeting.reminder.\(meetingID).\(suffix)"
    }
}
