//
//  Swipe.swift
//  Eureka
//
//  Created by Marco Betschart on 14.06.17.
//  Copyright © 2017 Xmartlabs. All rights reserved.
//

import Foundation
import UIKit

public typealias SwipeActionHandler = (SwipeAction, BaseRow, ((Bool) -> Void)?) -> Void

public class SwipeAction: ContextualAction {
    let handler: SwipeActionHandler
    let style: Style

    public var actionBackgroundColor: UIColor?
    public var image: UIImage?
    public var title: String?

    @available (*, deprecated, message: "Use actionBackgroundColor instead")
    public var backgroundColor: UIColor? {
        get { return actionBackgroundColor }
        set { self.actionBackgroundColor = newValue }
    }

    public init(style: Style, title: String?, handler: @escaping SwipeActionHandler){
        self.style = style
        self.title = title
        self.handler = handler
    }

    func contextualAction(forRow: BaseRow) -> ContextualAction {
        var action: ContextualAction
        if #available(iOS 11, *){
            action = UIContextualAction(style: style.contextualStyle as! UIContextualAction.Style, title: title){ [weak self] action, view, completion -> Void in
                guard let strongSelf = self else{ return }
                strongSelf.handler(strongSelf, forRow) { shouldComplete in
                    if #available(iOS 13, *) { // starting in iOS 13, completion handler is not removing the row automatically, so we need to remove it ourselves
                        if shouldComplete && action.style == .destructive {
                            forRow.section?.remove(at: forRow.indexPath!.row)
                        }
                    }
                    completion(shouldComplete)
                }
            }
        } else {
            action = UITableViewRowAction(style: style.contextualStyle as! UITableViewRowAction.Style,title: title){ [weak self] (action, indexPath) -> Void in
                guard let strongSelf = self else{ return }
				strongSelf.handler(strongSelf, forRow) { _ in
					DispatchQueue.main.async {
						guard action.style == .destructive else {
							forRow.baseCell?.formViewController()?.tableView?.setEditing(false, animated: true)
							return
						}
						forRow.section?.remove(at: indexPath.row)
					}
				}
            }
        }
        if let color = self.actionBackgroundColor {
            action.actionBackgroundColor = color
        }
        if let image = self.image {
            action.image = image
        }
        return action
    }
	
    public enum Style {
        case normal
        case destructive
        
        var contextualStyle: ContextualStyle {
            if #available(iOS 11, *){
                switch self{
                case .normal:
                    return UIContextualAction.Style.normal
                case .destructive:
                    return UIContextualAction.Style.destructive
                }
            } else {
                switch self{
                case .normal:
                    return UITableViewRowAction.Style.normal
                case .destructive:
                    return UITableViewRowAction.Style.destructive
                }
            }
        }
    }
}

public struct SwipeConfiguration {
	
    unowned var row: BaseRow
    
	init(_ row: BaseRow){
		self.row = row
	}
	
	public var performsFirstActionWithFullSwipe = false
	public var actions: [SwipeAction] = []
}

extension SwipeConfiguration {
    @available(iOS 11.0, *)
    var contextualConfiguration: UISwipeActionsConfiguration? {
        let contextualConfiguration = UISwipeActionsConfiguration(actions: self.contextualActions as! [UIContextualAction])
        contextualConfiguration.performsFirstActionWithFullSwipe = self.performsFirstActionWithFullSwipe
        return contextualConfiguration
    }

    var contextualActions: [ContextualAction]{
        return self.actions.map { $0.contextualAction(forRow: self.row) }
    }
}

protocol ContextualAction {
    var actionBackgroundColor: UIColor? { get set }
    var image: UIImage? { get set }
    var title: String? { get set }
}

extension UITableViewRowAction: ContextualAction {
    public var image: UIImage? {
        get { return nil }
        set { return }
    }

    public var actionBackgroundColor: UIColor? {
        get { return backgroundColor }
        set { self.backgroundColor = newValue }
    }
}

@available(iOS 11.0, *)
extension UIContextualAction: ContextualAction {

    public var actionBackgroundColor: UIColor? {
        get { return backgroundColor }
        set { self.backgroundColor = newValue }
    }

}

public protocol ContextualStyle{}
extension UITableViewRowAction.Style: ContextualStyle {}

@available(iOS 11.0, *)
extension UIContextualAction.Style: ContextualStyle {}
