//
//  PhotoManager.swift
//  PhotoManager
//
//  Created by edy on 2025/4/22.
//

import Foundation
import Photos
import AVFoundation
import CoreML
import Vision
import UIKit

// 在 PhotoManager 类之前添加
actor ImageCacheActor {
    private let cache = NSCache<NSString, UIImage>()
    
    func getImage(for key: String) -> UIImage? {
        cache.object(forKey: key as NSString)
    }
    
    func setImage(_ image: UIImage, for key: String) {
        cache.setObject(image, forKey: key as NSString)
    }
}


// 定义状态枚举
enum BaseDataLoadingState {
    case notLoaded
    case loading
    case loaded
    case failed(Error)
}

enum FileType {
    case json
    case plist
    case all
}


class PhotoManager{
    
    static let shared = PhotoManager()
    
    private let imageCache = ImageCacheActor()
    
    // 定义存储数据结构
    private struct StorageData: Codable {
        var video: [AssetModel]
        var other: [AssetModel]
        var screenshot: [AssetModel]
    }
    
    // 获取本地存储路径
    private func getLocalStoragePath() -> URL {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        return documentsPath.appendingPathComponent("assets_data.json")
    }
    
    // 保存数据到本地
    private let fileQueue = DispatchQueue(label: "com.cleanphoto.fileoperations")
    
    private init() {
        requestAuthorization()
    }
    
    func config(){}
    
    // 添加 Published 属性
    private(set) var baseDataLoadingState: BaseDataLoadingState = .notLoaded
    
    var permissionStatus:PHAuthorizationStatus = .notDetermined
    // MARK: - 基础配置
    // 所有的媒体资源
    var allAssets:[PHAsset] = []
    // 照片
    private(set) var photosAssets:[PHAsset] = []
    // 截图
    private(set) var screenShotAssets:[PHAsset] = []
    // 视频
     private(set) var videoAssets:[PHAsset] = []
    // 其他
    private(set) var otherAssets:[PHAsset] = []
    
    // 相似图片分组
    var similarModels:[[AssetModel]] = []
    // 相似截图分组
    var similarScreenShotModels:[[AssetModel]] = []
    // 相似视频分组
    var similarVideoModels:[[AssetModel]] = []
    // 重复图片分组
    var duplicateModels:[[AssetModel]] = []
    
    // 过滤垃圾桶/保留相似图片分组
    var filterSimilarModels:[[AssetModel]] = []
    // 过滤垃圾桶/保留相似截图分组
    var filterSimilarScreenShotModels:[[AssetModel]] = []
    // 过滤垃圾桶/保留相似视频分组
    var filterSimilarVideoModels:[[AssetModel]] = []

    // 截图
    var screenShotModels:[AssetModel] = []
    // 视频
    var videoModels:[AssetModel] = []
    // 其他
    var otherModels:[AssetModel] = []
    
    // 过滤垃圾桶/保留截图
    var filterScreenShotModels:[AssetModel] = []
    // 过滤垃圾桶/保留视频
    var filterVideoModels:[AssetModel] = []
    // 过滤垃圾桶/保留其他
    var filterOtherModels:[AssetModel] = []
    
    
    private(set) var screenShotTotalSize:Int64 = 0
    private(set) var videoTotalSize:Int64 = 0
    private(set) var otherTotalSize:Int64 = 0
    
    
    var trash:[String] = []
    
    var keep:[String] = []

    private var currentPage: Int = 0
    private let pageSize: Int = 50 // 每次加载的数量
    
    // MARK: -基础函数
    // 获取相册权限
    func requestAuthorization(completion: @escaping (Bool) -> Void) {
        PHPhotoLibrary.requestAuthorization {[weak self] status in
            guard let weakSelf = self else { return }
            DispatchQueue.main.async {
                weakSelf.permissionStatus = status
                completion(status == .authorized)
            }
        }
    }
    

   private func requestAuthorization(){
        // 获取基础数据
       requestAuthorization {[weak self] permission in
           guard let weakSelf = self else { return }
           if permission{
               weakSelf.getBaseAssetGroup()
           }else{
               //weakSelf.clearLocalData()
           }
           
        }
    }
    
