import UIKit
import Foundation
import Combine

// MARK: - 图片缓存管理器
class ImageCacheManager: ObservableObject {
    static let shared = ImageCacheManager()
    
    private let cache = NSCache<NSString, UIImage>()
    private let fileManager = FileManager.default
    private let documentsPath: String
    
    init() {
        // 设置缓存限制
        cache.countLimit = 50 // 限制缓存数量
        cache.totalCostLimit = 50 * 1024 * 1024 // 限制缓存大小（50MB）
        
        // 获取文档目录路径
        documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        
        // 监听内存警告
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleMemoryWarning),
            name: UIApplication.didReceiveMemoryWarningNotification,
            object: nil
        )
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // MARK: - 内存缓存管理
    
    /// 设置图片到内存缓存
    func setImage(_ image: UIImage, forKey key: String) {
        cache.setObject(image, forKey: key as NSString)
    }
    
    /// 从内存缓存获取图片
    func getImage(forKey key: String) -> UIImage? {
        return cache.object(forKey: key as NSString)
    }
    
    /// 从内存缓存移除图片
    func removeImage(forKey key: String) {
        cache.removeObject(forKey: key as NSString)
    }
    
    /// 清空内存缓存
    func clearCache() {
        cache.removeAllObjects()
        print("🧹 图片内存缓存已清空")
    }
    
    // MARK: - 文件缓存管理
    
    /// 保存图片到文件系统
    func saveImageToFile(_ image: UIImage, withName name: String) -> String? {
        let imagePath = (documentsPath as NSString).appendingPathComponent("\(name).jpg")
        
        if let imageData = image.jpegData(compressionQuality: 0.8) {
            do {
                try imageData.write(to: URL(fileURLWithPath: imagePath))
                print("💾 图片已保存到文件: \(imagePath)")
                return imagePath
            } catch {
                print("❌ 保存图片失败: \(error)")
                return nil
            }
        }
        return nil
    }
    
    /// 从文件系统加载图片
    func loadImageFromFile(path: String) -> UIImage? {
        return UIImage(contentsOfFile: path)
    }
    
    /// 删除文件系统中的图片
    func deleteImageFromFile(path: String) {
        do {
            try fileManager.removeItem(atPath: path)
            print("🗑️ 图片文件已删除: \(path)")
        } catch {
            print("❌ 删除图片文件失败: \(error)")
        }
    }
    
    /// 清理过期的文件缓存
    func cleanupExpiredFiles() {
        let imageCachePath = (documentsPath as NSString).appendingPathComponent("ImageCache")
        
        do {
            let files = try fileManager.contentsOfDirectory(atPath: imageCachePath)
            let currentDate = Date()
            
            for file in files {
                let filePath = (imageCachePath as NSString).appendingPathComponent(file)
                let attributes = try fileManager.attributesOfItem(atPath: filePath)
                
                if let creationDate = attributes[.creationDate] as? Date {
                    // 删除7天前的文件
                    if currentDate.timeIntervalSince(creationDate) > 7 * 24 * 60 * 60 {
                        try fileManager.removeItem(atPath: filePath)
                        print("🗑️ 删除过期文件: \(file)")
                    }
                }
            }
        } catch {
            print("❌ 清理过期文件失败: \(error)")
        }
    }
    
    // MARK: - 智能缓存管理
    
    /// 智能获取图片（先查内存缓存，再查文件缓存）
    func getImageIntelligently(forKey key: String) -> UIImage? {
        // 1. 先查内存缓存
        if let cachedImage = getImage(forKey: key) {
            return cachedImage
        }
        
        // 2. 再查文件缓存
        let imagePath = (documentsPath as NSString).appendingPathComponent("\(key).jpg")
        if let fileImage = loadImageFromFile(path: imagePath) {
            // 加载到内存缓存
            setImage(fileImage, forKey: key)
            return fileImage
        }
        
        return nil
    }
    
    /// 智能保存图片（同时保存到内存和文件）
    func saveImageIntelligently(_ image: UIImage, forKey key: String) {
        // 1. 保存到内存缓存
        setImage(image, forKey: key)
        
        // 2. 保存到文件缓存
        _ = saveImageToFile(image, withName: key)
    }
    
    // MARK: - 内存警告处理
    
    @objc private func handleMemoryWarning() {
        print("🚨 收到内存警告，清理图片缓存")
        clearCache()
    }
    
    // MARK: - 缓存统计
    
    /// 获取缓存统计信息
    func getCacheStatistics() -> (memoryCount: Int, memorySize: String, fileCount: Int) {
        let memoryCount = cache.totalCostLimit > 0 ? cache.totalCostLimit : 0
        let memorySize = ByteCountFormatter.string(fromByteCount: Int64(memoryCount), countStyle: .memory)
        
        let imageCachePath = (documentsPath as NSString).appendingPathComponent("ImageCache")
        var fileCount = 0
        
        do {
            let files = try fileManager.contentsOfDirectory(atPath: imageCachePath)
            fileCount = files.count
        } catch {
            fileCount = 0
        }
        
        return (memoryCount, memorySize, fileCount)
    }
    
    /// 打印缓存统计信息
    func printCacheStatistics() {
        let stats = getCacheStatistics()
        print("📊 图片缓存统计:")
        print("   - 内存缓存数量: \(stats.memoryCount)")
        print("   - 内存缓存大小: \(stats.memorySize)")
        print("   - 文件缓存数量: \(stats.fileCount)")
    }
}

