import Foundation
import UIKit

// 图片加载进度回调
typealias ImageLoadingProgress = (Double) -> Void
// 图片加载完成回调
typealias ImageCompletion = (UIImage?, Error?) -> Void

/// 头像样式
enum AvatarStyle {
    case circle          // 圆形
    case rounded(radius: CGFloat)  // 圆角矩形
}

/// 图片加载工具类（含缓存功能，支持头像专用圆角处理）
class ImageLoader {
    // 单例模式
    static let shared = ImageLoader()
    
    // 内存缓存（LRU策略）
    private let memoryCache = NSCache<NSString, UIImage>()
    // 磁盘缓存路径
    private let diskCachePath: String
    // 最大内存缓存大小（默认100MB）
    private let maxMemoryCacheSize: Int64 = 100 * 1024 * 1024
    // 最大磁盘缓存大小（默认200MB）
    private let maxDiskCacheSize: Int64 = 200 * 1024 * 1024
    
    // 初始化
    private init() {
        // 创建磁盘缓存目录
        let documentsPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
        diskCachePath = "\(documentsPath)/ImageCache"
        
        // 配置内存缓存
        memoryCache.countLimit = 100 // 最多缓存100张图片
        memoryCache.totalCostLimit = Int(maxMemoryCacheSize)
        
        // 清理过期的磁盘缓存
        cleanExpiredDiskCache()
    }
    
    /// 加载头像图片（带缓存）
    func loadAvatar(
        from url: URL,
        placeholder: UIImage? = nil,
        style: AvatarStyle = .circle,
        progress: ImageLoadingProgress? = nil,
        completion: @escaping ImageCompletion
    ) -> UIImage? {
        // 生成缓存键（包含样式信息）
        let cacheKey = generateAvatarCacheKey(url: url, style: style)
        
        // 先检查内存缓存
        if let cachedImage = memoryCache.object(forKey: cacheKey) {
            return cachedImage
        }
        
        // 检查磁盘缓存
        if let cachedImage = loadAvatarFromDiskCache(url: url, style: style) {
            memoryCache.setObject(cachedImage, forKey: cacheKey)
            return cachedImage
        }
        
        // 显示占位图
        completion(placeholder, nil)
        return placeholder
    }
    
    /// 异步加载头像图片（带进度监听）
    func loadAvatarAsync(
        from url: URL,
        placeholder: UIImage? = nil,
        style: AvatarStyle = .circle,
        progress: ImageLoadingProgress? = nil,
        completion: @escaping ImageCompletion
    ) {
        // 生成缓存键（包含样式信息）
        let cacheKey = generateAvatarCacheKey(url: url, style: style)
        
        // 先检查内存缓存
        if let cachedImage = memoryCache.object(forKey: cacheKey) {
            DispatchQueue.main.async {
                completion(cachedImage, nil)
            }
            return
        }
        
        // 检查磁盘缓存
        if let cachedImage = loadAvatarFromDiskCache(url: url, style: style) {
            memoryCache.setObject(cachedImage, forKey: cacheKey)
            DispatchQueue.main.async {
                completion(cachedImage, nil)
            }
            return
        }
        
        // 显示占位图
        DispatchQueue.main.async {
            completion(placeholder, nil)
        }
        
        // 从网络加载图片
        let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            guard let self = self,
                  let data = data,
                  error == nil,
                  let response = response as? HTTPURLResponse,
                  response.statusCode == 200,
                  let image = UIImage(data: data) else {
                DispatchQueue.main.async {
                    completion(nil, error)
                }
                return
            }
            
            // 应用头像样式处理
            let processedImage = self.processAvatar(image: image, style: style)
            
            // 保存到缓存
            self.saveAvatarToCache(image: processedImage, url: url, style: style)
            
            DispatchQueue.main.async {
                completion(processedImage, nil)
            }
        }
        
