import SwiftUI
import PhotosUI

// MARK: - Photo Picker

/// 照片选择器，封装了系统相册选择功能
struct PhotoPicker: UIViewControllerRepresentable {
    // MARK: - Properties
    
    @Binding var selectedImages: [UIImage]
    let selectionLimit: Int
    let filter: PHPickerFilter
    var onImageUploaded: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
    var onUploadProgress: ((ImageUploadService.UploadProgress) -> Void)?
    @Environment(\.presentationMode) private var presentationMode
    
    // MARK: - Initialization
    
    init(selectedImages: Binding<[UIImage]>,
         selectionLimit: Int = 1,
         filter: PHPickerFilter = .images,
         onImageUploaded: ((Result<ImageUploadService.UploadResults, Error>) -> Void)? = nil,
         onUploadProgress: ((ImageUploadService.UploadProgress) -> Void)? = nil) {
        self._selectedImages = selectedImages
        self.selectionLimit = selectionLimit
        self.filter = filter
        self.onImageUploaded = onImageUploaded
        self.onUploadProgress = onUploadProgress
    }
    
    // MARK: - UIViewControllerRepresentable
    
    func makeUIViewController(context: Context) -> PHPickerViewController {
        var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
        configuration.filter = filter
        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)
    }
    
    // MARK: - Coordinator
    
    class Coordinator: NSObject, PHPickerViewControllerDelegate {
        let parent: PhotoPicker
        private let uploadService = ImageUploadService.shared
        
        init(_ parent: PhotoPicker) {
            self.parent = parent
        }
        
        func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
            guard !results.isEmpty else {
                parent.presentationMode.wrappedValue.dismiss()
                return
            }
            
            parent.selectedImages.removeAll()
            let group = DispatchGroup()
            var loadedImages: [Int: UIImage] = [:] 
            var uploadResults: [Int: ImageUploadService.UploadResults] = [:]
            var lastError: Error?
            
            for (index, result) in results.enumerated() {
                group.enter()
                
                if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
                    result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
                        if let error = error {
                            lastError = error
                            group.leave()
                            return
                        }
                        
                        guard let image = image as? UIImage else {
                            lastError = NSError(domain: "com.wake.upload", code: -2, userInfo: [NSLocalizedDescriptionKey: "Failed to load image"])
                            group.leave()
                            return
                        }
                        
                        loadedImages[index] = image
                        
                        // Upload the image
                        self.uploadService.uploadOriginalAndCompressedImage(
                            image,
                            compressionQuality: 0.5,
                            progress: { progress in
                                DispatchQueue.main.async {
                                    self.parent.onUploadProgress?(progress)
                                }
                            },
                            completion: { result in
                                defer { group.leave() }
                                
                                switch result {
                                case .success(let results):
                                    uploadResults[index] = results
                                    
                                    // 使用 NetworkService 上传文件信息
                                    let parameters: [String: Any] = [
                                        "file_id": results.original.fileId,
                                        "preview_file_id": results.compressed.fileId
                                    ]
                                    
                                    // 将参数包装在数组中
                                    let requestBody: [[String: Any]] = [parameters]
                                    
                                    // 定义响应模型
                                    struct MaterialResponse: Decodable {
                                        let success: Bool
                                        let message: String?
                                    }
                                    
                                    // 直接使用 URLSession 发送请求，确保数据格式正确
                                    do {
                                        let jsonData = try JSONSerialization.data(withJSONObject: requestBody)
                                        var request = URLRequest(url: URL(string: "\(APIConfig.baseURL)/material")!)
                                        request.httpMethod = "POST"
                                        request.allHTTPHeaderFields = APIConfig.authHeaders
                                        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                                        request.httpBody = jsonData
                                        
                                        let task = URLSession.shared.dataTask(with: request) { data, response, error in
                                            if let error = error {
                                                print("❌ 文件信息上传失败: \(error.localizedDescription)")
                                                return
                                            }
                                            
                                            if let httpResponse = response as? HTTPURLResponse {
                                                if (200...299).contains(httpResponse.statusCode) {
                                                    print("✅ 文件信息上传成功")
                                                } else {
                                                    let statusCode = httpResponse.statusCode
                                                    let errorMessage = String(data: data ?? Data(), encoding: .utf8) ?? ""
                                                    print("❌ 服务器返回错误状态码: \(statusCode), 响应: \(errorMessage)")
                                                }
                                            }
                                        }
                                        task.resume()
                                    } catch {
                                        print("❌ 请求数据序列化失败: \(error.localizedDescription)")
                                    }
                                    
                                case .failure(let error):
                                    lastError = error
                                    print("❌ 图片上传失败: \(error.localizedDescription)")
                                }
                            }
                        )
                    }
                } else {
                    group.leave()
                }
            }
            
            group.notify(queue: .main) { [weak self] in
                guard let self = self else { return }
                
                if let error = lastError {
                    self.parent.onImageUploaded?(.failure(error))
                } else {
                    let sortedImages = loadedImages.sorted { $0.key < $1.key }.map { $0.value }
                    self.parent.selectedImages.append(contentsOf: sortedImages)
                    
                    if let firstResult = uploadResults.first?.value {
                        self.parent.onImageUploaded?(.success(firstResult))
                    } else {
                        self.parent.onImageUploaded?(.failure(NSError(
                            domain: "com.wake.upload", 
                            code: -1, 
                            userInfo: [NSLocalizedDescriptionKey: "上传过程中出现错误"]
                        )))
                    }
                }
                
                self.parent.presentationMode.wrappedValue.dismiss()
            }
        }
    }
}

// MARK: - Avatar Uploader

/// 头像上传视图，提供头像选择功能
struct AvatarUploader: View {
    @Binding var selectedImage: UIImage?
    let size: CGFloat
    var onUploadComplete: ((Result<ImageUploadService.UploadResults, Error>) -> Void)?
    
    @State private var isImagePickerPresented = false
    
    var body: some View {
        Button(action: { isImagePickerPresented = true }) {
            ZStack {
                if let selectedImage = selectedImage {
                    Image(uiImage: selectedImage)
                        .resizable()
                        .scaledToFill()
                        .frame(width: size, height: size)
                        .clipShape(RoundedRectangle(cornerRadius: size * 0.1))
                } else {
                    Color.gray.opacity(0.1)
                        .frame(width: size, height: size)
                        .overlay(
                            SVGImage(svgName: "Avatar")
                                .frame(width: size * 0.8, height: size * 0.8)
                        )
                        .clipShape(RoundedRectangle(cornerRadius: size * 0.1))
                        .overlay(
                            RoundedRectangle(cornerRadius: size * 0.1)
                                .stroke(Color.gray.opacity(0.3), lineWidth: 1)
                        )
                }
            }
            .frame(width: size, height: size)
            .contentShape(Rectangle())
        }
        .buttonStyle(PlainButtonStyle())
        .sheet(isPresented: $isImagePickerPresented) {
            PhotoPicker(
                selectedImages: Binding(
                    get: { [selectedImage].compactMap { $0 } },
                    set: { images in
                        selectedImage = images.first
                    }
                ),
                selectionLimit: 1,
                onImageUploaded: { result in
                    onUploadComplete?(result)
                },
                onUploadProgress: { progress in
                    print("上传进度：\(progress.current)/\(progress.total)，进度：\(Int(progress.progress * 100))%")
                }
            )
        }
    }
}