import SwiftUI
import PhotosUI
import AVFoundation
import os.log

/// 媒体类型
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
        }
    }
}

struct MediaPicker: UIViewControllerRepresentable {
    @Binding var selectedMedia: [MediaType]
    var selectionLimit: Int
    var onDismiss: (() -> Void)?
    
    func makeUIViewController(context: Context) -> PHPickerViewController {
        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        
        // 配置支持图片和视频
        configuration.filter = .any(of: [.videos, .images])
        configuration.selectionLimit = selectionLimit
        configuration.preferredAssetRepresentationMode = .current
        
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = context.coordinator
        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")
        private var processedCount = 0
        private var totalToProcess = 0
        private var tempMedia: [MediaType] = []
        
        init(_ parent: MediaPicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            guard !results.isEmpty else {
                parent.onDismiss?()
                return
            }
            
            processedCount = 0
            totalToProcess = results.count
            tempMedia = []
            
            for result in results {
                let itemProvider = result.itemProvider
                
                if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
                    processImage(itemProvider: itemProvider) { [weak self] media in
                        self?.handleProcessedMedia(media)
                    }
                } else if itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
                    processVideo(itemProvider: itemProvider) { [weak self] media in
                        self?.handleProcessedMedia(media)
                    }
                } else {
                    processedCount += 1
                    checkCompletion()
                }
            }
        }
        
        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
                }
                
                // 创建临时文件URL
                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)
                    
                    // 提取视频缩略图
                    MediaUtils.extractFirstFrame(from: targetURL) { result in
                        switch result {
                        case .success(let thumbnail):
                            completion(.video(targetURL, thumbnail))
                        case .failure(let error):
                            self.logger.error("Failed to extract video thumbnail: \(error.localizedDescription)")
                            // 即使缩略图提取失败，也继续处理视频
                            completion(.video(targetURL, nil))
                        }
                    }
                } catch {
                    self.logger.error("Failed to copy video file: \(error.localizedDescription)")
                    completion(nil)
                }
            }
        }
        
        private func handleProcessedMedia(_ media: MediaType?) {
            if let media = media {
                DispatchQueue.main.async { [weak self] in
                    self?.tempMedia.append(media)
                    self?.checkCompletion()
                }
            } else {
                processedCount += 1
                checkCompletion()
            }
        }
        
        private func checkCompletion() {
            processedCount += 1
            
            if processedCount >= totalToProcess {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    if !self.tempMedia.isEmpty {
                        self.parent.selectedMedia = self.tempMedia
                    }
                    self.parent.onDismiss?()
                }
            }
        }
    }
}