import Foundation
import UIKit

/// 图片上传服务，封装了图片上传和进度跟踪功能
public class ImageUploadService {
    
    // MARK: - Shared Instance
    
    public static let shared = ImageUploadService()
    
    // MARK: - Properties
    
    private let uploader: ImageUploaderGetID
    
    // MARK: - Initialization
    
    public init(uploader: ImageUploaderGetID = ImageUploaderGetID()) {
        self.uploader = uploader
    }
    
    // MARK: - Public Methods
    
    /// 上传图片并返回上传结果
    /// - Parameters:
    ///   - image: 要上传的图片
    ///   - progressHandler: 上传进度回调 (0.0 到 1.0)
    ///   - completion: 完成回调，返回上传结果或错误
    public func uploadImage(
        _ image: UIImage,
        progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
        completion: @escaping (Result<ImageUploaderGetID.UploadResult, Error>) -> Void
    ) {
        uploader.uploadImage(
            image,
            progress: { progress in
                let progressInfo = ImageUploadService.UploadProgress(
                    current: Int(progress * 100),
                    total: 100,
                    progress: progress,
                    isOriginal: true
                )
                DispatchQueue.main.async {
                    progressHandler(progressInfo)
                }
            },
            completion: { result in
                DispatchQueue.main.async {
                    completion(result)
                }
            }
        )
    }
    
    /// 上传压缩图片并返回上传结果
    /// - Parameters:
    ///   - image: 要上传的图片
    ///   - compressionQuality: 压缩质量 (0.0 到 1.0)
    ///   - progressHandler: 上传进度回调 (0.0 到 1.0)
    ///   - completion: 完成回调，返回上传结果或错误
    public func uploadCompressedImage(
        _ image: UIImage,
        compressionQuality: CGFloat = 0.5,
        progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
        completion: @escaping (Result<ImageUploaderGetID.UploadResult, Error>) -> Void
    ) {
        guard let compressedImage = image.jpegData(compressionQuality: compressionQuality).flatMap(UIImage.init(data:)) else {
            completion(.failure(NSError(domain: "com.wake.upload", code: -1, userInfo: [NSLocalizedDescriptionKey: "图片压缩失败"])))
            return
        }
        
        uploadImage(
            compressedImage,
            progress: progressHandler,
            completion: completion
        )
    }
    
