import SwiftUI
import PhotosUI
import os.log
import AVKit

/// 媒体类型
public enum MediaType: Equatable {
    case image(UIImage)
    case video(URL, UIImage?) // URL 是视频地址，UIImage 是视频缩略图
    
    public var thumbnail: UIImage? {
        switch self {
        case .image(let image):
            return image
        case .video(_, let thumbnail):
            return thumbnail
        }
    }
    
    public var isVideo: Bool {
        if case .video = self {
            return true
        }
        return false
    }
    
    public static func == (lhs: MediaType, rhs: MediaType) -> Bool {
        switch (lhs, rhs) {
        case (.image(let lhsImage), .image(let rhsImage)):
            return lhsImage.pngData() == rhsImage.pngData()
        case (.video(let lhsURL, _), .video(let rhsURL, _)):
            return lhsURL == rhsURL
        default:
            return false
        }
    }
}

enum MediaTypeFilter {
    case imagesOnly
    case videosOnly
    case all
    
    var pickerFilter: PHPickerFilter {
        switch self {
        case .imagesOnly: return .images
        case .videosOnly: return .videos
        case .all: return .any(of: [.videos, .images])
        }
    }
}

struct MediaPicker: UIViewControllerRepresentable {
    @Binding var selectedMedia: [MediaType]
    let imageSelectionLimit: Int
    let videoSelectionLimit: Int
    let onDismiss: (() -> Void)?
    let allowedMediaTypes: MediaTypeFilter
    let selectionMode: SelectionMode
    let onUploadProgress: ((Int, Double) -> Void)? 
    
    /// 选择模式
    enum SelectionMode {
        case single    // 单选模式
        case multiple  // 多选模式
        
        var selectionLimit: Int {
            switch self {
            case .single: return 1
            case .multiple: return 0  // 0 表示不限制选择数量，由 imageSelectionLimit 和 videoSelectionLimit 控制
            }
        }
    }
    
    init(selectedMedia: Binding<[MediaType]>, 
        imageSelectionLimit: Int = 10, 
        videoSelectionLimit: Int = 10,
        allowedMediaTypes: MediaTypeFilter = .all,
        selectionMode: SelectionMode = .multiple,
        onDismiss: (() -> Void)? = nil,
        onUploadProgress: ((Int, Double) -> Void)? = nil) {
        self._selectedMedia = selectedMedia
        self.imageSelectionLimit = imageSelectionLimit
        self.videoSelectionLimit = videoSelectionLimit
        self.allowedMediaTypes = allowedMediaTypes
        self.selectionMode = selectionMode
        self.onDismiss = onDismiss
        self.onUploadProgress = onUploadProgress
    }

    
    func makeUIViewController(context: Context) -> PHPickerViewController {
        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        configuration.filter = allowedMediaTypes.pickerFilter
        configuration.selectionLimit = selectionMode.selectionLimit
        configuration.preferredAssetRepresentationMode = .current
        
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = context.coordinator
        context.coordinator.currentPicker = picker
        
        return picker
    }
    
    func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
        // 更新视图控制器（如果需要）
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, PHPickerViewControllerDelegate {
        let parent: MediaPicker
        private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.example.app", category: "MediaPicker")
        internal var currentPicker: PHPickerViewController?
        
        init(_ parent: MediaPicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            guard !results.isEmpty else {
                parent.onDismiss?()
                return
            }
            
            // 如果是单选模式，清空之前的选择
            var processedMedia = parent.selectionMode == .single ? [] : parent.selectedMedia
            
            // 统计当前已选择的图片和视频数量
            var currentImageCount = 0
            var currentVideoCount = 0
            
            for media in processedMedia {
                switch media {
                case .image: currentImageCount += 1
                case .video: currentVideoCount += 1
                }
            }
            
            // 检查新选择的项目
            var newImages = 0
            var newVideos = 0
            
            for result in results {
                let itemProvider = result.itemProvider
                if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
                    guard parent.allowedMediaTypes != .videosOnly else { continue }
                    newImages += 1
                } else if itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
                    guard parent.allowedMediaTypes != .imagesOnly else { continue }
                    newVideos += 1
                }
            }
            
            // 检查是否超出限制
            if (currentImageCount + newImages > parent.imageSelectionLimit) ||
               (currentVideoCount + newVideos > parent.videoSelectionLimit) {
                
                // 准备错误信息
                var message = "选择超出限制：\n"
                var limits: [String] = []
                
                if currentImageCount + newImages > parent.imageSelectionLimit && parent.allowedMediaTypes != .videosOnly {
                    limits.append("图片最多选择\(parent.imageSelectionLimit)张")
                }
                if currentVideoCount + newVideos > parent.videoSelectionLimit && parent.allowedMediaTypes != .imagesOnly {
                    limits.append("视频最多选择\(parent.videoSelectionLimit)个")
                }
                
                message += limits.joined(separator: "\n")
                
                // 显示提示
                let alert = UIAlertController(
                    title: "提示",
                    message: message,
                    preferredStyle: .alert
                )
                alert.addAction(UIAlertAction(title: "好的", style: .default) { _ in
                    // 不清空选择，允许用户继续选择
                })
                
                // 显示提示框
                picker.present(alert, animated: true)
                return
            }
            
