//
//  DailyNotificationBackgroundTasks.swift
//  DailyNotificationPlugin
//
//  Created by Matthew Raymer on 2025-09-22
//  Copyright © 2025 TimeSafari. All rights reserved.
//

import Foundation
import BackgroundTasks
import UserNotifications
import CoreData

/**
 * Background task handlers for iOS Daily Notification Plugin
 * Implements BGTaskScheduler handlers for content fetch and notification delivery
 * 
 * @author Matthew Raymer
 * @version 1.1.0
 * @created 2025-09-22 09:22:32 UTC
 */
extension DailyNotificationPlugin {
    
    private func handleBackgroundFetch(task: BGAppRefreshTask) {
        print("DNP-FETCH-START: Background fetch task started")
        
        task.expirationHandler = {
            print("DNP-FETCH-TIMEOUT: Background fetch task expired")
            task.setTaskCompleted(success: false)
        }
        
        Task {
            do {
                let startTime = Date()
                let content = try await performContentFetch()
                
                // Store content in Core Data
                try await storeContent(content)
                
                let duration = Date().timeIntervalSince(startTime)
                print("DNP-FETCH-SUCCESS: Content fetch completed in \(duration)s")
                
                // Fire callbacks
                try await fireCallbacks(eventType: "onFetchSuccess", payload: content)
                
                task.setTaskCompleted(success: true)
                
            } catch {
                print("DNP-FETCH-FAILURE: Content fetch failed: \(error)")
                task.setTaskCompleted(success: false)
            }
        }
    }
    
    private func handleBackgroundNotify(task: BGProcessingTask) {
        print("DNP-NOTIFY-START: Background notify task started")
        
        task.expirationHandler = {
            print("DNP-NOTIFY-TIMEOUT: Background notify task expired")
            task.setTaskCompleted(success: false)
        }
        
        Task {
            do {
                let startTime = Date()
                
                // Get latest cached content
                guard let latestContent = try await getLatestContent() else {
                    print("DNP-NOTIFY-SKIP: No cached content available")
                    task.setTaskCompleted(success: true)
                    return
                }
                
                // Check TTL
                if isContentExpired(content: latestContent) {
                    print("DNP-NOTIFY-SKIP-TTL: Content TTL expired, skipping notification")
                    try await recordHistory(kind: "notify", outcome: "skipped_ttl")
                    task.setTaskCompleted(success: true)
                    return
                }
                
                // Show notification
                try await showNotification(content: latestContent)
                
                let duration = Date().timeIntervalSince(startTime)
                print("DNP-NOTIFY-SUCCESS: Notification displayed in \(duration)s")
                
                // Fire callbacks
                try await fireCallbacks(eventType: "onNotifyDelivered", payload: latestContent)
                
                task.setTaskCompleted(success: true)
                
            } catch {
                print("DNP-NOTIFY-FAILURE: Notification failed: \(error)")
                task.setTaskCompleted(success: false)
            }
        }
    }
    
    private func performContentFetch() async throws -> [String: Any] {
        // Mock content fetch implementation
        // In production, this would make actual HTTP requests
        let mockContent = [
            "id": "fetch_\(Date().timeIntervalSince1970)",
            "timestamp": Date().timeIntervalSince1970,
            "content": "Daily notification content from iOS",
            "source": "ios_platform"
        ] as [String: Any]
        
        return mockContent
    }
    
    private func storeContent(_ content: [String: Any]) async throws {
        // Phase 1: Use DailyNotificationStorage instead of CoreData
        // Convert dictionary to NotificationContent and store via stateActor
        guard let id = content["id"] as? String else {
            throw NSError(domain: "DailyNotification", code: -1, userInfo: [NSLocalizedDescriptionKey: "Missing content ID"])
        }
        
        let currentTime = Int64(Date().timeIntervalSince1970 * 1000)
        let notificationContent = NotificationContent(
            id: id,
            title: content["title"] as? String,
            body: content["content"] as? String ?? content["body"] as? String,
            scheduledTime: currentTime, // Will be updated by scheduler
            fetchedAt: currentTime,
            url: content["url"] as? String,
            payload: content,
            etag: content["etag"] as? String
        )
        
        // Store via stateActor if available
        if #available(iOS 13.0, *), let stateActor = stateActor {
            await stateActor.saveNotificationContent(notificationContent)
        } else if let storage = storage {
            storage.saveNotificationContent(notificationContent)
        }
        
        print("DNP-CACHE-STORE: Content stored via DailyNotificationStorage")
    }
    
    private func getLatestContent() async throws -> [String: Any]? {
        // Phase 1: Get from DailyNotificationStorage
        if #available(iOS 13.0, *), let stateActor = stateActor {
            // Get latest notification from storage
            // For now, return nil - this will be implemented when needed
            return nil
        } else if let storage = storage {
            // Access storage directly if stateActor not available
            // For now, return nil - this will be implemented when needed
            return nil
        }
        return nil
    }
    
    private func isContentExpired(content: [String: Any]) -> Bool {
        guard let timestamp = content["timestamp"] as? TimeInterval else { return true }
        let fetchedAt = Date(timeIntervalSince1970: timestamp)
        let ttlExpiry = fetchedAt.addingTimeInterval(3600) // 1 hour TTL
        return Date() > ttlExpiry
    }
    
    private func showNotification(content: [String: Any]) async throws {
        let notificationContent = UNMutableNotificationContent()
        notificationContent.title = "Daily Notification"
        notificationContent.body = content["content"] as? String ?? "Your daily update is ready"
        notificationContent.sound = .default
        
        let request = UNNotificationRequest(
            identifier: "daily-notification-\(Date().timeIntervalSince1970)",
            content: notificationContent,
            trigger: nil // Immediate delivery
        )
        
        try await notificationCenter.add(request)
        print("DNP-NOTIFY-DISPLAY: Notification displayed")
    }
    
    private func recordHistory(kind: String, outcome: String) async throws {
        guard let context = PersistenceController.shared.viewContext else {
            print("DNP-HISTORY: Cannot record history - CoreData not available")
            return
        }
        
        let historyId = UUID().uuidString
        let history = History.create(
            in: context,
            id: historyId,
            refId: nil,
            kind: kind,
            occurredAt: Date(),
            durationMs: 0,
            outcome: outcome,
            diagJson: nil
        )
        
        do {
            if context.hasChanges {
                try context.save()
                print("DNP-HISTORY: Recorded \(kind) - \(outcome)")
            }
        } catch {
            print("DNP-HISTORY: Failed to save history: \(error.localizedDescription)")
            context.rollback()
            throw error
        }
    }
}