    // 获取基本资源
    func getBaseAssetGroup() {
        
        baseDataLoadingState = .loading
        
        trash = TrashDatabase.shared.queryAll().compactMap{$0.localIdentifier}
        
        keep = GroupDatabase.shared.queryAll().compactMap{$0.localIdentifier}

        DispatchQueue.global(qos: .background).async {[weak self] in
            
            guard let weakSelf = self else { return }

            let fetchOptions = PHFetchOptions()
            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            
            let photoAllAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
            
            let videoAllAssets = PHAsset.fetchAssets(with: .video, options: fetchOptions)
            
           
            
            let fetchOptionsS = PHFetchOptions()
            fetchOptionsS.predicate = NSPredicate(format: "mediaSubtypes == %d", PHAssetMediaSubtype.photoScreenshot.rawValue)
            let screenShotAllAssets = PHAsset.fetchAssets(with: .image, options: fetchOptionsS)
            
            let photoAssetsArray = photoAllAssets.objects(at: IndexSet(0..<photoAllAssets.count))
            let videoAssetsArray = videoAllAssets.objects(at: IndexSet(0..<videoAllAssets.count))
            let screenShotArray = screenShotAllAssets.objects(at: IndexSet(0..<screenShotAllAssets.count))
            let otherArray =  photoAssetsArray.filter {!screenShotArray.contains($0) }
            
            weakSelf.allAssets = photoAssetsArray + videoAssetsArray
            
            // 在主线程更新状态
           DispatchQueue.main.async {
               weakSelf.photosAssets = photoAssetsArray
               weakSelf.videoAssets = videoAssetsArray
               weakSelf.screenShotAssets = screenShotArray
               weakSelf.otherAssets = otherArray
               weakSelf.baseDataLoadingState = .loaded
               print("基本数据执行完毕")
               NotificationManager().scheduleInactiveNotification(days: 8, identifier: "inactive_8d")
               NotificationManager().scheduleInactiveNotification(days: 10, identifier: "inactive_10d")
               NotificationCenter.default.post(name: .getBaseAssetsSuccess, object: nil)
            }
        }
     }
    
    
    // 转化视频模型和获取大小
    func convertVideoModels(complectionHandler:(([AssetModel],Int64) ->Void)?){
        Task{
            // 先尝试从本地加载
            if let localModels = loadFromLocal(type: "video") {
                let videoTotalSize = Int64(localModels.reduce(0){$0+$1.assetSize})
                await MainActor.run {
                    self.videoModels = localModels
                    self.videoTotalSize = videoTotalSize
                    complectionHandler?(localModels, videoTotalSize)
                }
            }
            
            let start = CFAbsoluteTimeGetCurrent()
            self.videoModels = await convertAssetsToModel(for: self.videoAssets, mediaType: 2)
            self.videoModels.sort { $0.createDate > $1.createDate }
            let duration = CFAbsoluteTimeGetCurrent() - start
            print("视频转换总耗时: \(duration)秒")
            let videoTotalSize = Int64(self.videoModels.reduce(0){$0+$1.assetSize})
            
            // 保存到本地
            saveToLocal(type: "video", models: self.videoModels)
            
            await MainActor.run {
                self.videoTotalSize = videoTotalSize
                complectionHandler?(self.videoModels,videoTotalSize)
            }
        }
    }
    
    // 转化其他图片模型和获取大小
    func convertOtherPhotoModels(complectionHandler:(([AssetModel],Int64) ->Void)?){
        Task{
            // 先尝试从本地加载
            if let localModels = loadFromLocal(type: "other") {
                let otherTotalSize = Int64(localModels.reduce(0){$0+$1.assetSize})
                await MainActor.run {
                    self.otherModels = localModels
                    self.otherTotalSize = otherTotalSize
                    complectionHandler?(localModels, otherTotalSize)
                }
            }
            
            let start = CFAbsoluteTimeGetCurrent()
            self.otherModels = await convertAssetsToModel(for: self.otherAssets, mediaType: 1)
            self.otherModels.sort { $0.createDate > $1.createDate }
            let duration = CFAbsoluteTimeGetCurrent() - start
            print("其他图片转换总耗时: \(duration)秒")
            let otherTotalSize = Int64(self.otherModels.reduce(0){$0+$1.assetSize})
            
            // 保存到本地
            saveToLocal(type: "other", models: self.otherModels)
            
            await MainActor.run {
                self.otherTotalSize = otherTotalSize
                complectionHandler?(self.otherModels,otherTotalSize)
            }
        }
    }
    