            // 先关闭选择器
            picker.dismiss(animated: true) { [weak self] in
                guard let self = self else { return }
                
                // 处理选中的媒体
                var processedMedia = self.parent.selectionMode == .single ? [] : self.parent.selectedMedia
                self.processSelectedMedia(results: results, picker: picker, processedMedia: &processedMedia)
                
                // 调用 onDismiss 通知外部选择器已关闭
                self.parent.onDismiss?()
            }
        }
        
        private func processSelectedMedia(results: [PHPickerResult], 
                                    picker: PHPickerViewController,
                                    processedMedia: inout [MediaType]) {
            let group = DispatchGroup()
            let mediaCollector = MediaCollector()
            
            for (index, result) in results.enumerated() {
                let itemProvider = result.itemProvider
                
                if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
                    guard parent.allowedMediaTypes != .videosOnly else { continue }
                    
                    group.enter()
                    processImage(itemProvider: itemProvider) { media in
                        if let media = media {
                            mediaCollector.add(media: media)
                            // 更新上传进度
                            DispatchQueue.main.async {
                                self.parent.onUploadProgress?(index, 1.0) // 图片直接完成
                            }
                        }
                        group.leave()
                    }
                } else if itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
                    guard parent.allowedMediaTypes != .imagesOnly else { continue }
                    
                    group.enter()
                    processVideo(itemProvider: itemProvider) { media in
                        if let media = media {
                            mediaCollector.add(media: media)
                            // 更新上传进度
                            DispatchQueue.main.async {
                                self.parent.onUploadProgress?(index, 1.0) // 视频直接完成
                            }
                        }
                        group.leave()
                    }
                }
            }
    
            group.notify(queue: .main) {
                let finalMedia = mediaCollector.mediaItems
                self.parent.selectedMedia = finalMedia
            }
        }
        
        private func processImage(itemProvider: NSItemProvider, completion: @escaping (MediaType?) -> Void) {
            itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in
                if let image = object as? UIImage {
                    completion(.image(image))
                } else {
                    self.logger.error("Failed to load image: \(error?.localizedDescription ?? "Unknown error")")
                    completion(nil)
                }
            }
        }
        
        private func processVideo(itemProvider: NSItemProvider, completion: @escaping (MediaType?) -> Void) {
            itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
                guard let videoURL = url, error == nil else {
                    self.logger.error("Failed to load video: \(error?.localizedDescription ?? "Unknown error")")
                    completion(nil)
                    return
                }
                
                let tempDirectory = FileManager.default.temporaryDirectory
                let targetURL = tempDirectory.appendingPathComponent("\(UUID().uuidString).\(videoURL.pathExtension)")
                
                do {
                    if FileManager.default.fileExists(atPath: targetURL.path) {
                        try FileManager.default.removeItem(at: targetURL)
                    }
                    try FileManager.default.copyItem(at: videoURL, to: targetURL)
                    
                    if let thumbnail = self.generateThumbnail(for: targetURL) {
                        completion(.video(targetURL, thumbnail))
                    } else {
                        completion(.video(targetURL, nil))
                    }
                } catch {
                    self.logger.error("Failed to copy video file: \(error.localizedDescription)")
                    completion(nil)
                }
            }
        }
        
        private func generateThumbnail(for videoURL: URL) -> UIImage? {
            let asset = AVAsset(url: videoURL)
            let imageGenerator = AVAssetImageGenerator(asset: asset)
            imageGenerator.appliesPreferredTrackTransform = true
            
            do {
                let cgImage = try imageGenerator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 1), actualTime: nil)
                return UIImage(cgImage: cgImage)
            } catch {
                logger.error("Failed to generate thumbnail: \(error.localizedDescription)")
                return nil
            }
        }
    }
}

// Helper class to collect media items in a thread-safe way
private class MediaCollector {
    private let queue = DispatchQueue(label: "com.example.MediaCollector", attributes: .concurrent)
    private var _mediaItems: [MediaType] = []
    
    var mediaItems: [MediaType] {
        queue.sync { _mediaItems }
    }
    
    func add(media: MediaType) {
        queue.async(flags: .barrier) { [weak self] in
            self?._mediaItems.append(media)
        }
    }
}
