//
//  KMBatesManager.swift
//  PDF Master
//
//  Created by tangchao on 2022/12/28.
//

import Cocoa

class KMBatesManager: NSObject {
    let kFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("bates")
    let kPlistPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("bates").stringByAppendingPathComponent("bates.plist")
    
    static let defaultManager = KMBatesManager()
    
    var datas: Array<KMBatesModel> = []
    
    override init() {
        super.init()
        if (FileManager.default.fileExists(atPath: kPlistPath!)) {
            let dataDict = NSDictionary(contentsOfFile: kPlistPath!)
            if (dataDict == nil) {
                return
            }
            
            for keyIndex in 0 ..< (dataDict?.allKeys.count)! {
                let key: String = dataDict?.allKeys[keyIndex] as! String
                let modelDict: NSDictionary = dataDict?.object(forKey: key) as! NSDictionary
                
                let model = parseDictionary(dict: modelDict)
                /// 赋值id
                model.id = key
                self.datas.append(model)
            }
            
            /// 根据id进行排序(升序)
            self.datas.sort(){$0.id > $1.id}
        }
    }
    
    func addTemplate(_ model: KMBatesModel) -> Bool {
        if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
            let create: ()? = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
            if (create == nil) {
                return false
            }
        }
        
        if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
            let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
            if (create == nil) {
                return false
            }
        }
        
        let dict = NSDictionary(contentsOfFile: kPlistPath!)
        var newDict:NSMutableDictionary!
        if (dict != nil) {
            newDict = NSMutableDictionary(dictionary: dict!)
        } else {
            newDict = NSMutableDictionary()
        }
        
        let modelDict = self.parseModel(model: model)
        
        let tag = tagString()
        newDict.addEntries(from: [tag : modelDict])
        model.id = tag
        let result = newDict.write(toFile: kPlistPath!, atomically: true)
        if (result) {
            if (self.datas.count < 1) {
                self.datas.append(model)
            } else {
                self.datas.insert(model, at: 0)
            }
        }
        
        return result
    }
    
    func deleteTemplate(_ model: KMBatesModel) -> Bool {
        if (model.id.isEmpty) {
            return false
        }
        
        if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
            return false
        }
        
        let key: String = model.id
        
        let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
        var newDictionary: NSMutableDictionary!
        if (dictionary != nil) {
            newDictionary = NSMutableDictionary(dictionary: dictionary!)
        } else {
            newDictionary = NSMutableDictionary()
        }
        newDictionary.removeObject(forKey: key)
        
        let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
        if (result) {
            if (self.datas.contains(model)) {
                self.datas.removeObject(model)
            }
        }
        return result
    }
    
    func deleteAllTemplate() -> Bool {
        if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
            return false
        }
        
        let dictionary = NSDictionary(contentsOfFile: kPlistPath!)
        var newDictionary: NSMutableDictionary!
        if (dictionary != nil) {
            newDictionary = NSMutableDictionary(dictionary: dictionary!)
        } else {
            newDictionary = NSMutableDictionary()
        }
        
        newDictionary.removeAllObjects()
        
        let result = newDictionary.write(toFile: kPlistPath!, atomically: true)
        if (result) {
            self.datas.removeAll()
        }
        
        return result
    }
    
    func updateTemplate(_ model: KMBatesModel) -> Bool {
        if (!FileManager.default.fileExists(atPath: kFolderPath!)) {
            let create = try?FileManager.default.createDirectory(atPath: kFolderPath!, withIntermediateDirectories: false)
            if (create == nil) {
                return false
            }
        }
        
        if (!FileManager.default.fileExists(atPath: kPlistPath!)) {
            let create = try?FileManager.default.createFile(atPath: kPlistPath!, contents: nil)
            if (create == nil) {
                return false
            }
        }
        
        var flagModel: KMBatesModel!
        for model_ in self.datas {
            if (model_.id == model.id) {
                flagModel = model_
                break
            }
        }
        
        if (flagModel == nil) {
            return false
        }
        
        let dict = NSDictionary(contentsOfFile: kPlistPath!)
        var newDict:NSMutableDictionary!
        if (dict != nil) {
            newDict = NSMutableDictionary(dictionary: dict!)
        } else {
            newDict = NSMutableDictionary()
        }
        
        let modelDict = self.parseModel(model: model)
        newDict.setObject(modelDict, forKey: flagModel.id as NSCopying)
        let result = newDict.write(toFile: kPlistPath!, atomically: true)
        if (result) {
            let index = self.datas.index(of: flagModel)
            self.datas[index!] = model
        }
        
        return result
    }
    
    /**
        `Private Methods`
     */
    private func parseModel(model: KMBatesModel) -> Dictionary<String, Any> {
        var dict: [String : Any] = [:]
        /// 字体相关
        switch model.textFont {
        case .font(name: var name, size: var size):
            dict["fontName"] = name
            dict["fontSize"] = size
        default: break
        }
        
        switch model.textColor {
        case .color(red: var red, green: var green, blue: var blue, alpha: var alpha):
            dict["red"] = red
            dict["green"] = green
            dict["blue"] = blue
            dict["alpha"] = alpha
        default: break
        }
      
        /// 页边距
        dict["leftMargin"] = model.leftMargin
        dict["rightMargin"] = model.rightMargin
        dict["bottomMargin"] = model.bottomMargin
        dict["topMargin"] = model.topMargin
        
        /// 内容
        dict["topLeftString"] = model.topLeftString
        dict["topCenterString"] = model.topCenterString
        dict["topRightString"] = model.topRightString
        dict["bottomLeftString"] = model.bottomLeftString
        dict["bottomCenterString"] = model.bottomCenterString
        dict["bottomRightString"] = model.bottomRightString
        
        dict["prefixString"] = model.prefixString
        dict["suffixString"] = model.suffixString
        dict["digits"] = model.digits
        dict["startString"] = model.startString
        
        dict["pageRangeType"] = model.pageRangeType
        dict["pageRangeString"] = model.pageRangeString
        
        return dict
    }
    
    private func parseDictionary(dict: NSDictionary) -> KMBatesModel {
        let model = KMBatesModel()
        
        /// 字体相关
        model.textFont = .font(name: dict["fontName"] as! String, size: dict["fontSize"] as! CGFloat)
        model.textColor = .color(red: dict["red"] as! CGFloat, green: dict["green"] as! CGFloat, blue: dict["blue"] as! CGFloat, alpha: dict["alpha"] as! CGFloat)

        /// 页边距
        model.leftMargin = dict["leftMargin"] as! CGFloat
        model.rightMargin = dict["rightMargin"] as! CGFloat
        model.bottomMargin = dict["bottomMargin"] as! CGFloat
        model.topMargin = dict["topMargin"] as! CGFloat
        
        /// 内容
        model.topLeftString = dict["topLeftString"] as! String
        model.topCenterString = dict["topCenterString"] as! String
        model.topRightString = dict["topRightString"] as! String
        model.bottomLeftString = dict["bottomLeftString"] as! String
        model.bottomCenterString = dict["bottomCenterString"] as! String
        model.bottomRightString = dict["bottomRightString"] as! String
        
        model.prefixString = dict["prefixString"] as! String
        model.suffixString = dict["suffixString"] as! String
        model.digits = dict["digits"] as! Int
        model.startString = dict["startString"] as! String
        
        model.pageRangeType = dict["pageRangeType"] as! Int
        model.pageRangeString = dict["pageRangeString"] as! String
        
        return model
    }
    
    private func tagString() -> String {
        var result: String = ""
        
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyMMddHHmmss"
        result.append(dateFormatter.string(from: Date()))
        result = result.appendingFormat("%04d", arc4random()%10000)
        
        return result
    }
}