import UIKit
import RealmSwift
import RxSwift
import RxCocoa
import os.log
import PKHUD

extension OSLog {
    static let startup = OSLog(subsystem: "pro.aliencat.autocat.startup", category: "startup")
}

enum QuickAction {
    case none
    case check
    case checkNumber(String, VehicleEvent?)
    case addVoiceRecord
    case openReport(String)
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var quickAction: QuickAction = .none

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
		
        let config = Realm.Configuration(
            schemaVersion: 32,
            migrationBlock: { migration, oldSchemaVersion in
                if oldSchemaVersion <= 3 {
                    var numbers: [String] = []
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        if let number = old?["number"] as? String {
                            if numbers.contains(number) {
                                migration.delete(old!)
                            } else {
                                numbers.append(number)
                            }
                        }
                    }
                }
                
                if oldSchemaVersion <= 14 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        new!["isRightWheel"] = RealmOptional<Bool>(old!["isRightWheel"] as? Bool)
                    }
                }
                
                if oldSchemaVersion <= 18 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        let addedDate = old!["addedDate"] as! TimeInterval
                        let events = old!.dynamicList("events")
                        new!["addedDate"] = addedDate/1000
                        
                        let lastEvent = events.max { first, second in
                            let firstDate = first["date"] as! TimeInterval
                            let secondDate = second["date"] as! TimeInterval
                            return firstDate < secondDate
                        }
                        
                        if let lastEvent = lastEvent {
                            new!["updatedDate"] = max(addedDate/1000, lastEvent["date"] as! TimeInterval)
                        } else {
                            new!["updatedDate"] = addedDate/1000
                        }
                    }
                }
                
                if oldSchemaVersion == 19 || oldSchemaVersion == 20 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        guard let addedDate = old?["addedDate"] as? TimeInterval else { return }
                        guard let updatedDate = old?["updatedDate"] as? TimeInterval else { return }
                        
                        if addedDate > TimeInterval(Int32.max) {
                            new!["addedDate"] = addedDate/1000
                        }
                        
                        if updatedDate > TimeInterval(Int32.max) {
                            new!["updatedDate"] = updatedDate/1000
                        }
                    }
                }
                
                if oldSchemaVersion <= 21 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        if let oldEngineVolume = (old?["engine"] as? MigrationObject)?["volume"] as? Int {
                            (new?["engine"] as? MigrationObject)?["volume"] = RealmOptional(oldEngineVolume)
                        } else {
                            (new?["engine"] as? MigrationObject)?["volume"] = RealmOptional(0)
                        }
                    }
                }
                
                if oldSchemaVersion <= 22 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        if let oldEnginePower = (old?["engine"] as? MigrationObject)?["powerKw"] as? Int {
                            (new?["engine"] as? MigrationObject)?["powerKw"] = RealmOptional(oldEnginePower)
                        } else {
                            (new?["engine"] as? MigrationObject)?["powerKw"] = RealmOptional(0)
                        }
                    }
                }
                
                if oldSchemaVersion <= 23 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        if let oldJapanese = old?["isJapanese"] as? Bool {
                            new?["isJapanese"] = RealmOptional(oldJapanese)
                        } else {
                            new?["isJapanese"] = RealmOptional<Bool>()
                        }
                    }
                }
                
                if oldSchemaVersion <= 31 {
                    migration.enumerateObjects(ofType: "Vehicle") { old, new in
                        if let oldDebugInfo = old?["debugInfo"] as? DynamicObject, let newDebugInfo = new?["debugInfo"] as? DynamicObject {
                            let addStatus = { (providerName: String) -> Void in
                                if let provider = oldDebugInfo[providerName] as? DynamicObject, let newProvider = newDebugInfo[providerName] as? DynamicObject {
                                    if provider["error"] != nil {
                                        newProvider["status"] = DebugInfoStatus.error.rawValue
                                    } else {
                                        newProvider["status"] = DebugInfoStatus.success.rawValue
                                    }
                                }
                            }
                            
                            addStatus("autocod")
                            addStatus("vin01vin")
                            addStatus("vin01base")
                            addStatus("vin01history")
                            addStatus("nomerogram")
                        }
                    }
                }
            })

		Realm.Configuration.defaultConfiguration = config
        
        HUD.dimsBackground = true
        HUD.allowsInteraction = false
        
        Logging.URLRequests = { _ in false };
        
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        
        #if !targetEnvironment(macCatalyst)
        
        if let shortcutItem = options.shortcutItem {
            if shortcutItem.type == "CheckNumberAction" {
                self.quickAction = .check
            } else if shortcutItem.type == "AddVoiceRecordAction" {
                self.quickAction = .addVoiceRecord
            }
        }
        
        #endif
        
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
}

