//
//  DailyNotificationScheduleHelper.swift
//  DailyNotificationPlugin
//
//  Created by Matthew Raymer on 2025-12-23
//  Copyright © 2025 TimeSafari. All rights reserved.
//

import Foundation
import UserNotifications

/**
 * DailyNotificationScheduleHelper.swift
 * 
 * Orchestration helper for daily notification scheduling
 * 
 * This helper encapsulates complex scheduling orchestration logic that combines
 * multiple services (scheduler, storage, stateActor, background tasks).
 * Similar to Android's ScheduleHelper.kt pattern.
 * 
 * Responsibilities:
 * - Schedule daily notifications with full orchestration (cancel, clear, save, schedule, prefetch)
 * - Schedule dual notifications (background fetch + user notification)
 * - Clear rollover state
 * - Combine status from multiple sources
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 * @created 2025-12-23
 */
enum DailyNotificationScheduleHelper {
    
    /**
     * Schedule daily notification with full orchestration
     * 
     * Orchestrates:
     * 1. Cancel all existing notifications
     * 2. Clear all stored notification content
     * 3. Clear rollover state
     * 4. Save notification content (via stateActor if available)
     * 5. Schedule notification
     * 6. Schedule background fetch (5 minutes before notification)
     * 
     * @param content Notification content to schedule
     * @param scheduledTime Scheduled time in milliseconds
     * @param scheduler DailyNotificationScheduler instance
     * @param storage DailyNotificationStorage instance
     * @param stateActor DailyNotificationStateActor instance (optional, iOS 13+)
     * @param scheduleBackgroundFetch Closure to schedule background fetch
     * @return true if scheduling succeeded, false otherwise
     */
    static func scheduleDailyNotification(
        content: NotificationContent,
        scheduledTime: Int64,
        scheduler: DailyNotificationScheduler,
        storage: DailyNotificationStorage?,
        stateActor: DailyNotificationStateActor?,
        scheduleBackgroundFetch: (Int64) -> Void
    ) async -> Bool {
        // Step 1: Cancel all existing notifications
        await scheduler.cancelAllNotifications()
        
        // Step 2: Clear all stored notification content
        storage?.clearAllNotifications()
        
        // Step 3: Clear rollover state
        clearRolloverState(storage: storage)
        
        // Step 4: Save notification content (via stateActor if available, otherwise storage)
        if #available(iOS 13.0, *), let stateActor = stateActor {
            await stateActor.saveNotificationContent(content)
        } else {
            storage?.saveNotificationContent(content)
        }
        
        // Step 5: Schedule notification
        let scheduled = await scheduler.scheduleNotification(content)
        
        // Step 6: Schedule background fetch if notification was scheduled
        if scheduled {
            scheduleBackgroundFetch(scheduledTime)
        }
        
        return scheduled
    }
    
    /**
     * Schedule dual notification (background fetch + user notification)
     * 
     * Orchestrates both background fetch and user notification scheduling.
     * 
     * @param contentFetchConfig Background fetch configuration
     * @param userNotificationConfig User notification configuration
     * @param scheduleBackgroundFetch Closure to schedule background fetch
     * @param scheduleUserNotification Closure to schedule user notification
     * @throws Error if scheduling fails
     */
    static func scheduleDualNotification(
        contentFetchConfig: [String: Any],
        userNotificationConfig: [String: Any],
        scheduleBackgroundFetch: ([String: Any]) throws -> Void,
        scheduleUserNotification: ([String: Any]) throws -> Void
    ) throws {
        // Schedule both background fetch and user notification
        try scheduleBackgroundFetch(contentFetchConfig)
        try scheduleUserNotification(userNotificationConfig)
    }
    
    /**
     * Clear rollover state from storage and UserDefaults
     * 
     * Clears:
     * - Global rollover time in storage
     * - All rollover_* keys from UserDefaults
     * 
     * @param storage DailyNotificationStorage instance (optional)
     */
    static func clearRolloverState(storage: DailyNotificationStorage?) {
        // Clear global rollover time
        storage?.saveLastRolloverTime(0)
        
        // Clear per-notification rollover times from UserDefaults
        let userDefaults = UserDefaults.standard
        let allKeys = userDefaults.dictionaryRepresentation().keys
        for key in allKeys {
            if key.hasPrefix("rollover_") {
                userDefaults.removeObject(forKey: key)
            }
        }
        userDefaults.synchronize()
    }
    
    /**
     * Get health status combining multiple sources
     * 
     * Combines:
     * - Scheduler status (pending count, permission status)
     * - Storage/StateActor status (last notification)
     * 
     * @param scheduler DailyNotificationScheduler instance
     * @param storage DailyNotificationStorage instance (optional)
     * @param stateActor DailyNotificationStateActor instance (optional, iOS 13+)
     * @return Health status dictionary
     * @throws Error if scheduler not initialized
     */
    static func getHealthStatus(
        scheduler: DailyNotificationScheduler,
        storage: DailyNotificationStorage?,
        stateActor: DailyNotificationStateActor?
    ) async throws -> [String: Any] {
        // Delegate to scheduler for pending count and permission status
        let pendingCount = await scheduler.getPendingNotificationCount()
        let isEnabled = await scheduler.checkPermissionStatus() == .authorized
        
        // Delegate to stateActor if available (thread-safe), otherwise use storage directly
        let lastNotification: NotificationContent?
        if #available(iOS 13.0, *), let stateActor = stateActor {
            lastNotification = await stateActor.getLastNotification()
        } else {
            lastNotification = storage?.getLastNotification()
        }
        
        return [
            "contentFetch": [
                "isEnabled": true,
                "isScheduled": pendingCount > 0,
                "lastFetchTime": lastNotification?.fetchedAt ?? 0,
                "nextFetchTime": 0,
                "pendingFetches": pendingCount
            ],
            "userNotification": [
                "isEnabled": isEnabled,
                "isScheduled": pendingCount > 0,
                "lastNotificationTime": lastNotification?.scheduledTime ?? 0,
                "nextNotificationTime": 0,
                "pendingNotifications": pendingCount
            ],
            "relationship": [
                "isLinked": true,
                "contentAvailable": lastNotification != nil,
                "lastLinkTime": lastNotification?.fetchedAt ?? 0
            ],
            "overall": [
                "isActive": isEnabled && pendingCount > 0,
                "lastActivity": lastNotification?.scheduledTime ?? 0,
                "errorCount": 0,
                "successRate": 1.0
            ]
        ]
    }
}