        task.resume()
    }
    
    /// 生成头像缓存键
    private func generateAvatarCacheKey(url: URL, style: AvatarStyle) -> NSString {
        let styleKey: String
        switch style {
        case .circle:
            styleKey = "circle"
        case .rounded(let radius):
            styleKey = "rounded_\(radius)"
        }
        return "\(url.absoluteString)_\(styleKey)" as NSString
    }
    
    /// 从磁盘缓存加载头像
    private func loadAvatarFromDiskCache(url: URL, style: AvatarStyle) -> UIImage? {
        let fileName = generateAvatarFileName(url: url, style: style)
        let filePath = "\(diskCachePath)/\(fileName)"
        
        if let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) {
            return UIImage(data: data)
        }
        
        return nil
    }
    
    /// 生成头像文件名
    private func generateAvatarFileName(url: URL, style: AvatarStyle) -> String {
        let baseFileName = url.lastPathComponent
        let styleKey: String
        
        switch style {
        case .circle:
            styleKey = "avatar_circle"
        case .rounded(let radius):
            styleKey = "avatar_rounded_\(radius)"
        }
        
        return "\(styleKey)_\(baseFileName)"
    }
    
    /// 保存头像到缓存
    private func saveAvatarToCache(image: UIImage, url: URL, style: AvatarStyle) {
        // 保存到内存缓存
        let cacheKey = generateAvatarCacheKey(url: url, style: style)
        memoryCache.setObject(image, forKey: cacheKey)
        
        // 保存到磁盘缓存
        DispatchQueue.global(qos: .background).async { [weak self] in
            guard let self = self else { return }
            
            // 创建缓存目录（如果不存在）
            if !FileManager.default.fileExists(atPath: self.diskCachePath) {
                do {
                    try FileManager.default.createDirectory(atPath: self.diskCachePath, withIntermediateDirectories: true)
                } catch {
                    return
                }
            }
            
            let fileName = self.generateAvatarFileName(url: url, style: style)
            let filePath = "\(self.diskCachePath)/\(fileName)"
            
            // 压缩图片（JPEG格式，质量0.8）
            if let data = image.jpegData(compressionQuality: 0.8) {
                do {
                    try data.write(to: URL(fileURLWithPath: filePath), options: .atomic)
                    self.updateDiskCacheSize()
                } catch {
                    //print("保存头像到磁盘失败: \(error)")
                }
            }
        }
    }
    
    /// 处理头像样式
    private func processAvatar(image: UIImage, style: AvatarStyle) -> UIImage {
        // 优化：如果是圆形且图片已经是正方形，直接使用CoreImage滤镜
        if case .circle = style, image.size.width == image.size.height {
            return applyCircularFilter(image: image)
        }
        
        // 否则使用传统绘图方式
        return applyAvatarStyle(image: image, style: style)
    }
    
    /// 应用圆形滤镜（性能优化）
    private func applyCircularFilter(image: UIImage) -> UIImage {
        guard let cgImage = image.cgImage,
              let filter = CIFilter(name: "CICropToCircle") else {
            return image
        }
        
        let ciImage = CIImage(cgImage: cgImage)
        filter.setValue(ciImage, forKey: kCIInputImageKey)
        
        if let outputImage = filter.outputImage,
           let outputCGImage = CIContext().createCGImage(outputImage, from: outputImage.extent) {
            return UIImage(cgImage: outputCGImage, scale: image.scale, orientation: image.imageOrientation)
        }
        
        return image
    }
    
    /// 应用头像样式（传统绘图方式）
    private func applyAvatarStyle(image: UIImage, style: AvatarStyle) -> UIImage {
        let size = image.size
        let rect = CGRect(origin: .zero, size: size)
        let cornerRadius: CGFloat
        
        switch style {
        case .circle:
            cornerRadius = min(size.width, size.height) / 2
        case .rounded(let radius):
            cornerRadius = radius
        }
        
        UIGraphicsBeginImageContextWithOptions(size, false, image.scale)
        defer { UIGraphicsEndImageContext() }
        
        let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
        path.addClip()
        
        image.draw(in: rect)
        
        if let outputImage = UIGraphicsGetImageFromCurrentImageContext() {
            return outputImage
        }
        
        return image
    }
    
    /// 更新磁盘缓存大小
    private func updateDiskCacheSize() {
        // 保持原有逻辑不变...
        do {
            let fileManager = FileManager.default
            let cacheFiles = try fileManager.contentsOfDirectory(atPath: diskCachePath)
            
            var totalSize: Int64 = 0
            for file in cacheFiles {
                let filePath = "\(diskCachePath)/\(file)"
                if let attributes = try? fileManager.attributesOfItem(atPath: filePath),
                   let size = attributes[.size] as? Int64 {
                    totalSize += size
                }
            }
            
            // 如果超过最大缓存大小，清理旧文件
            if totalSize > maxDiskCacheSize {
                cleanOldestDiskCacheFiles(untilSize: totalSize - maxDiskCacheSize)
            }
        } catch {
            //print("更新磁盘缓存大小失败: \(error)")
        }
    }
    
    /// 清理最旧的磁盘缓存文件
    private func cleanOldestDiskCacheFiles(untilSize: Int64) {
        // 保持原有逻辑不变...
        guard untilSize > 0 else { return }
        
        do {
            let fileManager = FileManager.default
            var files: [(path: String, date: Date)] = []
            
            // 获取所有缓存文件及其修改日期
            for file in try fileManager.contentsOfDirectory(atPath: diskCachePath) {
                let filePath = "\(diskCachePath)/\(file)"
                if let attributes = try? fileManager.attributesOfItem(atPath: filePath),
                   let date = attributes[.modificationDate] as? Date,
                   let size = attributes[.size] as? Int64,
                   size > 0 {
                    files.append((path: filePath, date: date))
                }
            }
            
            // 按修改日期排序（最旧的在前）
            files.sort { $0.date < $1.date }
            
            // 删除最旧的文件，直到达到目标大小
            var removedSize: Int64 = 0
            for file in files {
                if removedSize >= untilSize { break }
                
                do {
                    let attributes = try fileManager.attributesOfItem(atPath: file.path)
                    if let size = attributes[.size] as? Int64 {
                        try fileManager.removeItem(atPath: file.path)
                        removedSize += size
                    }
                } catch {
                    //print("删除缓存文件失败: \(error)")
                }
            }
        } catch {
            //print("清理磁盘缓存失败: \(error)")
        }
    }
    
    /// 清理过期的磁盘缓存
    private func cleanExpiredDiskCache() {
        // 保持原有逻辑不变...
        // 这里可以添加清理逻辑，例如删除超过30天的缓存
        let oneMonthAgo = Date().addingTimeInterval(-30 * 24 * 60 * 60)
        
        do {
            let fileManager = FileManager.default
            for file in try fileManager.contentsOfDirectory(atPath: diskCachePath) {
                let filePath = "\(diskCachePath)/\(file)"
                if let attributes = try? fileManager.attributesOfItem(atPath: filePath),
                   let date = attributes[.modificationDate] as? Date,
                   date < oneMonthAgo {
                    try fileManager.removeItem(atPath: filePath)
                }
            }
        } catch {
            //print("清理过期缓存失败: \(error)")
        }
    }
    
    /// 清除所有缓存
    func clearAllCache(completion: (() -> Void)? = nil) {
        // 保持原有逻辑不变...
        // 清除内存缓存
        memoryCache.removeAllObjects()
        
        // 清除磁盘缓存
        DispatchQueue.global(qos: .background).async { [weak self] in
            guard let self = self else { return }
            
            do {
                if FileManager.default.fileExists(atPath: self.diskCachePath) {
                    try FileManager.default.removeItem(atPath: self.diskCachePath)
                    // 重新创建空目录
                    try FileManager.default.createDirectory(atPath: self.diskCachePath, withIntermediateDirectories: true)
                }
            } catch {
                //print("清除磁盘缓存失败: \(error)")
            }
            
            DispatchQueue.main.async {
                completion?()
            }
        }
    }
}
