//// Copyright 2019 Esri
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import ArcGIS

extension RichPopupViewController {
        
    // MARK: Save
    
    func finishEditingAndPersistRecord(_ completion: ((_ error: Error?) -> Void)? = nil) {
        
        // 1. Finish editing pop-up.
        finishEditingPopup { [weak self] (error) in
            
            guard let self = self else { return }
            
            if let error = error {
                completion?(error)
                return
            }
            
            // 2. Persist edits to table
            self.persistEditsToTable { (error) in
                completion?(error)
            }
        }
    }
    
    private func finishEditingPopup(_ completion: @escaping (_ error: Error?) -> Void) {
        
        // Popup manager must not be in an editing session already.
        guard self.popupManager.isEditing else {
            completion(RichPopupManager.InvalidOperation())
            return
        }
        
        // Ensure the popup validates.
        do {
            try self.popupManager.validatePopup()
        }
        catch {
            completion(error)
            return
        }
        
        // Finally, finish editing the pop-up.
        self.popupManager.finishEditing { (error) in
            completion(error)
        }
    }
    
    private func persistEditsToTable(_ completion: @escaping (_ error: Error?) -> Void) {
        
        guard let feature = self.popupManager.popup.geoElement as? AGSArcGISFeature else {
            preconditionFailure("Unsupported feature type.")
        }
        
        guard let featureTable = feature.featureTable as? AGSArcGISFeatureTable else {
            preconditionFailure("Unsupported feature table type.")
        }
        
        featureTable.performEdit(feature: feature, completion: { [weak self] (error) in
            
            guard let self = self else { return }
            
            if let error = error {
                completion(error)
                return
            }
            
            // An extra check is performed for the sake of the _Trees of Portland_ web map story.
            // This line can be removed without any consequence.
            self.popupManager.conditionallyPerformCustomBehavior { completion(nil) }
        })
    }
    
    // MARK: Delete
    
    func deleteRecord(_ completion: ((_ error: Error?) -> Void)? = nil) {
        
        guard let feature = popupManager.popup.geoElement as? AGSArcGISFeature,
              let featureTable = feature.featureTable as? AGSArcGISFeatureTable,
              featureTable.canDelete(feature) else {
                completion?(RichPopupManager.InvalidOperation())
                return
        }
        
        self.popupManager.cancelEditing()
        
        do {
            try self.popupManager.deleteRichPopup()
        }
        catch {
            completion?(error)
            return
        }
        
        // Delete the record from the table.
        featureTable.performDelete(feature: feature) { (error) in
            completion?(error)
        }
    }
}