    // 转化截图模型和获取大小
    func convertScreenShotModels(complectionHandler:(([AssetModel],Int64) ->Void)?){
        Task{
            // 先尝试从本地加载
            if let localModels = loadFromLocal(type: "screenshot") {
                let screenShotTotalSize = Int64(localModels.reduce(0){$0+$1.assetSize})
                await MainActor.run {
                    self.screenShotModels = localModels
                    self.screenShotTotalSize = screenShotTotalSize
                    complectionHandler?(localModels, screenShotTotalSize)
                }
            }
            
            let start = CFAbsoluteTimeGetCurrent()
            self.screenShotModels = await convertAssetsToModel(for: self.screenShotAssets, mediaType: 1)
            self.screenShotModels.sort { $0.createDate > $1.createDate }
            let duration = CFAbsoluteTimeGetCurrent() - start
            print("截图转换总耗时: \(duration)秒")
            let screenShotTotalSize = Int64(self.screenShotModels.reduce(0){$0+$1.assetSize})
            
            // 保存到本地
            saveToLocal(type: "screenshot", models: self.screenShotModels)
            
            await MainActor.run {
                self.screenShotTotalSize = screenShotTotalSize
                complectionHandler?(self.screenShotModels,screenShotTotalSize)
            }
        }
    }
    
}

// MARK: - 本地存储
extension PhotoManager{
    
    private func saveToLocal(type: String, models: [AssetModel]) {
        fileQueue.async {
            let filePath = self.getLocalStoragePath()
            let encoder = JSONEncoder()
            let decoder = JSONDecoder() // 添加这行
            encoder.dateEncodingStrategy = .iso8601
            decoder.dateDecodingStrategy = .iso8601 // 添加这行
            
            // 在串行队列中执行读取-修改-写入操作
            var storageData: StorageData
            if let existingData = try? Data(contentsOf: filePath),
               let decoded = try? decoder.decode(StorageData.self, from: existingData) {
                storageData = decoded
            } else {
                storageData = StorageData(video: [], other: [], screenshot: [])
            }
            
            switch type {
            case "video":
                storageData.video = models
            case "other":
                storageData.other = models
            case "screenshot":
                storageData.screenshot = models
            default:
                break
            }
            
            do {
                let data = try encoder.encode(storageData)
                try data.write(to: filePath)
            } catch {
                print("保存本地数据失败:", error)
            }
        }
    }
    
    // 从本地读取数据
    private func loadFromLocal(type: String) -> [AssetModel]? {
        return fileQueue.sync {
            let filePath = getLocalStoragePath()
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            
            guard let data = try? Data(contentsOf: filePath),
                  let storageData = try? decoder.decode(StorageData.self, from: data) else {
                return nil
            }
            
            switch type {
            case "video":
                return storageData.video
            case "other":
                return storageData.other
            case "screenshot":
                return storageData.screenshot
            default:
                return nil
            }
        }
    }
}


// MARK: - 工具函数支持
extension PhotoManager{
    
    
    // 获取文件大小
//    func getAssetSize(for asset:PHAsset) ->Int64{
//        if let resource = PHAssetResource.assetResources(for: asset).first,
//           let size = resource.value(forKey: "fileSize") as? Int64 {
//            return size
//        } else {
//            return 0
//        }
//    }
    
    func getAssetSize(for asset: PHAsset) async -> Int64 {
        // 先尝试从缓存获取
        if let cachedSize = await AssetSizeCache.shared.getSize(for: asset) {
            return cachedSize
        }
        
        // 如果缓存中没有，则计算大小
        if let resource = PHAssetResource.assetResources(for: asset).first,
           let size = resource.value(forKey: "fileSize") as? Int64 {
            // 将计算结果存入缓存
            await AssetSizeCache.shared.setSize(size, for: asset)
            return size
        }
        
        return 0
    }
    

    // 请求照片数据的大小
    private func requestImageData(for asset: PHAsset, completion: @escaping (Int64) -> Void) {
        let options = PHImageRequestOptions()
        options.isSynchronous = true // 设置为同步，以在回调前完成任务
        options.version = .original
        PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { (data, _, _, _) in
            let dataSize = data?.count ?? 0
            completion(Int64(dataSize))
        }
    }
    