// MARK: - 图片压缩工具
extension ImageCacheManager {
    
    /// 压缩图片到指定大小
    func compressImage(_ image: UIImage, maxSize: CGSize) -> UIImage {
        let originalSize = image.size
        
        // 如果图片已经小于最大尺寸，直接返回
        if originalSize.width <= maxSize.width && originalSize.height <= maxSize.height {
            return image
        }
        
        // 计算缩放比例
        let scaleX = maxSize.width / originalSize.width
        let scaleY = maxSize.height / originalSize.height
        let scale = min(scaleX, scaleY)
        
        let newSize = CGSize(width: originalSize.width * scale, height: originalSize.height * scale)
        
        // 重新渲染图片
        let renderer = UIGraphicsImageRenderer(size: newSize)
        return renderer.image { context in
            image.draw(in: CGRect(origin: .zero, size: newSize))
        }
    }
    
    /// 压缩图片到指定文件大小
    func compressImageToFileSize(_ image: UIImage, targetSizeInKB: Double) -> UIImage {
        let targetSizeInBytes = Int64(targetSizeInKB * 1024)
        
        // 尝试不同的压缩质量
        let compressionQualities: [CGFloat] = [0.8, 0.6, 0.4, 0.2, 0.1, 0.05]
        
        for quality in compressionQualities {
            if let imageData = image.jpegData(compressionQuality: quality) {
                let dataSize = Int64(imageData.count)
                
                if dataSize <= targetSizeInBytes {
                    if let compressedImage = UIImage(data: imageData) {
                        print("✅ 图片压缩成功: \(dataSize) bytes (质量: \(quality))")
                        return compressedImage
                    }
                }
            }
        }
        
        // 如果JPEG压缩仍然太大，尝试缩小尺寸
        print("⚠️ JPEG压缩后仍超过目标大小，尝试缩小尺寸")
        return compressImageByReducingSize(image, targetSizeInBytes: targetSizeInBytes)
    }
    
    /// 通过缩小尺寸来压缩图片
    private func compressImageByReducingSize(_ image: UIImage, targetSizeInBytes: Int64) -> UIImage {
        let originalSize = image.size
        let originalWidth = originalSize.width
        let originalHeight = originalSize.height
        
        // 计算当前图片的内存大小
        let currentMemorySize = Int64(originalWidth * originalHeight * 4) // 假设RGBA格式
        
        // 计算需要的缩放比例
        let scaleFactor = sqrt(Double(targetSizeInBytes) / Double(currentMemorySize))
        let newWidth = max(originalWidth * CGFloat(scaleFactor), 40) // 最小40像素
        let newHeight = max(originalHeight * CGFloat(scaleFactor), 40)
        
        let newSize = CGSize(width: newWidth, height: newHeight)
        
        // 重新渲染到新尺寸
        let renderer = UIGraphicsImageRenderer(size: newSize)
        let resizedImage = renderer.image { context in
            image.draw(in: CGRect(origin: .zero, size: newSize))
        }
        
        // 再次尝试JPEG压缩
        if let imageData = resizedImage.jpegData(compressionQuality: 0.3) {
            let finalSize = Int64(imageData.count)
            print("✅ 通过缩小尺寸压缩成功: \(finalSize) bytes (新尺寸: \(newWidth) x \(newHeight))")
            
            if let finalImage = UIImage(data: imageData) {
                return finalImage
            }
        }
        
        // 如果还是太大，返回最小尺寸的图片
        print("⚠️ 无法压缩到目标大小，返回最小尺寸图片")
        let minSize = CGSize(width: 40, height: 40)
        let rendererMin = UIGraphicsImageRenderer(size: minSize)
        return rendererMin.image { context in
            image.draw(in: CGRect(origin: .zero, size: minSize))
        }
    }
}
