//
//  SHCloudManager.swift
//  ShorthandMaster
//
//  Created by 明津李 on 2020/8/31.
//  Copyright © 2020 明津李. All rights reserved.
//

import UIKit
import CloudKit

class SHCloudManager: NSObject {

    @objc static let shared = SHCloudManager()
    
    private override init() {}
    
    let recordName = "Recording"
    let recordFolderName = "recordFolder"
    
    lazy var container = CKContainer.default()
//    lazy var dateBase = container.publicCloudDatabase
    lazy var dateBase = container.privateCloudDatabase

    lazy var folderResults:[CKRecord] = []
    lazy var recordResults:[CKRecord] = []
    
    var icloudFolderModels:[SHRecordFolderModel] = []
    
    typealias StatusHandler = ((Bool) -> ())
    typealias CompletionHandler = ((Bool, [SHRecordFolderModel]) -> ())
    
    var statusHandler: StatusHandler?
    var completionHandler: CompletionHandler?
    
    func cheakAccountStatus(_ handler:@escaping StatusHandler){

        statusHandler = handler

        let container = CKContainer.default()
        container.accountStatus { (status, statusError) in

            if let error = statusError {
                DispatchQueue.main.async {
                    MBProgressHUD.showError("未知错误,终止操作")
                }
                self.statusHandler?(false)
                print("\(error.localizedDescription)")
            }else{
                switch status {
                case .available:
                    self.statusHandler?(true)
                    break;
                case .noAccount:
                    DispatchQueue.main.async {
                        MBProgressHUD.showError("请确认您的iCloid是否开启")
                    }
                    self.statusHandler?(false)
                    break;
                default:
                    DispatchQueue.main.async {
                        MBProgressHUD.showError("未知错误,终止操作")
                    }
                    self.statusHandler?(false)
                    break;
                }
            }
        }
    }
    
    func getAllFolderDataSource(_ handler:@escaping CompletionHandler){
        
        completionHandler = handler

        self.cheakAccountStatus { result in
            if result == true {
                let predicate = NSPredicate.init(value: true)
                let query = CKQuery.init(recordType: self.recordFolderName, predicate: predicate)

                self.dateBase.perform(query, inZoneWith: nil) { (records, queryError) in

                    if let error = queryError {
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        self.folderResults = records ?? []
                        self.getAllRecordDataSource(handler)
//                        self.cleanAllFolder()
                    }
                }
            } else {
                DispatchQueue.main.async {
                    MBProgressHUD.showError("获取icloud数据失败, 请稍后再试")
                }
                self.completionHandler?(false, [])
            }
        }
    }
    
    func getAllRecordDataSource(_ handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        self.cheakAccountStatus { result in
            if result == true {
                let predicate = NSPredicate.init(value: true)
                let query = CKQuery.init(recordType: self.recordName, predicate: predicate)

                self.dateBase.perform(query, inZoneWith: nil) { (records, queryError) in

                    if let error = queryError {
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        self.recordResults = records ?? []
                        self.mapDataSource()
                        self.completionHandler?(true, self.icloudFolderModels)
//                        self.cleanAllRecord()
                    }
                }
            } else {
                DispatchQueue.main.async {
                    MBProgressHUD.showError("获取icloud数据失败, 请稍后再试")
                }
                self.completionHandler?(false, [])
            }
        }
    }
    
    func cleanAllRecord(){
        for model in self.recordResults {
            self.deleteRecord(model) { (result, models) in
                
            }
        }
    }
    
    func cleanAllFolder(){
        for model in self.folderResults {
            self.deleteRecord(model) { (result, models) in
                
            }
        }
    }
    