    // 请求视频数据的大小
    private func getVideoAssetSize(_ asset: PHAsset, completion: @escaping (Int64) -> Void) {
        let options = PHVideoRequestOptions()
        // 获取原始数据
        options.version = .original
        // 不去计算iclound资源
        options.isNetworkAccessAllowed = true
        PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, _, _) in
            if let urlAsset = avAsset as? AVURLAsset {
                let size = try? urlAsset.url.resourceValues(forKeys: [.fileSizeKey]).fileSize ?? 0
                completion(Int64(size ?? 0))
            } else {
                completion(0)
            }
        }
    }
    
    // 根据 localIdentifier 获取图片
//    func getImage(localIdentifier: String, targetSize: CGSize = PHImageManagerMaximumSize, completion: @escaping (UIImage?) -> Void) {
//
//        // 根据 localIdentifier 获取 PHAsset
//        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
//        guard let asset = fetchResult.firstObject else {
//            completion(nil)
//            return
//        }
//        
//        // 配置图片请求选项
//        let options = PHImageRequestOptions()
//        options.version = .current
//        options.deliveryMode = .highQualityFormat
//        options.isNetworkAccessAllowed = true // 允许从 iCloud 下载
//        options.resizeMode = .exact
//        
//        // 请求图片
//        PHImageManager.default().requestImage(
//            for: asset,
//            targetSize: targetSize,
//            contentMode: .aspectFit,
//            options: options
//        ) { image, info in
//  
//            DispatchQueue.main.async {
//                completion(image)
//            }
//        }
//    }
    
    
    
    func getImage(localIdentifier: String, targetSize: CGSize = PHImageManagerMaximumSize, completion: @escaping (UIImage?) -> Void) {
        Task {
            // 先检查缓存
            if let cachedImage = await imageCache.getImage(for: localIdentifier) {
                await MainActor.run {
                    completion(cachedImage)
                }
                return
            }
            
            // 根据 localIdentifier 获取 PHAsset
            let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
            guard let asset = fetchResult.firstObject else {
                await MainActor.run {
                    completion(nil)
                }
                return
            }
            
            // 配置图片请求选项
            let options = PHImageRequestOptions()
            options.version = .current
            options.deliveryMode = .highQualityFormat
            options.isNetworkAccessAllowed = true
            options.resizeMode = .exact
            
            // 请求图片
            PHImageManager.default().requestImage(
                for: asset,
                targetSize: targetSize,
                contentMode: .aspectFit,
                options: options
            ) { [weak self] image, info in
                guard let self = self else { return }
                
                if let image = image {
                    Task {
                        await self.imageCache.setImage(image, for: localIdentifier)
                        await MainActor.run {
                            completion(image)
                        }
                    }
                } else {
                    Task {
                        await MainActor.run {
                            completion(nil)
                        }
                    }
                }
            }
        }
        
    }
    
    // 获取视频url
    func getVideoURL(localIdentifier: String, completion: @escaping (URL?) -> Void) {
         // 1. 通过本地标识符获取 PHAsset
         let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
         guard let asset = fetchResult.firstObject else {
             completion(nil)
             return
         }
         
         // 2. 确保资产是视频类型
         guard asset.mediaType == .video else {
             completion(nil)
             return
         }
         
         // 3. 设置视频请求选项
         let options = PHVideoRequestOptions()
         options.version = .original
         options.deliveryMode = .highQualityFormat
         options.isNetworkAccessAllowed = true
        
         // 4. 请求视频资源
         PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, _, _) in
             DispatchQueue.main.async {
                 if let urlAsset = avAsset as? AVURLAsset {
                     completion(urlAsset.url)
                 } else {
                     completion(nil)
                 }
             }
         }
     }
    
    // 根据文件大小直接格式化
    func formatBytes(_ bytes: Int64) -> String {
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = [.useKB, .useMB, .useGB] // 选择合适的单位
        formatter.countStyle = .file
        return formatter.string(fromByteCount: bytes)
    }
}

// MARK: - 数据函数支持
extension PhotoManager{
    
    // 获取一定页数的图片
    func fetchImages(page: Int, completion: @escaping ([PHAsset]) -> Void) {
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        fetchOptions.fetchLimit = pageSize * (page + 1) // 增加请求的数量

        let allImages = PHAsset.fetchAssets(with: .image, options: fetchOptions)
        var images = [PHAsset]()
        
        allImages.enumerateObjects { (asset, _, _) in
            images.append(asset)
        }
        
        completion(images)
    }
    
