import Foundation
import Photos

actor AssetSizeCache {
    static let shared = AssetSizeCache()
    
    private let cache: NSCache<NSString, NSNumber> = NSCache<NSString, NSNumber>()
    private let fileQueue = DispatchQueue(label: "com.assetsize.fileoperations", qos: .utility)
    
    // 临时存储，用于跟踪修改
    private var tempStorage: [String: Int64] = [:]
    private var hasChanges: Bool = false
    
    private let cachePath: String = {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0].appendingPathComponent("AssetSizeCache.plist").path
    }()
    
    private init() {
        Task {
            await loadCache()
        }
    }
    
    private func loadCache() {
        fileQueue.sync {
            if let dict = NSDictionary(contentsOfFile: cachePath) as? [String: Int64] {
                for (key, value) in dict {
                    cache.setObject(NSNumber(value: value), forKey: key as NSString)
                    tempStorage[key] = value
                }
            }
        }
    }
    
    func getSize(for asset: PHAsset) -> Int64? {
        // 优先从内存缓存中读取
        if let size = tempStorage[asset.localIdentifier] {
            return size
        }
        return cache.object(forKey: asset.localIdentifier as NSString)?.int64Value
    }
    
    func setSize(_ size: Int64, for asset: PHAsset) {
        cache.setObject(NSNumber(value: size), forKey: asset.localIdentifier as NSString)
        tempStorage[asset.localIdentifier] = size
        hasChanges = true
    }
    
    // 手动触发保存到文件
    func saveToFile() {
        guard hasChanges else { return }
        
        let path = self.cachePath
        let storageToSave = self.tempStorage
        
        fileQueue.async {
            (storageToSave as NSDictionary).write(toFile: path, atomically: true)
        }
        hasChanges = false
    }
    
    func clearCache() {
        cache.removeAllObjects()
        tempStorage.removeAll()
        hasChanges = true
        
        let path = self.cachePath
        fileQueue.async {
            try? FileManager.default.removeItem(atPath: path)
        }
    }
}
