//
//  AssetModel.swift
//  CleanPhoto
//
//  Created by edy on 2025/5/7.
//

import Foundation


struct AssetModel :Codable,Hashable {
    var localIdentifier : String
    var assetSize : Double
    var createDate : Date
    var mediaType:Int? // 1 图片 2视频
    
    
    init(localIdentifier: String, assetSize: Double, createDate: Date,mediaType:Int = 1) {
        self.localIdentifier = localIdentifier
        self.assetSize = assetSize
        self.createDate = createDate
        self.mediaType = mediaType
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(localIdentifier)
        hasher.combine(assetSize)
        hasher.combine(createDate)
        hasher.combine(mediaType)
    }
   
    static func ==(lhs: AssetModel, rhs: AssetModel) -> Bool {
        return lhs.localIdentifier == rhs.localIdentifier &&
        lhs.assetSize == rhs.assetSize &&
        lhs.createDate == rhs.createDate && lhs.mediaType == rhs.mediaType
    }

}


struct AssetFileModel:Codable{
    var videoAssets:[AssetModel] = []
    var otherAssets:[AssetModel] = []
    var screenShotAssets:[AssetModel] = []
    var photosAssets:[AssetModel] = []
}


// 添加媒体类型枚举
enum MediaType {
    case video
    case screenshot
    case photo
    case other
}

extension MediaType{
    
    var dbValue:String{
        switch self {
        case .video:
            return "video"
        case .screenshot:
            return "screenshot"
        case .photo:
            return "photo"
        case .other:
            return "other"
        }
    }
}



// 时间组模型
struct TimeGroupModel: Codable {
    let groupId: String
    let startTime: TimeInterval
    let endTime: TimeInterval
    var isProcessed: Bool
}

// 相似图片组模型
struct SimilarGroupModel: Codable {
    let groupId: String
    var assets: [AssetModel]
}


struct Match {
     let groupIndex: Int
     let matchedElements: [AssetModel]
 }

struct RemovalResult {
    let updatedGroups: [SimilarGroupModel]
    let removedAssets: [AssetModel]
    let removedGroups: [SimilarGroupModel]
}

extension Sequence where Element == [AssetModel] {
    
    /// 判断二维数组中是否包含某个子数组，其元素的localIdentifier集合与给定数组完全相同（忽略顺序）
    func containsGroup(matching elements: [AssetModel]) -> Bool {
        let targetIDs = Set(elements.map { $0.localIdentifier })
        
        return self.contains { group in
            let groupIDs = Set(group.map { $0.localIdentifier })
            return groupIDs == targetIDs
        }
    }
    
    
    func matches(containingAny elements: [AssetModel]) -> [Match] {
         let targetIDs = Set(elements.map { $0.localIdentifier })
         var matches = [Match]()
         
         for (index, group) in self.enumerated() {
             let matched = group.filter { targetIDs.contains($0.localIdentifier) }
             if !matched.isEmpty {
                 matches.append(Match(groupIndex: index, matchedElements: matched))
             }
         }
         
         return matches
     }
}


extension SimilarGroupModel {
    /// 过滤掉assets中包含指定ID的元素
    func removingAssets(withIDs ids: Set<String>) -> SimilarGroupModel {
        let filteredAssets = self.assets.filter { !ids.contains($0.localIdentifier) }
        return SimilarGroupModel(groupId: self.groupId, assets: filteredAssets)
    }
}

extension Array where Element == SimilarGroupModel {
    
    /// 批量过滤所有组中的assets，移除包含指定ID的元素，并移除assets为空的组
    func removingGroupsWithEmptyAssets(afterRemovingIDs ids: [String]) -> [SimilarGroupModel] {
        let idSet = Set(ids)
        return self.compactMap { group in
            let filteredGroup = group.removingAssets(withIDs: idSet)
            return filteredGroup.assets.isEmpty ? nil : filteredGroup
        }
    }
    
    /// 原地修改：直接在原数组上移除包含指定ID的元素，并移除assets为空的组
    mutating func removeGroupsWithEmptyAssetsInPlace(afterRemovingIDs ids: [String]) {
        self = self.removingGroupsWithEmptyAssets(afterRemovingIDs: ids)
    }
    
    /// 删除日志，拿到执行删除后的更新数据，删除数据，移除的组
    func removingGroupsWithEmptyAssetsWithDetails(afterRemovingIDs ids: [String]) -> RemovalResult {
        let idSet = Set(ids)
        var removedAssets = [AssetModel]()
        var removedGroups = [SimilarGroupModel]()
        
        let updated = self.compactMap { (group: SimilarGroupModel) -> SimilarGroupModel? in
            let filteredAssets = group.assets.filter { !idSet.contains($0.localIdentifier) }
            let removedInGroup = group.assets.filter { idSet.contains($0.localIdentifier) }
            
            removedAssets.append(contentsOf: removedInGroup)
            
            // 修改判断条件：当assets数量小于2时移除整个组
            if filteredAssets.count < 2 {
                removedGroups.append(group)
                return nil
            } else {
                return SimilarGroupModel(groupId: group.groupId, assets: filteredAssets)
            }
        }
        
        return RemovalResult(
            updatedGroups: updated,
            removedAssets: removedAssets,
            removedGroups: removedGroups
        )
    }
}


extension Sequence where Element == [AssetModel] {
    /// 删除二维数组中包含指定ID的元素，并移除所有元素数量少于2的子数组
    func removingElementsAndSmallGroups(ids: [String]) -> [[AssetModel]] {
        let idSet = Set(ids)
        return self.compactMap { group in
            let filtered = group.filter { !idSet.contains($0.localIdentifier) }
            return filtered.count < 2 ? nil : filtered  // 修改判断条件
        }
    }
}


enum PrivacyType:String {

    case authorized = "authorized"
    case notDetermined = "notDetermined"
    case denied = "denied"
    case restricted = "restricted"
}

enum PhotsFileType:String {
    
    case duplicates = "Duplicates"
    case similar = "Similar"
    case videos = "Videos"
    case similarScreenshots = "Similar Screenshots"
    case screenshots = "Screenshots"
    case SimilarVideos = "Similar Videos"
    case Other = "Other"
}