    // 获取一定页数的视频
     func fetchVideos(page: Int, completion: @escaping ([PHAsset]) -> Void) {
         let fetchOptions = PHFetchOptions()
         fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
         fetchOptions.fetchLimit = pageSize * (page + 1) // 增加请求的数量

         let allVideos = PHAsset.fetchAssets(with: .video, options: fetchOptions)
         var videos = [PHAsset]()
         
         allVideos.enumerateObjects { (asset, _, _) in
             videos.append(asset)
         }
         
         completion(videos)
     }
    
    // 获取指定类型的媒体资源
    func fetchMediaAssets(type: MediaType, completion: @escaping ([PHAsset]) -> Void) {
        DispatchQueue.global(qos: .background).async {
            let fetchOptions = PHFetchOptions()
            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            
            var assets: PHFetchResult<PHAsset>
            
            switch type {
            case .video:
                assets = PHAsset.fetchAssets(with: .video, options: fetchOptions)
            case .screenshot:
                // 使用系统属性判断截图
                fetchOptions.predicate = NSPredicate(format: "mediaSubtype == %d", PHAssetMediaSubtype.photoScreenshot.rawValue)
                assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
            case .photo:
                assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
            case .other:
                // 排除视频和截图
                let predicates = [
                    NSPredicate(format: "mediaType == %d", PHAssetMediaType.image.rawValue),
                    NSPredicate(format: "mediaSubtype != %d", PHAssetMediaSubtype.photoScreenshot.rawValue)
                ]
                fetchOptions.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
                assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
            }
            
            var mediaAssets:[PHAsset] = []
            
            assets.enumerateObjects {(asset, _, _) in
                mediaAssets.append(asset)
            }
            
            DispatchQueue.main.async {
                completion(mediaAssets)
            }
            
        }
    }
    
    // 根据Id获取PHAsset
    func fetchAsset(with localIdentifier: String, completion: @escaping (PHAsset?) -> Void) {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "localIdentifier == %@", localIdentifier)
        let assets = PHAsset.fetchAssets(with: fetchOptions)
        if let asset = assets.firstObject {
            completion(asset)
        } else {
            completion(nil)
        }
    }
    
    func getTotalSize(source:[[AssetModel]]) ->Double{
        return source.flatMap{$0}.reduce(0){$0+$1.assetSize}
    }
    
    // 获取所有资产的总数
//    func fetchTotalAssets(completion: @escaping ([PHAsset]) -> Void) {
//        DispatchQueue.global(qos: .background).async {
//            let fetchOptions = PHFetchOptions()
//            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
//            
//            let allAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
//            var assets = [PHAsset]()
//            
//            allAssets.enumerateObjects { (asset, _, _) in
//                assets.append(asset)
//            }
//
//            DispatchQueue.main.async {
//                self.allAssets = assets
//                completion(assets)
//            }
//        }
//    }
}

extension PhotoManager{
    
    // 批量转模型
    func convertAssetsToModel(for assets: [PHAsset], mediaType: Int) async -> [AssetModel] {
        let batchSize = 4 // 控制并发数量
        var results: [AssetModel] = []
        
        // 分批处理资产
        for batch in stride(from: 0, to: assets.count, by: batchSize) {
            let end = min(batch + batchSize, assets.count)
            let currentBatch = Array(assets[batch..<end])
            
            await withTaskGroup(of: AssetModel.self) { group in
                for asset in currentBatch {
                    group.addTask {
                        return AssetModel(
                            localIdentifier: asset.localIdentifier,
                            assetSize: Double(await self.getAssetSize(for: asset)),
                            createDate: asset.creationDate ?? Date(),
                            mediaType: mediaType
                        )
                    }
                }
                
                // 收集当前批次的结果
                for await result in group {
                    results.append(result)
                }
            }
        }
        return results
    }
    