    /// 上传原图和压缩图
    /// - Parameters:
    ///   - image: 原始图片
    ///   - compressionQuality: 压缩质量 (0.0 到 1.0)
    ///   - progressHandler: 上传进度回调
    ///   - completion: 完成回调，返回原始图和压缩图的上传结果
    public func uploadOriginalAndCompressedImage(
        _ image: UIImage,
        compressionQuality: CGFloat = 0.5,
        progress progressHandler: @escaping (ImageUploadService.UploadProgress) -> Void,
        completion: @escaping (Result<ImageUploadService.UploadResults, Error>) -> Void
    ) {
        // 上传原图
        uploadImage(image, progress: { progress in
            let originalProgress = ImageUploadService.UploadProgress(
                current: Int(progress.progress * 100),
                total: 200, // 总进度为200（原图100 + 压缩图100）
                progress: progress.progress * 0.5, // 原图占50%
                isOriginal: true
            )
            progressHandler(originalProgress)
        }) { [weak self] originalResult in
            guard let self = self else { return }
            
            switch originalResult {
            case .success(let originalUploadResult):
                // 原图上传成功，上传压缩图
                self.uploadCompressedImage(
                    image,
                    compressionQuality: compressionQuality,
                    progress: { progress in
                        let compressedProgress = ImageUploadService.UploadProgress(
                            current: 100 + Int(progress.progress * 100), // 从100开始
                            total: 200, // 总进度为200（原图100 + 压缩图100）
                            progress: 0.5 + (progress.progress * 0.5), // 压缩图占后50%
                            isOriginal: false
                        )
                        progressHandler(compressedProgress)
                    },
                    completion: { compressedResult in
                        switch compressedResult {
                        case .success(let compressedUploadResult):
                            let results = ImageUploadService.UploadResults(
                                original: originalUploadResult,
                                compressed: compressedUploadResult
                            )
                            completion(.success(results))
                            
                        case .failure(let error):
                            completion(.failure(error))
                        }
                    }
                )
                
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }
    
    // MARK: - Unified Media Upload
    
    /// 上传媒体文件（图片或视频）
    /// - Parameters:
    ///   - media: 媒体类型，可以是图片或视频
    ///   - progress: 上传进度回调 (0.0 到 1.0)
    ///   - completion: 完成回调，返回上传结果或错误
    public func uploadMedia(
        _ media: MediaType,
        progress: @escaping (UploadProgress) -> Void,
        completion: @escaping (Result<MediaUploadResult, Error>) -> Void
    ) {
        switch media {
        case .image(let image):
            print("🖼️ 开始处理图片上传")
            uploadImage(
                image,
                progress: { progressInfo in
                    print("📊 图片上传进度: \(progressInfo.current)%")
                    progress(progressInfo)
                },
                completion: { result in
                    switch result {
                    case .success(let uploadResult):
                        print("✅ 图片上传完成, fileId: \(uploadResult.fileId)")
                        completion(.success(.file(uploadResult)))
                    case .failure(let error):
                        print("❌ 图片上传失败: \(error.localizedDescription)")
                        completion(.failure(error))
                    }
                }
            )
            
        case .video(let videoURL, _):
            print("🎥 开始处理视频上传: \(videoURL.lastPathComponent)")
            
            uploader.uploadVideo(
                videoURL,
                progress: { uploadProgress in
                    print("📊 视频上传进度: \(Int(uploadProgress * 100))%")
                    let progressInfo = UploadProgress(
                        current: Int(uploadProgress * 100),
                        total: 100,
                        progress: uploadProgress,
                        isOriginal: true
                    )
                    progress(progressInfo)
                },
                completion: { result in
                    switch result {
                    case .success(let videoResult):
                        print("✅ 视频文件上传完成, fileId: \(videoResult.fileId)")
                        print("🖼️ 开始提取视频缩略图...")
                        
                        MediaUtils.extractFirstFrame(from: videoURL) { thumbnailResult in
                            switch thumbnailResult {
                            case .success(let thumbnailImage):
                                print("🖼️ 视频缩略图提取成功")
                                
                                if let compressedThumbnail = thumbnailImage.resized(to: CGSize(width: 800, height: 800)) {
                                    print("🖼️ 开始上传视频缩略图...")
                                    
                                    self.uploader.uploadImage(
                                        compressedThumbnail,
                                        progress: { _ in },
                                        completion: { thumbnailResult in
                                            switch thumbnailResult {
                                            case .success(let thumbnailUploadResult):
                                                print("✅ 视频缩略图上传完成, fileId: \(thumbnailUploadResult.fileId)")
                                                let result = MediaUploadResult.video(
                                                    video: videoResult,
                                                    thumbnail: thumbnailUploadResult
                                                )
                                                completion(.success(result))
                                                
                                            case .failure(let error):
                                                print("❌ 视频缩略图上传失败: \(error.localizedDescription)")
                                                completion(.failure(error))
                                            }
                                        }
                                    )
                                } else {
                                    let error = NSError(domain: "ImageUploadService", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to compress thumbnail"])
                                    print("❌ 视频缩略图压缩失败")
                                    completion(.failure(error))
                                }
                                
                            case .failure(let error):
                                print("❌ 视频缩略图提取失败: \(error.localizedDescription)")
                                completion(.failure(error))
                            }
                        }
                        
                    case .failure(let error):
                        print("❌ 视频文件上传失败: \(error.localizedDescription)")
                        completion(.failure(error))
                    }
                }
            )
        }
    }
    
    /// 上传视频及其缩略图
    private func uploadVideoWithThumbnail(
        videoURL: URL,
        existingThumbnail: UIImage?,
        compressionQuality: CGFloat,
        progress progressHandler: @escaping (UploadProgress) -> Void,
        completion: @escaping (Result<MediaUploadResult, Error>) -> Void
    ) {
        // 1. 提取视频缩略图
        func processThumbnail(_ thumbnail: UIImage) {
            // 2. 压缩缩略图
            guard let compressedThumbnail = thumbnail.jpegData(compressionQuality: compressionQuality).flatMap(UIImage.init(data:)) else {
                let error = NSError(domain: "com.wake.upload", code: -1, userInfo: [NSLocalizedDescriptionKey: "缩略图压缩失败"])
                completion(.failure(error))
                return
            }
            
            // 3. 上传视频文件
            let videoProgress = Progress(totalUnitCount: 100)
            let thumbnailProgress = Progress(totalUnitCount: 100)
            
            // 组合进度
            let totalProgress = Progress(totalUnitCount: 200) // 视频100 + 缩略图100
            totalProgress.addChild(videoProgress, withPendingUnitCount: 100)
            totalProgress.addChild(thumbnailProgress, withPendingUnitCount: 100)
            
            // 上传视频
            self.uploader.uploadVideo(
                videoURL,
                progress: { progress in
                    videoProgress.completedUnitCount = Int64(progress * 100)
                    let currentProgress = Double(totalProgress.completedUnitCount) / 200.0
                    progressHandler(UploadProgress(
                        current: Int(progress * 100),
                        total: 100,
                        progress: currentProgress,
                        isOriginal: true
                    ))
                },
                completion: { videoResult in
                    switch videoResult {
                    case .success(let videoUploadResult):
                        // 4. 上传缩略图
                        self.uploadCompressedImage(
                            compressedThumbnail,
                            compressionQuality: 1.0, // 已经压缩过，不再压缩
                            progress: { progress in
                                thumbnailProgress.completedUnitCount = Int64(progress.progress * 100)
                                let currentProgress = Double(totalProgress.completedUnitCount) / 200.0
                                progressHandler(UploadProgress(
                                    current: 100 + Int(progress.progress * 100),
                                    total: 200,
                                    progress: currentProgress,
                                    isOriginal: false
                                ))
                            },
                            completion: { thumbnailResult in
                                switch thumbnailResult {
                                case .success(let thumbnailUploadResult):
                                    let result = MediaUploadResult.video(
                                        video: videoUploadResult,
                                        thumbnail: thumbnailUploadResult
                                    )
                                    completion(.success(result))
                                    
                                case .failure(let error):
                                    completion(.failure(error))
                                }
                            }
                        )
                        
                    case .failure(let error):
                        completion(.failure(error))
                    }
                }
            )
        }
        
        // 如果已有缩略图，直接使用
        if let thumbnail = existingThumbnail {
            processThumbnail(thumbnail)
        } else {
            // 否则提取第一帧作为缩略图
            MediaUtils.extractFirstFrame(from: videoURL) { result in
                switch result {
                case .success(let thumbnail):
                    processThumbnail(thumbnail)
                case .failure(let error):
                    completion(.failure(error))
                }
            }
        }
    }
    
    // MARK: - Supporting Types
    
    /// 媒体类型
    public enum MediaType {
        case image(UIImage)
        case video(URL, UIImage?)
    }
    
    /// 媒体上传结果
    public enum MediaUploadResult {
        case file(ImageUploaderGetID.UploadResult)
        case video(video: ImageUploaderGetID.UploadResult, thumbnail: ImageUploaderGetID.UploadResult)
        
        /// 获取文件ID（对于视频，返回视频文件的ID）
        public var fileId: String {
            switch self {
            case .file(let result):
                return result.fileId
            case .video(let videoResult, _):
                return videoResult.fileId
            }
        }
    }
    
    /// 上传进度信息
    public struct UploadProgress {
        public let current: Int
        public let total: Int
        public let progress: Double
        public let isOriginal: Bool
        
        public init(current: Int, total: Int, progress: Double, isOriginal: Bool) {
            self.current = current
            self.total = total
            self.progress = progress
            self.isOriginal = isOriginal
        }
    }
    
    /// 上传结果，包含原图和压缩图的上传信息
    public struct UploadResults {
        public let original: ImageUploaderGetID.UploadResult
        public let compressed: ImageUploaderGetID.UploadResult
        
        public init(original: ImageUploaderGetID.UploadResult, 
                    compressed: ImageUploaderGetID.UploadResult) {
            self.original = original
            self.compressed = compressed
        }
    }
}

// MARK: - UIImage Extension

private extension UIImage {
    func resized(to size: CGSize) -> UIImage? {
        let widthRatio = size.width / self.size.width
        let heightRatio = size.height / self.size.height
        let ratio = min(widthRatio, heightRatio)
        
        let newSize = CGSize(
            width: self.size.width * ratio,
            height: self.size.height * ratio
        )
        
        let renderer = UIGraphicsImageRenderer(size: newSize)
        return renderer.image { _ in
            self.draw(in: CGRect(origin: .zero, size: newSize))
        }
    }
}
