import 'dart:io'; import 'dart:convert'; // Added to ensure correct UTF-8 encoding import 'package:flutter/foundation.dart'; import 'package:archive/archive_io.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as p; /// A dedicated service to handle the creation of ZIP archives for FTP submission. class ZippingService { /// Creates multiple JSON files from a map of data and zips them into a single archive. /// The map keys will be the filenames (e.g., 'db.json', 'form_data.json'). /// The map values should be the JSON string content for each file. Future createDataZip({ required Map jsonDataMap, required String baseFileName, Directory? destinationDir, }) async { try { final targetDir = destinationDir ?? await getTemporaryDirectory(); // Ensure the target directory exists before creating the file if (!await targetDir.exists()) { await targetDir.create(recursive: true); } final zipFilePath = p.join(targetDir.path, '$baseFileName.zip'); final encoder = ZipFileEncoder(); encoder.create(zipFilePath); debugPrint("Creating data ZIP at: $zipFilePath"); for (var entry in jsonDataMap.entries) { final fileName = entry.key; final jsonContent = entry.value; // --- MODIFIED: Ensure UTF-8 encoding --- // 1. Encode the string content into UTF-8 bytes final utf8Bytes = utf8.encode(jsonContent); // 2. Use the UTF-8 bytes and their correct length for the archive // (This replaces the original: jsonContent.length, jsonContent.codeUnits) final archiveFile = ArchiveFile(fileName, utf8Bytes.length, utf8Bytes); // --- END MODIFICATION --- encoder.addArchiveFile(archiveFile); debugPrint("Added $fileName to data ZIP."); } encoder.close(); debugPrint("Data ZIP creation complete."); return File(zipFilePath); } catch (e) { debugPrint("Error creating data ZIP file: $e"); return null; } } /// Creates a ZIP file from a list of image files. Future createImageZip({ required List imageFiles, required String baseFileName, Directory? destinationDir, // ADDED: New optional parameter }) async { if (imageFiles.isEmpty) { debugPrint("No images provided to create an image ZIP."); return null; } try { final targetDir = destinationDir ?? await getTemporaryDirectory(); // Ensure the target directory exists before creating the file if (!await targetDir.exists()) { await targetDir.create(recursive: true); } final zipFilePath = p.join(targetDir.path, '${baseFileName}_img.zip'); final encoder = ZipFileEncoder(); encoder.create(zipFilePath); debugPrint("Creating image ZIP at: $zipFilePath"); for (var imageFile in imageFiles) { if (await imageFile.exists()) { await encoder.addFile(imageFile); debugPrint("Added ${p.basename(imageFile.path)} to image ZIP."); } else { debugPrint("Skipping non-existent file: ${imageFile.path}"); } } encoder.close(); debugPrint("Image ZIP creation complete."); return File(zipFilePath); } catch (e) { debugPrint("Error creating image ZIP file: $e"); return null; } } }