import 'package:xml/xml.dart';
import 'package:archive/archive.dart';
import 'package:docx/docx.dart';
import 'dart:typed_data';
import 'dart:io';
import 'dart:convert';

  /// Recreate a Archive to add modification and save it on [fileInDocx]
  /// [documentsXml] is list -> ['word/document.xml', 'word/_rels/document.xml.rels']
  /// [docxEditor] Instance of docxEditor for Bytes, path,...
  void save(List<XmlDocument> documentsXml, DocxEditor docxEditor) {
    try {
      final archive = ZipDecoder().decodeBytes(docxEditor.binaryInDocx!);

      final Uint8List uListDocumentXml = utf8.encode(documentsXml[0].toXmlString());
      final Uint8List uListDocumentXmlRels = utf8.encode(documentsXml[1].toXmlString());

      final newArchive = Archive();

      for (ArchiveFile file in archive.files) {
        if (file.name == 'word/document.xml') {
          newArchive.addFile(ArchiveFile(
            'word/document.xml',
            uListDocumentXml.length,
            uListDocumentXml,
          ));
        }
        else if (file.name == 'word/_rels/document.xml.rels') {
          newArchive.addFile(ArchiveFile(
            'word/_rels/document.xml.rels',
            uListDocumentXmlRels.length,
            uListDocumentXmlRels,
          ));
        } else {
          newArchive.addFile(file);
        }
      }
      for (ReplaceContent replaceCnt in docxEditor.replaceMap.values.where((rm) => rm.img != null)) {
        final imageBytes = replaceCnt.img!.bytes;
        newArchive.addFile(
          ArchiveFile(
            'word/media/${replaceCnt.img!.name}',
            imageBytes.length,
            imageBytes,
          )
        );
      }

      List<int> zipData = ZipEncoder().encode(newArchive);

      File? fileInDocx = docxEditor.fileInDocx;
      String? pathOutDocx = docxEditor.pathOutDocx;
      
      if (fileInDocx != null) {
        File newFile = pathOutDocx == null ? fileInDocx : File(pathOutDocx);
        newFile.writeAsBytesSync(zipData);
      }
      else {
        File newFile = pathOutDocx == null ? File('.') : File(pathOutDocx);
        newFile.writeAsBytesSync(zipData);
      }
    } catch (e) {
      throw StateError('DOCX BUILDER ERROR: $e');
    }
  }
