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

import UIKit
import PlaygroundSupport
import SPCCore

/// An activity button is a special button that displays an activity sheet when it’s pressed.
/// The activity sheet lets you share an image or images in a variety of ways, including by AirDrop, text message or email.
///
/// - localizationKey: ActivityButton
public class ActivityButton: Button {
    public override class var componentType: String { return String(describing: ActivityButton.self) }
    
    public override var liveComponent: LiveComponent? {
        return liveActivityButton
    }
    
    private var liveActivityButton: LiveActivityButton?
    
    enum ActivityButtonEventName : ComponentEventName {
        case imagesChanged
        case share
    }
    
    // MARK: Properties
    
    /// The images to be shared, as an array.
    ///
    /// - localizationKey: ActivityButton.images
    public var images = [Image]() {
        didSet {
            liveActivityButton?.images = images
            let playgroundValuesArray = images.compactMap { $0.playgroundValue }
            updateLiveComponent(.imagesChanged, value: .array(playgroundValuesArray))
        }
    }
    
    // MARK: Inputs
    
    /// An input that accepts event notifications of type `Image`. When this input receives an event, the image is ready to be shared when the activity button is pressed.
    ///
    /// You can connect an output of type `Output<Image>` to this input.
    ///
    /// - localizationKey: ActivityButton.imageInput
    public private(set) lazy var imageInput = Input<Image>({ [weak self] image in
        self?.images = [image]
    })
    
    // MARK: Initialization
    override func initialize() {
        super.initialize()
        
        pressed.connect(to: { _ in
            let event = ComponentEvent(name: ActivityButtonEventName.share.rawValue, value: .boolean(true))
            event.send(to: self, in: .live)
        })
    }
    
    override func createLiveComponent() {
        liveActivityButton = LiveActivityButton(component: self)
    }
    
    // MARK: Messaging
    private func updateLiveComponent(_ eventName: ActivityButtonEventName, value: PlaygroundValue?) {
        guard let playgroundValue = value else { return }
        let event = ComponentEvent(name: eventName.rawValue, value: playgroundValue)
        event.send(to: self, in: .live)
    }
    
    public override func receive(_ event: ComponentEvent, from origin: ComponentMessageOrigin) {
        super.receive(event, from: origin)
        guard let eventName = ActivityButtonEventName(rawValue: event.name) else { return }
        switch eventName {
        case .imagesChanged:
            guard case let .array(playgroundValues) = event.value else { return }
            let images = playgroundValues.compactMap { UIImage.from($0) as? UIImage }
            liveActivityButton?.images = images
        case .share:
            liveActivityButton?.share()
        }
    }
}

class LiveActivityButton: LiveButton {
    
    fileprivate var images: [UIImage]?
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    required init(component: Component) {
        super.init(component: component)
        backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
        layer.cornerRadius = 10
        setAccessibilityInfo()
        setImage(UIImage(named: "ActionIcon"), for: .normal)
        imageEdgeInsets = UIEdgeInsets(top: 6, left: 6, bottom: 6, right: 6)
    }
    
    func share() {
        guard let images = images else { return }
        guard let viewController = self.ancestorViewController else { return }
        let activityViewController = UIActivityViewController(activityItems: images, applicationActivities: nil)
        activityViewController.excludedActivityTypes = [.assignToContact, .addToReadingList]
        activityViewController.popoverPresentationController?.sourceView = self
        activityViewController.popoverPresentationController?.sourceRect = self.bounds
        activityViewController.completionWithItemsHandler = {(activityType: UIActivity.ActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
            viewController.dismiss(animated: true, completion: nil)
            if !completed {
                //PBLog("User canceled activity.")
                return
            }
            PBLog("User completed activity\(activityType?.rawValue ?? "").")
        }
        viewController.present(activityViewController, animated: true, completion: nil)
    }
}