    // 获取总数据
    func getModelsData(){
        Task{
            let start = CFAbsoluteTimeGetCurrent()
            self.screenShotModels =  await convertAssetsToModel(for: self.screenShotAssets, mediaType: 1)
            self.otherModels =  await convertAssetsToModel(for: self.otherAssets, mediaType: 1)
            self.videoModels =  await convertAssetsToModel(for: self.videoAssets, mediaType: 2)
            let duration = CFAbsoluteTimeGetCurrent() - start
            print("转换总耗时: \(duration)秒")
            let screenShotTotalSize = Int64(self.screenShotModels.reduce(0){$0+$1.assetSize})
            let videoTotalSize = Int64(self.videoModels.reduce(0){$0+$1.assetSize})
            let otherTotalSize = Int64(self.otherModels.reduce(0){$0+$1.assetSize})
            
            await MainActor.run {
                self.screenShotTotalSize = screenShotTotalSize
                self.videoTotalSize = videoTotalSize
                self.otherTotalSize = otherTotalSize
            }
        }
    }
}



extension PhotoManager{
    
    
    //调用系统删除
    func deleteAssets(localIdentifiers: [String],suc:@escaping () -> ()) {
        // 获取要删除的 PHAsset
        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil)
        // 开始删除操作
        PHPhotoLibrary.shared().performChanges({
            // 创建删除请求
            PHAssetChangeRequest.deleteAssets(fetchResult)
        }) { success, error in
            if success {
                suc()
            } else if let error = error {
                print("删除失败: \(error.localizedDescription)")
                PMLoadingHUD.share.disMiss()
            }
        }
    }
    
    // 处理app图片删除
    func removeDataWhenDeleteInPage(data:[AssetModel],completionHandler: (() -> Void)? = nil){
        
        Task.detached(priority: .background) { [weak self] in
            guard let self = self else { return }
            
            let deletes = data.compactMap{$0.localIdentifier}
            
            // 临时数据更新
            let others = removeAssets(withIdentifiers: deletes, from: otherModels)
            let videos = removeAssets(withIdentifiers: deletes, from: videoModels)
            let screens = removeAssets(withIdentifiers: deletes, from: screenShotModels)
            
            otherModels = others
            videoModels = videos
            screenShotModels = screens
            
            // 临时数据更新
            let similarPhotos = filterGroups(similarModels, byExcludingIDs: deletes)
            let similarVideos = filterGroups(similarVideoModels, byExcludingIDs: deletes)
            let similarShots = filterGroups(similarScreenShotModels, byExcludingIDs: deletes)
            let duplicates = filterGroups(duplicateModels, byExcludingIDs: deletes)
            
            similarModels = similarPhotos
            similarVideoModels = similarVideos
            similarScreenShotModels = similarShots
            duplicateModels = duplicates
            
            // 保存到本地
            saveToLocal(type: "video", models: self.videoModels)
            saveToLocal(type: "other", models: self.otherModels)
            saveToLocal(type: "screenshot", models: self.screenShotModels)
            
            await PhotoSimilarManager.shared.removeLocalFileWithIds(for: deletes)
            await ScreenshotSimilarJSONManager.shared.removeLocalFileWithIds(for: deletes)
            await VideoSimilarJSONManager.shared.removeLocalFileWithIds(for: deletes)
            await PhotoDuplicateManager.shared.removeLocalFileWithIds(for: deletes)
            
            filterResource()
            completionHandler?()
        }
    }
    
    // 清楚本地存储数据
    func clearLocalData(){
        
    }
    
    
    func removeAssets(withIdentifiers identifiers: [String], from assets: [AssetModel]) -> [AssetModel] {
        let identifierSet = Set(identifiers)
        return assets.filter { !identifierSet.contains($0.localIdentifier) }
    }
    
    /// 过滤分组中的资源
    func filterGroups(_ groups: [[AssetModel]], byExcludingIDs ids: [String]) -> [[AssetModel]] {
        let excludeSet = Set(ids)
        return groups.compactMap { group in
            // 过滤掉需要排除的元素
            let filteredGroup = group.filter { !excludeSet.contains($0.localIdentifier) }
            // 仅当过滤后的组至少包含2个元素时保留
            return filteredGroup.count >= 2 ? filteredGroup : nil
        }
    }
    
    // 重写获取垃圾桶和保留刷新进行刷新
    func reloadTrashAndKeep(){
        trash = TrashDatabase.shared.queryAll().compactMap{$0.localIdentifier}
        keep = GroupDatabase.shared.queryAll().compactMap{$0.localIdentifier}
        filterResource()
    }
    
    // 基本资源过滤保留和垃圾桶资源
    func filterResource(){
        
        let filterArray = trash + keep
        
        let others = removeAssets(withIdentifiers: filterArray, from: otherModels)
        let videos = removeAssets(withIdentifiers: filterArray, from: videoModels)
        let screens = removeAssets(withIdentifiers: filterArray, from: screenShotModels)
        
        filterOtherModels = others
        filterVideoModels = videos
        filterScreenShotModels = screens
        
        
        let similarPhotos = filterGroups(similarModels, byExcludingIDs: filterArray)
        let similarVideos = filterGroups(similarVideoModels, byExcludingIDs: filterArray)
        let similarShots = filterGroups(similarScreenShotModels, byExcludingIDs: filterArray)
        
        filterSimilarModels = similarPhotos
        filterSimilarVideoModels = similarVideos
        filterSimilarScreenShotModels = similarShots
    }

    
    func getPHAsssetwithID(ids :[String]) -> PHAsset? {
        
        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: ids, options: nil)
        
        let assetsArray = fetchResult.objects(at: IndexSet(0..<fetchResult.count))
        
        return assetsArray.first
    }
    
    func getPHAsssetwithIDs(ids :[AssetModel]) -> [PHAsset]? {
        
        let localIdentifiers = ids.map { $0.localIdentifier }
        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil)
        let assetsArray = fetchResult.objects(at: IndexSet(0..<fetchResult.count))
        
        return assetsArray
    }
    
    func getImageFromAssetID(id: String) -> UIImage? {
        
        if let asset = getPHAsssetwithID(ids: [id]) {
            
            return getImageFromAsset(asset: asset)
        }else {
            
            return nil
        }
    }
    
    func getImageFromAsset(asset: PHAsset) -> UIImage? {
        var image: UIImage?
        let imageManager = PHImageManager.default()
        let targetSize = CGSize(width: 400, height: 400)
        let options = PHImageRequestOptions()
        options.isSynchronous = true
        options.deliveryMode = .opportunistic
        options.isNetworkAccessAllowed = true
        imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: options) { result, _ in
            image = result
        }
        return image
    }
    
    static func deleteAssets(localIdentifiers: [String],suc:@escaping () -> ()) {
        // 获取要删除的 PHAsset
        PMLoadingHUD.share.show()
        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil)
        
        // 开始删除操作
        PHPhotoLibrary.shared().performChanges({
            // 创建删除请求
            PHAssetChangeRequest.deleteAssets(fetchResult)
        }) { success, error in
            if success {
                suc()
            } else if let error = error {
                print("删除失败: \(error.localizedDescription)")
            }
            PMLoadingHUD.share.disMiss()
        }
    }
    
    func asynGetImageFromAssetID(id: String,finised:@escaping (UIImage)->Void) {
        if let asset = getPHAsssetwithID(ids: [id]) {
            let imageManager = PHImageManager.default()
            let targetSize = CGSize(width: 400, height: 400)
            let options = PHImageRequestOptions()
            options.isSynchronous = false
            options.deliveryMode = .opportunistic
            options.isNetworkAccessAllowed = true
            imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: options) { result, _ in
                finised(result ?? UIImage())
            }
        }else {
            finised(UIImage())
        }
    }
    
    /// 获取视频第一帧
    /// - Parameters:
    ///   - ident: 视频的标识
    ///   - finished: 完成回调
    func getVideoImageByIdent(ident: AssetModel,finished:@escaping (UIImage)->Void,errorHandler:@escaping ()->Void){
        // 定义请求选项来获取视频的第一帧
        let options = PHImageRequestOptions()
        // 获取当前版本的照片或视频
        options.version = .current
        // 尽可能快地提供结果
        options.deliveryMode = .highQualityFormat
        // 允许从iCloud请求
        options.isNetworkAccessAllowed = true
        // 异步请求
        options.isSynchronous = false
        // 从 PHAsset 获取 AVAsset
        if let videoAsset = getPHAsssetwithID(ids: [ident.localIdentifier]){
            // 使用requestImageForAsset方法请求视频的第一帧图片
            PHImageManager.default().requestImage(for: videoAsset, targetSize: CGSize(width: 400, height: 400), contentMode: PHImageContentMode.aspectFit, options: options) { image, _ in
                // 处理获取到的图片
                if let thumbnailImage = image {
                    // 使用获取到的图片，例如显示在UIImageView上
                    finished(thumbnailImage)
                } else {
                    errorHandler()
                }
            }
        }
    }
}
