//
//  NotificationService.swift
//  NotificationServiceExtension
//
//  Created by Jake MacMullin on 1/2/2022.
//

import UserNotifications
import Intents
import UIKit

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        
        let userInfo = request.content.userInfo
        if let userName = userInfo["userName"] as? String,
            let userId = userInfo["userId"] as? String,
           let avatarUrlString = userInfo["avatar"] as? String,
           let avatarUrl = URL(string: avatarUrlString) {
            
            Task {
                let (data, _) = try await URLSession.shared.data(from: avatarUrl)

                let handle = INPersonHandle(value: userId, type: .unknown)
                
                let avatar = INImage(imageData: data)
                
                let sender = INPerson(personHandle: handle,
                                      nameComponents: nil,
                                      displayName: userName,
                                      image: avatar,
                                      contactIdentifier: nil,
                                      customIdentifier: nil)
                let intent = INSendMessageIntent(recipients: nil,
                                                 outgoingMessageType: .outgoingMessageText,
                                                 content: request.content.body,
                                                 speakableGroupName: nil,
                                                 conversationIdentifier: "conversation-1",
                                                 serviceName: nil,
                                                 sender: sender,
                                                 attachments: nil)
                let interaction = INInteraction(intent: intent, response: nil)
                interaction.direction = .incoming
                
                interaction.donate { error in
                    do {
                        if let error = error {
                            print(error)
                            return
                        }
                        
                        let content = request.content
                        let updatedContent = try content.updating(from: intent)
                        contentHandler(updatedContent)
                    } catch {
                        print(error)
                    }
                }
            }

        } else
        if let thumbnailURLString = userInfo["thumbnail"] as? String,
            let thubnailURL = URL(string: thumbnailURLString) {
            Task {
                do {
                    let urlRequest = URLRequest(url: thubnailURL)
                    let imageLoader = ImageLoader()
                    let _ = try await imageLoader.fetch(urlRequest)
                    if let cachedImage = await imageLoader.fileName(for: urlRequest),
                     let imageAttachment = try? UNNotificationAttachment(identifier: "thumbnail", url: cachedImage, options: nil),
                       let bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) {
                        print(cachedImage.absoluteString)
                        bestAttemptContent.attachments = [imageAttachment]
                        contentHandler(bestAttemptContent)
                    } else {
                        contentHandler(request.content)
                    }
                } catch {
                    print(error.localizedDescription)
                    contentHandler(request.content)
                }
                
                contentHandler(request.content)
            }
        } else {
            contentHandler(request.content)
        }
    }

    
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}
