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

import Foundation
import Photos
import PlaygroundSupport
import SPCCore

/// A photo album represents the collection of photos in a **Photos** album.
/// It conforms to the Swift `Collection` and `Sequence` protocols so you can use it just like an array. For example:
/// ```
/// let photoCount = photoAlbum.count
/// let photo = photoAlbum[12]
/// ```
///
/// - localizationKey: PhotoAlbum
public class PhotoAlbum: PhotoCollection {
    
    /// Creates a photo album to hold a **Photos** album with the specified name.
    /// Assumes that PhotoLibrary authorization has already been granted.
    ///
    /// - Parameter name: The name of the album to be loaded.
    ///
    /// - localizationKey: PhotoAlbum.init(named:)
    public init(named name: String) {
        super.init()
        self.assetCollection = getAlbum(named: name, createIfNotFound: true)
        if self.assetCollection == nil {
            PBLog("Photo album not found: \(name)")
            self.identifier = nil
        } else {
            self.identifier = self.assetCollection?.localIdentifier
            PBLog("Photo album found: \(self.name) \(self.identifier ?? "")")
        }
        
        // TODO: Better to handle this fully asynchronously and ensure that the completion handler does the necessary.
        //        PhotosUtilities.getAlbum(named: name, createIfNotFound: true, completion: { assetCollection in
        //
        //            if assetCollection == nil {
        //                PBLog("Photo album not found: \(name)")
        //                self.identifier = nil
        //            } else {
        //                self.assetCollection = assetCollection
        //                self.identifier = assetCollection?.localIdentifier
        //                PBLog("Photo album found: \(name) \(self.identifier ?? "")")
        //                self.rehydrate()
        //                self.updated.notifyInputs(true)
        //            }
        //        })
        
    }
    
    public override init() {
        super.init()
    }
    
    // MARK: Private
    
    private func getAlbum(named name: String, createIfNotFound: Bool = false) -> PHAssetCollection? {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "title = %@", name)
        let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
        if collections.count > 0 {
            return collections.firstObject
        } else if createIfNotFound {
            return createAlbum(named: name)
        }
        return nil
    }
    
    private func createAlbum(named name: String) -> PHAssetCollection? {
        var placeholder: PHObjectPlaceholder?
        var assetCollection: PHAssetCollection?
        do {
            try PHPhotoLibrary.shared().performChangesAndWait({
                let createAlbumRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: name)
                placeholder = createAlbumRequest.placeholderForCreatedAssetCollection
            })
            PBLog("Photo album created: \(name)")
            let collections = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [placeholder?.localIdentifier ?? ""], options: nil)
            assetCollection = collections.firstObject
            self.rehydrate()
            self.updated.notifyInputs(true)

        } catch {
            PBLog("Failed to create album \(error).")
        }
        return assetCollection
    }
}
