//
//  PhotosUtilities.swift
//  
//  Copyright © 2016-2019 Apple Inc. All rights reserved.
//

import Foundation
import UIKit
import Photos
import SPCCore

struct PhotosUtilities {
    
    static func getAlbum(named name: String, createIfNotFound: Bool = false, completion: @escaping (_ assetCollection: PHAssetCollection?) -> ()) {
        
        DispatchQueue.global(qos: .userInitiated).async {
            
            let fetchOptions = PHFetchOptions()
            fetchOptions.predicate = NSPredicate(format: "title = %@", name)
            let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
            if collections.firstObject == nil && createIfNotFound {
                PhotosUtilities.createAlbum(named: name, completion: completion)
                return
            }
            DispatchQueue.main.async {
                completion(collections.firstObject)
            }
        }
    }
    
    static func getImage(at index: Int, from assetCollection: PHAssetCollection, targetSize: CGSize, completion: @escaping (_ image: UIImage?) -> ()) {
        
        guard let assets = (PHAsset.fetchAssets(in: assetCollection, options: nil) as AnyObject?) as! PHFetchResult<AnyObject>?
            else {
                completion(nil)
                return
        }
        
        PhotosUtilities.getImage(at: index, from: assets, targetSize: targetSize, completion: completion)
    }
    
    static func getImage(at index: Int, from assets: PHFetchResult<AnyObject>, targetSize: CGSize, completion: @escaping (_ image: UIImage?) -> ()) {
        
        guard let asset = assets[index] as? PHAsset
            else {
                completion(nil)
                return
        }

        DispatchQueue.global(qos: .userInitiated).async {
            
            let requestOptions = PHImageRequestOptions()
            requestOptions.deliveryMode = .highQualityFormat
            requestOptions.resizeMode = .fast
            requestOptions.isSynchronous = true
            
            PHImageManager.default().requestImage(for: asset,
                                                  targetSize: targetSize,
                                                  contentMode: .aspectFit,
                                                  options: requestOptions,
                                                  resultHandler: { (image, info) in
                                                    DispatchQueue.main.async {
                                                        completion(image)
                                                    }
            })
        }
    }

    static func createAlbum(named name: String, completion: @escaping (_ assetCollection: PHAssetCollection?) -> ()) {
        
        DispatchQueue.global(qos: .userInitiated).async {
            
            var placeholder: PHObjectPlaceholder?
            PHPhotoLibrary.shared().performChanges({
                let createAlbumRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: name)
                placeholder = createAlbumRequest.placeholderForCreatedAssetCollection
            }) { success, error in
                var assetCollection: PHAssetCollection?
                if success {
                    PBLog("Photos album created: \(name)")
                    let collections = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [placeholder?.localIdentifier ?? ""], options: nil)
                    assetCollection = collections.firstObject
                }
                DispatchQueue.main.async {
                    completion(assetCollection)
                }
            }
        }
    }
    
    static func addImage(_ image: UIImage, to assetCollection: PHAssetCollection, completion: @escaping (_ success: Bool) -> ()) {
        
        DispatchQueue.global(qos: .userInitiated).async {
            
            PHPhotoLibrary.shared().performChanges({
                let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
                let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset
                if let albumChangeRequest = PHAssetCollectionChangeRequest(for: assetCollection) {
                    let fastEnumeration = NSArray(array: [assetPlaceholder] as! [PHObjectPlaceholder])
                    albumChangeRequest.addAssets(fastEnumeration)
                }
                
            }) { success, error in
            
                if error != nil {
                    PBLog("Error adding image to photo library: \(error?.localizedDescription ?? "")")
                }
                
                DispatchQueue.main.async {
                    completion(success)
                }
            }
        }
    }
}