    func mapDataSource(){
        icloudFolderModels = []
        for record in self.folderResults{

            let folderModel = SHRecordFolderModel()
            folderModel.createDate = record["createDate"] as? Date ?? Date(timeIntervalSince1970: 0)
            folderModel.modifyDate = record["modifyDate"] as? Date ?? Date(timeIntervalSince1970: 0)
            folderModel.top = record["top"] as? Bool ?? false
            folderModel.id = record["id"] as? String ?? ""
            folderModel.name = record["name"] as? String ?? ""

            let recordPaths:[String] = record["recordPaths"] as! [String]
            var contains = false
            for pathFile in recordPaths{
                for record in self.recordResults{
                    if pathFile == record["pathFile"] {
                        contains = true
                        let recordModel = SHRecordModel()
                        recordModel.recordingType = record["recordingType"] as? NSInteger ?? 0
                        recordModel.address = record["address"] as? String ?? ""
                        recordModel.pathFile = record["pathFile"] as? String ?? ""
                        recordModel.rename = record["title"] as? String ?? ""
                        recordModel.txt = record["content"] as? String ?? ""
                        recordModel.during = record["during"] as? NSInteger ?? 0
                        recordModel.createDate = record["createDate"] as? Date ?? Date(timeIntervalSince1970: 0)
                        recordModel.modifyDate = record["modifyDate"] as? Date ?? Date(timeIntervalSince1970: 0)
                        recordModel.icloud = true
                        let asset = record["recordAsset"] as! CKAsset
                        recordModel.assetFileUrlPath = asset.fileURL?.path ?? ""
                        
                        recordModel.imagesIndex = record["imagesIndex"] as? Array<NSInteger> ?? []
                        recordModel.imagesPath = record["imagesPath"] as? Array<String> ?? []
                        let assets = record["imagesAsset"] as? [CKAsset] ?? []
                        for (index, asset) in assets.enumerated(){
                            if index > recordModel.imagesIndex.count-1 {
                                break
                            }
                            if index > recordModel.imagesPath.count-1 {
                                break
                            }
                            let path = recordModel.imagesPath[index]
                            var filePath = path.components(separatedBy: "/")[1]
                            filePath = DocumentPath+"/"+filePath
//                            if let image = UIImage.init(contentsOfFile: asset.fileURL!.path){
//                                recordModel.images.append(image)
//                            }
                            if FileManager.default.fileExists(atPath: filePath) == false {
                                if let imageData = try? Data(contentsOf: asset.fileURL!){
                                    try! FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: true, attributes: nil)
                                    try? imageData.write(to: URL(fileURLWithPath: DocumentPath+path))
                                }
                            }
                        }
                        folderModel.dataSources.append(recordModel)
                    }
                }
            }
            if contains == false {
                
            }
            icloudFolderModels.append(folderModel)
        }
    }
    
    func addNewFolder(_ model: SHRecordFolderModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        var recordPaths:[String] = []
        for recordModel in model.dataSources{
            let path = recordModel.pathFile
            if recordModel.icloud {
                recordPaths.append(path)
            }
        }
        
        let folderRecord = CKRecord.init(recordType: recordFolderName)
        folderRecord.setValue(model.name, forKey: "name")
        folderRecord.setValue(model.id, forKey: "id")
        folderRecord.setValue(model.createDate, forKey: "createTime")
        folderRecord.setValue(model.modifyDate, forKey: "modifyDate")
        folderRecord.setValue(model.top, forKey: "top")
        folderRecord.setValue(recordPaths, forKey: "recordPaths")
           
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.save(folderRecord) { (subscription, saveError) in
                    if let error = saveError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        self.folderResults.append(folderRecord)
                        self.mapDataSource()
                        self.completionHandler?(true, self.icloudFolderModels)
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }
    
    func addNewRecord(_ recordModel: SHRecordModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        let recording = self.recordResults.filter({ (item) -> Bool in
            return item["pathFile"] == recordModel.pathFile
        }).first
        
        if recording != nil {
            self.completionHandler?(false, [])
            return
        }
        
        let documentsFile = DocumentPath.appending(recordModel.pathFile)
        let url = URL.init(fileURLWithPath: documentsFile)
        let asset = CKAsset.init(fileURL: url)
        let nowDate = Date()
        
        let record = CKRecord.init(recordType: recordName)
        record.setValue(recordModel.recordingType, forKey: "recordingType")
        record.setValue(recordModel.rename, forKey: "title")
        record.setValue(recordModel.pathFile, forKey: "pathFile")
        record.setValue(recordModel.address, forKey: "address")
        record.setValue(recordModel.txt, forKey: "content")
        record.setValue(recordModel.during, forKey: "during")
        record.setValue(nowDate, forKey: "createTime")
        record.setValue(nowDate, forKey: "modifyDate")
        record.setValue(asset, forKey: "recordAsset")
        
        record.setValue(recordModel.imagesIndex, forKey: "imagesIndex")
        record.setValue(recordModel.imagesPath, forKey: "imagesPath")
        var imageAssets:[CKAsset] = []
        for path in recordModel.imagesPath {
            let imageFile = DocumentPath.appending(path)
            let url = URL.init(fileURLWithPath: imageFile)
            let asset = CKAsset.init(fileURL: url)
            imageAssets.append(asset)
        }
        record.setValue(imageAssets, forKey: "imagesAsset")
        
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.save(record) { (subscription, saveError) in
                    if let error = saveError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        self.recordResults.append(record)
                        self.mapDataSource()
                        self.completionHandler?(true, self.icloudFolderModels)
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }
    
    func modifyFolder(_ folderModel: SHRecordFolderModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        var recordPaths:[String] = []
        for recordModel in folderModel.dataSources{
            let path = recordModel.pathFile
            if recordModel.icloud == true {
                recordPaths.append(path)
            }
        }
        
        let folderRecord = self.folderResults.filter({ (item) -> Bool in
            return item["id"] == folderModel.id
        }).first
        
        if folderRecord == nil{
            self.completionHandler?(false, [])
            return
        }
        
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.fetch(withRecordID: folderRecord!.recordID) { (record, fetchError) in
                    if let error = fetchError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else {
                        let nowDate = Date()
                        record?["recordPaths"] = recordPaths
                        record?["modifyDate"] = nowDate
                        record?["name"] = folderModel.name
                        self.dateBase.save(record!) { (saveRecord, saveError) in
                            
                            if let error = saveError {
                                DispatchQueue.main.async {
                                    MBProgressHUD.showError("icloud保存失败, 请稍后再试")
                                }
                                print("\(error.localizedDescription)")
                                self.completionHandler?(false, [])
                            }else{
                                if let index = self.folderResults.firstIndex(where: {
                                    $0["id"] == folderModel.id
                                }){
                                    self.folderResults[index] = saveRecord!
                                }
                                self.mapDataSource()
                                self.completionHandler?(true, self.icloudFolderModels)
                            }
                        }
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }
    
    func modifyRecord(_ recordModel: SHRecordModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        let recording = self.recordResults.filter({ (item) -> Bool in
            return item["pathFile"] == recordModel.pathFile
        }).first
        
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.fetch(withRecordID: recording!.recordID) { (record, fetchError) in
                    if let error = fetchError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else {
                        let nowDate = Date()
                        record?.setValue(nowDate, forKey: "modifyDate")
                        self.dateBase.save(record!) { (saveRecord, saveError) in
                            
                            if let error = saveError {
                                DispatchQueue.main.async {
                                    MBProgressHUD.showError("icloud保存失败, 请稍后再试")
                                }
                                print("\(error.localizedDescription)")
                                self.completionHandler?(false, [])
                            }else{
                                if let index = self.recordResults.firstIndex(where: {
                                    $0["pathFile"] == recordModel.pathFile
                                }){
                                    self.recordResults[index] = saveRecord!
                                }
                                self.mapDataSource()
                                self.completionHandler?(true, self.icloudFolderModels)
                            }
                        }
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }

    func deleteFolder(_ folderModel: SHRecordFolderModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        let folderRecord = self.folderResults.filter({ (item) -> Bool in
            return item["id"] == folderModel.id
        }).first
        
        if folderRecord == nil{
            self.completionHandler?(false, [])
            return
        }
        
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.delete(withRecordID: folderRecord!.recordID) { (recordID, deleteError) in
                    if let error = deleteError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        if let index = self.folderResults.firstIndex(where: {
                            $0["id"] == folderModel.id
                        }){
                            self.folderResults.remove(at: index)
                        }
                        self.mapDataSource()
                        self.completionHandler?(true, self.icloudFolderModels)
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }
    
    func deleteRecord(_ recordModel: SHRecordModel, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        let record = self.recordResults.filter({ (item) -> Bool in
            return item["pathFile"] == recordModel.pathFile
        }).first
        
        if record == nil{
            self.completionHandler?(false, [])
            return
        }
        self.cheakAccountStatus { result in
            if result == true {
                self.dateBase.delete(withRecordID: record!.recordID) { (recordID, deleteError) in
                    if let error = deleteError {
                        DispatchQueue.main.async {
                            MBProgressHUD.showError("icloud连接失败, 请稍后再试")
                        }
                        print("\(error.localizedDescription)")
                        self.completionHandler?(false, [])
                    }else{
                        if let index = self.recordResults.firstIndex(where: {
                            $0["pathFile"] == recordModel.pathFile
                        }){
                            self.recordResults.remove(at: index)
                        }
                        self.mapDataSource()
                        self.completionHandler?(true, self.icloudFolderModels)
                    }
                }
            } else {
                self.completionHandler?(false, [])
            }
        }
    }
    
    func deleteRecord(_ record: CKRecord, handler:@escaping CompletionHandler){
        
        completionHandler = handler
        
        dateBase.delete(withRecordID: record.recordID) { (recordID, deleteError) in
            
            if let error = deleteError {
                print("\(error.localizedDescription)")
                self.completionHandler?(false, [])
            }else{
                if let index = self.recordResults.firstIndex(where: {
                    $0.recordID == record.recordID
                }){
                    self.recordResults.remove(at: index)
                }
                self.mapDataSource()
                self.completionHandler?(true, self.icloudFolderModels)
            }
        }
    }
}
