//
//  SavedDataManager.swift
//  Tusker
//
//  Created by Shadowfacts on 12/19/19.
//  Copyright © 2019 Shadowfacts. All rights reserved.
//

import Foundation
import Pachyderm
import CoreData

class SavedDataManager: Codable {
    private static var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    private static var archiveURL = SavedDataManager.documentsDirectory.appendingPathComponent("saved_data").appendingPathExtension("plist")
    
    static func load() -> SavedDataManager? {
        let decoder = PropertyListDecoder()
        if let data = try? Data(contentsOf: archiveURL),
            let savedHashtagsManager = try? decoder.decode(Self.self, from: data) {
            return savedHashtagsManager
        }
        return nil
    }
    
    static func destroy() throws {
        try FileManager.default.removeItem(at: archiveURL)
    }
    
    private init() {}
    
    private(set) var savedHashtags: [String: [Hashtag]] = [:]
    private(set) var savedInstances: [String: [URL]] = [:]
    
    var accountIDs: Set<String> {
        var s = Set<String>()
        savedHashtags.keys.forEach { s.insert($0) }
        savedInstances.keys.forEach { s.insert($0) }
        return s
    }
    
    private func save() {
        let encoder = PropertyListEncoder()
        let data = try? encoder.encode(self)
        try? data?.write(to: SavedDataManager.archiveURL, options: .noFileProtection)
    }
    
    func migrateToCoreData(accountID: String, context: NSManagedObjectContext) throws {
        var changed = false
        
        if let hashtags = savedHashtags[accountID] {
            let objects: [[String: Any]] = hashtags.map {
                ["url": $0.url, "name": $0.name]
            }
            let hashtagsReq = NSBatchInsertRequest(entity: SavedHashtag.entity(), objects: objects)
            try context.execute(hashtagsReq)
            savedHashtags.removeValue(forKey: accountID)
            changed = true
        }
        
        if let instances = savedInstances[accountID] {
            let objects = instances.map {
                ["url": $0]
            }
            let instancesReq = NSBatchInsertRequest(entity: SavedInstance.entity(), objects: objects)
            try context.execute(instancesReq)
            savedInstances.removeValue(forKey: accountID)
            changed = true
        }
        
        if changed {
            save()
        }
    }
}

extension Foundation.Notification.Name {
    static let savedHashtagsChanged = Notification.Name("savedHashtagsChanged")
    static let savedInstancesChanged = Notification.Name("savedInstancesChanged")
}
