// BookForge Pro Turbo - Application Module

document.addEventListener('DOMContentLoaded', () => {
    function gerarHashLivro(texto) {
        let hash = 0;
        for (let i = 0; i < texto.length; i++) {
            const char = texto.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash;
        }
        return hash.toString(16);
    }

    function obterHashLivroAtual() {
        if (state && state.chapters && state.chapters.length > 0) {
            return gerarHashLivro(JSON.stringify(state.chapters));
        }
        return 'master';
    }

    // ----------------------------------------------------
    // STATE MANAGEMENT
    // ----------------------------------------------------
    const state = {
        bookTitle: '',
        bookAuthor: '',
        chapters: [], // Array of { id, title, content }
        showWorkspacePreview: false,
        proofreadModeActive: false,
        
        // Formatting
        paperColor: 'cream', // 'cream' | 'white'
        bookFormat: '14x21', // '14x21' | 'A5' | '16x23'
        globalFont: 'EB Garamond',
        hasDropCap: true,
        sceneOrnament: 'none', // 'none' | 'fleur' | 'oliveira' | etc.
        pageMoldura: 'none',
        decorationsColor: '#000000', // Default decoration color
        fontChapterNumber: 'Cinzel',
        fontChapterTitle: 'EB Garamond',
        
        // Structural Pages
        structure: {
            'title-page': { active: true, font: 'Cinzel', fontAuthor: 'EB Garamond', showAuthor: true },
            'copyright': { active: true, text: '', font: 'EB Garamond', fontTitle: 'Cinzel' },
            'dedication': { active: false, text: '', font: 'Great Vibes', fontTitle: 'Cinzel' },
            'epigraph': { active: false, text: '', font: 'Great Vibes', fontTitle: 'Cinzel' },
            'acknowledgements': { active: false, title: 'Agradecimentos', text: '', font: 'EB Garamond', fontTitle: 'Cinzel' },
            'preface': { active: false, title: 'Prefácio', text: '', font: 'EB Garamond', fontTitle: 'Cinzel' },
            'epilogue': { active: false, title: 'Epílogo', text: '', font: 'EB Garamond', fontTitle: 'Cinzel' },
            'bio': { active: false, text: '', photo: '', font: 'EB Garamond', fontTitle: 'Cinzel' },
            'toc': { active: true, font: 'Cinzel', fontTitle: 'Cinzel' },
            'blank-page': { active: false }
        }
    };

    // ----------------------------------------------------
    // HISTÓRICO DE AÇÕES (UNDO / REDO)
    // ----------------------------------------------------
    const undoStack = [];
    const redoStack = [];
    let lastRecordedState = null;
    let isApplyingHistory = false;
    let historyTimeout = null;
    let stateToRecord = null;

    function recordHistoryState() {
        if (isApplyingHistory) return;
        const currentStateStr = JSON.stringify(state);
        if (lastRecordedState && lastRecordedState !== currentStateStr) {
            // Se não há um timer ativo, inicia uma sessão de edição (captura o estado original)
            if (!historyTimeout) {
                stateToRecord = lastRecordedState;
            } else {
                clearTimeout(historyTimeout);
            }
            
            historyTimeout = setTimeout(() => {
                if (!isApplyingHistory && stateToRecord) {
                    undoStack.push(stateToRecord);
                    redoStack.length = 0; // Nova alteração limpa o Redo
                    if (undoStack.length > 50) undoStack.shift(); // Limite de 50 ações
                    updateUndoRedoButtons();
                }
                historyTimeout = null;
                stateToRecord = null;
            }, 800);
        }
        lastRecordedState = currentStateStr;
    }

    function applyHistoryState(stateStr, isUndo) {
        try {
            if (historyTimeout) {
                clearTimeout(historyTimeout);
                historyTimeout = null;
                stateToRecord = null;
            }

            const targetState = JSON.parse(stateStr);
            isApplyingHistory = true;
            
            // Grava o estado atual na pilha oposta
            const currentStateStr = JSON.stringify(state);
            if (isUndo) {
                redoStack.push(currentStateStr);
            } else {
                undoStack.push(currentStateStr);
            }
            
            // Copia as chaves do estado destino para o estado atual
            Object.keys(targetState).forEach(key => {
                state[key] = targetState[key];
            });
            
            // Sincroniza e redesenha tudo
            syncStateToUI();
            renderChapterList();
            updatePreviewPages();
            
            lastRecordedState = JSON.stringify(state);
            isApplyingHistory = false;
            updateUndoRedoButtons();
            
            // Salva no backup físico do disco também
            fetch('/api/save-backup', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(state)
            }).catch(err => console.error("Erro ao salvar backup no histórico:", err));
            
        } catch (e) {
            console.error("Falha ao aplicar estado do histórico:", e);
            isApplyingHistory = false;
        }
    }

    function undo() {
        if (undoStack.length === 0) return;
        const previousStateStr = undoStack.pop();
        applyHistoryState(previousStateStr, true);
    }

    function redo() {
        if (redoStack.length === 0) return;
        const nextStateStr = redoStack.pop();
        applyHistoryState(nextStateStr, false);
    }

    function updateUndoRedoButtons() {
        const btnUndo = document.getElementById('btn-undo');
        const btnRedo = document.getElementById('btn-redo');
        if (btnUndo) {
            btnUndo.disabled = undoStack.length === 0;
            btnUndo.style.opacity = undoStack.length === 0 ? '0.5' : '1';
            btnUndo.style.cursor = undoStack.length === 0 ? 'not-allowed' : 'pointer';
        }
        if (btnRedo) {
            btnRedo.disabled = redoStack.length === 0;
            btnRedo.style.opacity = redoStack.length === 0 ? '0.5' : '1';
            btnRedo.style.cursor = redoStack.length === 0 ? 'not-allowed' : 'pointer';
        }
    }

    // ----------------------------------------------------
    // DOM ELEMENTS CACHE
    // ----------------------------------------------------
    const btnAddChapter = document.getElementById('btn-add-chapter');
    const docxUploadSidebar = document.getElementById('docx-upload-sidebar');
    const docxUploadMain = document.getElementById('docx-upload-main');
    const chapterListContainer = document.getElementById('chapter-list-container');
    const btnExportDropdown = document.getElementById('btn-export-dropdown');
    const exportMenu = document.getElementById('export-menu');
    const btnExportPdf = document.getElementById('btn-export-pdf');
    const btnExportEpub = document.getElementById('btn-export-epub');
    const btnExportWord = document.getElementById('btn-export-word');
    const btnContinueWork = document.getElementById('btn-continue-work');
    
    // Configs inputs
    const paperColorSelect = document.getElementById('paper-color-select');
    const bookFormatSelect = document.getElementById('book-format');
    const toggleDropcap = document.getElementById('toggle-dropcap');
    const toggleMoldura = document.getElementById('toggle-moldura');
    const bookFontSelect = document.getElementById('book-font');
    const ornamentBtns = document.querySelectorAll('.ornament-grid-btn');
    
    // Tabs & Color Picker elements
    const tabBtns = document.querySelectorAll('.tab-btn');
    const tabBtnsRight = document.querySelectorAll('.tab-btn-right');
    const tabContents = document.querySelectorAll('.sidebar-left .tab-content');
    const tabContentsRight = document.querySelectorAll('.sidebar-right .tab-content');
    const detailsColorPicker = document.getElementById('details-color-picker');
    const detailsColorValue = document.getElementById('details-color-value');
    
    // Bottom Left Actions
    const btnBackBook = document.getElementById('btn-back-book');
    
    // Right Sidebar Structural Checkboxes
    const pageHasTitlepage = document.getElementById('page-has-titlepage');
    const inputBookTitle = document.getElementById('input-book-title');
    const pageHasCopyright = document.getElementById('page-has-copyright');
    const inputCopyrightText = document.getElementById('input-copyright-text');
    const pageHasDedication = document.getElementById('page-has-dedication');
    const inputDedicationText = document.getElementById('input-dedication-text');
    const pageHasEpigraph = document.getElementById('page-has-epigraph');
    const inputEpigraphText = document.getElementById('input-epigraph-text');
    const pageHasAcknowledgements = document.getElementById('page-has-acknowledgements');
    const inputAcknowledgementsTitle = document.getElementById('input-acknowledgements-title');
    const inputAcknowledgementsText = document.getElementById('input-acknowledgements-text');
    const pageHasPreface = document.getElementById('page-has-preface');
    const inputPrefaceTitle = document.getElementById('input-preface-title');
    const inputPrefaceText = document.getElementById('input-preface-text');
    const pageHasEpilogue = document.getElementById('page-has-epilogue');
    const inputEpilogueTitle = document.getElementById('input-epilogue-title');
    const inputEpilogueText = document.getElementById('input-epilogue-text');
    const pageHasBio = document.getElementById('page-has-bio');
    const inputBioPhoto = document.getElementById('input-bio-photo');
    const inputBioText = document.getElementById('input-bio-text');
    const selectBioFont = document.getElementById('select-bio-font');
    const pageHasToc = document.getElementById('page-has-toc');
    const pageHasBlank = document.getElementById('page-has-blank');
    
    // Custom Fonts selects
    const fontTitlepage = document.getElementById('font-titlepage');
    const fontTitlepageAuthor = document.getElementById('font-titlepage-author');
    const fontCopyright = document.getElementById('font-copyright');
    const fontCopyrightTitle = document.getElementById('font-copyright-title');
    const fontDedication = document.getElementById('font-dedication');
    const fontDedicationTitle = document.getElementById('font-dedication-title');
    const fontEpigraph = document.getElementById('font-epigraph');
    const fontEpigraphTitle = document.getElementById('font-epigraph-title');
    const fontAcknowledgementsTitle = document.getElementById('font-acknowledgements-title');
    const fontAcknowledgements = document.getElementById('font-acknowledgements');
    const fontPreface = document.getElementById('font-preface');
    const fontPrefaceTitle = document.getElementById('font-preface-title');
    const fontEpilogue = document.getElementById('font-epilogue');
    const fontEpilogueTitle = document.getElementById('font-epilogue-title');
    const fontBioTitle = document.getElementById('font-bio-title');
    const fontToc = document.getElementById('font-toc');
    const fontTocTitle = document.getElementById('font-toc-title');
    const fontChapterNumber = document.getElementById('font-chapter-number');
    const fontChapterTitle = document.getElementById('font-chapter-title');
    
    // Author inputs
    const inputBookAuthor = document.getElementById('input-book-author');
    const showAuthorTitlepage = document.getElementById('show-author-titlepage');

    // Spell Checker / Proofreader Helper Functions & Scope Variables
    let typoInstance = null;
    let typoLoadingPromise = null;

    function initSpellchecker() {
        if (typoLoadingPromise) return typoLoadingPromise;
        
        typoLoadingPromise = new Promise((resolve, reject) => {
            // Se os dicionários já estiverem carregados em memória via script tag, inicializa imediatamente
            if (window.pt_BR_aff && window.pt_BR_dic) {
                try {
                    typoInstance = new Typo("pt_BR", window.pt_BR_aff, window.pt_BR_dic);
                    window.typoInstance = typoInstance; // Expor globalmente para depuração
                    console.log("Corretor ortográfico Hunspell carregado em memória com sucesso!");
                    resolve(typoInstance);
                } catch (e) {
                    console.error("Erro ao inicializar o corretor ortográfico em memória:", e);
                    reject(e);
                }
            } else {
                // Fallback para fetch assíncrono caso os scripts não tenham sido carregados na memória
                Promise.all([
                    fetch('dictionaries/pt_BR.aff').then(res => {
                        if (!res.ok) throw new Error("Falha ao carregar o arquivo AFF");
                        return res.text();
                    }),
                    fetch('dictionaries/pt_BR.dic').then(res => {
                        if (!res.ok) throw new Error("Falha ao carregar o arquivo DIC");
                        return res.text();
                    })
                ]).then(([affData, dicData]) => {
                    typoInstance = new Typo("pt_BR", affData, dicData);
                    window.typoInstance = typoInstance;
                    console.log("Corretor ortográfico Hunspell carregado via fetch com sucesso!");
                    resolve(typoInstance);
                }).catch(err => {
                    console.error("Erro ao carregar dicionários via fetch:", err);
                    typoLoadingPromise = null; // Permitir tentar novamente em caso de falha
                    reject(err);
                });
            }
        });
        
        return typoLoadingPromise;
    }

    function isWordCorrect(word) {
        if (!typoInstance) return true; // Se não carregado, assume correto
        
        // Ignorar letras isoladas, exceto vogais ou palavras de uma letra comuns
        if (word.length === 1) {
            return ["a", "e", "o", "u", "i", "s", "A", "E", "O", "U", "I"].includes(word);
        }
        
        // Verificar palavra no dicionário Hunspell
        if (typoInstance.check(word) || typoInstance.check(word.toLowerCase())) {
            return true;
        }
        
        // Tratamento especial para verbos pronominais portugueses (ênclise/mesóclise) ex: vendê-lo, amou-a
        if (word.includes('-')) {
            const parts = word.split('-');
            const clitics = new Set([
                "o", "a", "os", "as", "me", "te", "se", "nos", "vos", 
                "lhe", "lhes", "lo", "la", "los", "las", "no", "na", "nos", "nas"
            ]);
            
            let allPartsOk = true;
            for (let part of parts) {
                if (!part) continue;
                const isClitic = clitics.has(part.toLowerCase());
                const isCorrect = typoInstance.check(part) || typoInstance.check(part.toLowerCase());
                if (!isClitic && !isCorrect) {
                    allPartsOk = false;
                    break;
                }
            }
            if (allPartsOk) return true;
        }
        
        return false;
    }

    function saveParagraph(paraEl) {
        const chapterId = paraEl.getAttribute('data-chapter-id');
        const paraIndex = parseInt(paraEl.getAttribute('data-para-index'));
        
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = paraEl.innerHTML;
        
        // Remove as tags de realce do corretor antes de salvar
        tempDiv.querySelectorAll('.proofread-error').forEach(span => {
            const parent = span.parentNode;
            while (span.firstChild) {
                parent.insertBefore(span.firstChild, span);
            }
            parent.removeChild(span);
        });
        
        const cleanHTML = tempDiv.innerHTML;
        
        const chapter = state.chapters.find(ch => ch.id === chapterId);
        if (chapter) {
            const chapterDiv = document.createElement('div');
            chapterDiv.innerHTML = chapter.content;
            
            const nodes = Array.from(chapterDiv.childNodes).filter(node => {
                if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) return true;
                if (node.nodeType === Node.ELEMENT_NODE) return true;
                return false;
            });
            
            const targetNode = nodes[paraIndex];
            if (targetNode) {
                if (targetNode.nodeType === Node.TEXT_NODE) {
                    targetNode.textContent = tempDiv.textContent;
                } else {
                    targetNode.innerHTML = cleanHTML;
                }
                
                chapter.content = chapterDiv.innerHTML;
                updatePreviewPages();
                console.log(`Parágrafo ${paraIndex} do capítulo ${chapterId} atualizado!`);
            }
        }
    }

    // ----------------------------------------------------
    // INITIALIZATION & SYNC
    // ----------------------------------------------------
    function init() {
        console.log("BookForge Pro Turbo - Interface iniciada com sucesso!");
        syncStateToUI();
        registerEvents();
        updateDynamicStyle();
        updatePrintStyle();
        
        // Exibe o botão "Continuar de onde parei" se houver progresso salvo no localStorage
        if (localStorage.getItem('bookforge_saved_state')) {
            if (btnContinueWork) {
                btnContinueWork.style.display = 'flex';
            }
        } else {
            // Se o localStorage foi limpo (ex: PC desligado), verifica se há um backup no disco rígido
            fetch('/api/load-backup')
                .then(res => {
                    if (res.ok) return res.json();
                    throw new Error("Sem backup");
                })
                .then(backupState => {
                    if (backupState && btnContinueWork) {
                        localStorage.setItem('bookforge_saved_state', JSON.stringify(backupState));
                        btnContinueWork.style.display = 'flex';
                        console.log("Progresso de contingência carregado do disco!");
                    }
                })
                .catch(err => {
                    console.log("Nenhum backup de contingência no disco disponível:", err.message);
                });
        }
        
        lastRecordedState = JSON.stringify(state);
        updateUndoRedoButtons();
    }

    // Update UI components with current state values
    function syncStateToUI() {
        if (paperColorSelect) paperColorSelect.value = state.paperColor;
        if (bookFormatSelect) bookFormatSelect.value = state.bookFormat;
        if (toggleDropcap) toggleDropcap.value = state.hasDropCap ? 'true' : 'false';
        if (toggleMoldura) toggleMoldura.value = state.pageMoldura || 'none';
        if (bookFontSelect) bookFontSelect.value = state.globalFont;
        
        // Sync color picker
        if (detailsColorPicker) detailsColorPicker.value = state.decorationsColor;
        if (detailsColorValue) detailsColorValue.textContent = state.decorationsColor.toUpperCase();
        
        // Sync ornament buttons grid
        ornamentBtns.forEach(btn => {
            const orn = btn.getAttribute('data-ornament');
            if (orn === state.sceneOrnament) {
                btn.classList.add('active');
            } else {
                btn.classList.remove('active');
            }
        });

        // Sync right sidebar checkboxes
        if (pageHasTitlepage) pageHasTitlepage.checked = state.structure['title-page'].active;
        if (pageHasCopyright) pageHasCopyright.checked = state.structure['copyright'].active;
        if (inputCopyrightText) inputCopyrightText.value = state.structure['copyright'].text;
        if (pageHasDedication) pageHasDedication.checked = state.structure['dedication'].active;
        if (inputDedicationText) inputDedicationText.value = state.structure['dedication'].text;
        if (pageHasEpigraph) pageHasEpigraph.checked = state.structure['epigraph'].active;
        if (inputEpigraphText) inputEpigraphText.value = state.structure['epigraph'].text;
        if (pageHasAcknowledgements) pageHasAcknowledgements.checked = state.structure['acknowledgements'].active;
        if (inputAcknowledgementsTitle) inputAcknowledgementsTitle.value = state.structure['acknowledgements'].title;
        if (inputAcknowledgementsText) inputAcknowledgementsText.value = state.structure['acknowledgements'].text;
        if (pageHasPreface) pageHasPreface.checked = state.structure['preface'].active;
        if (inputPrefaceTitle) inputPrefaceTitle.value = state.structure['preface'].title;
        if (inputPrefaceText) inputPrefaceText.value = state.structure['preface'].text;
        if (pageHasEpilogue) pageHasEpilogue.checked = state.structure['epilogue'].active;
        if (inputEpilogueTitle) inputEpilogueTitle.value = state.structure['epilogue'].title;
        if (inputEpilogueText) inputEpilogueText.value = state.structure['epilogue'].text;
        if (pageHasBio) pageHasBio.checked = state.structure['bio'].active;
        if (inputBioText) inputBioText.value = state.structure['bio'].text;
        if (selectBioFont) selectBioFont.value = state.structure['bio'].font;
        if (pageHasToc) pageHasToc.checked = state.structure['toc'].active;
        if (pageHasBlank) pageHasBlank.checked = state.structure['blank-page'].active;

        // Sync page custom fonts
        if (fontTitlepage) fontTitlepage.value = state.structure['title-page'].font;
        if (fontTitlepageAuthor) fontTitlepageAuthor.value = state.structure['title-page'].fontAuthor;
        if (fontCopyright) fontCopyright.value = state.structure['copyright'].font;
        if (fontCopyrightTitle) fontCopyrightTitle.value = state.structure['copyright'].fontTitle;
        if (fontDedication) fontDedication.value = state.structure['dedication'].font;
        if (fontDedicationTitle) fontDedicationTitle.value = state.structure['dedication'].fontTitle;
        if (fontEpigraph) fontEpigraph.value = state.structure['epigraph'].font;
        if (fontEpigraphTitle) fontEpigraphTitle.value = state.structure['epigraph'].fontTitle;
        if (fontAcknowledgementsTitle) fontAcknowledgementsTitle.value = state.structure['acknowledgements'].fontTitle;
        if (fontAcknowledgements) fontAcknowledgements.value = state.structure['acknowledgements'].font;
        if (fontPreface) fontPreface.value = state.structure['preface'].font;
        if (fontPrefaceTitle) fontPrefaceTitle.value = state.structure['preface'].fontTitle;
        if (fontEpilogue) fontEpilogue.value = state.structure['epilogue'].font;
        if (fontEpilogueTitle) fontEpilogueTitle.value = state.structure['epilogue'].fontTitle;
        if (selectBioFont) selectBioFont.value = state.structure['bio'].font;
        if (fontBioTitle) fontBioTitle.value = state.structure['bio'].fontTitle;
        if (fontToc) fontToc.value = state.structure['toc'].font;
        if (fontTocTitle) fontTocTitle.value = state.structure['toc'].fontTitle;
        if (fontChapterNumber) fontChapterNumber.value = state.fontChapterNumber || 'Cinzel';
        if (fontChapterTitle) fontChapterTitle.value = state.fontChapterTitle || 'EB Garamond';

        // Sync Title & Author
        if (inputBookTitle) inputBookTitle.value = state.bookTitle;
        if (inputBookAuthor) inputBookAuthor.value = state.bookAuthor;
        if (showAuthorTitlepage) showAuthorTitlepage.checked = state.structure['title-page'].showAuthor;
        
        // Sync proofreader button state
        const btnToggleProofreader = document.getElementById('btn-toggle-proofreader');
        if (btnToggleProofreader) {
            if (state.proofreadModeActive) {
                btnToggleProofreader.classList.add('active');
                btnToggleProofreader.innerHTML = '<i data-lucide="loader-2" class="animate-spin"></i> Carregando Dicionário...';
                if (window.lucide) window.lucide.createIcons();
                initSpellchecker().then(() => {
                    if (state.proofreadModeActive) {
                        btnToggleProofreader.innerHTML = '<i data-lucide="spell-check-2"></i> Desativar Corretor';
                        if (window.lucide) window.lucide.createIcons();
                        updatePreviewPages();
                    }
                }).catch(err => {
                    btnToggleProofreader.innerHTML = '<i data-lucide="spell-check-2"></i> Desativar Corretor';
                    if (window.lucide) window.lucide.createIcons();
                    updatePreviewPages();
                });
            } else {
                btnToggleProofreader.classList.remove('active');
                btnToggleProofreader.innerHTML = '<i data-lucide="spell-check"></i> Ativar Corretor';
                if (window.lucide) window.lucide.createIcons();
            }
        }
        
        renderChapterList();
    }

    // Render list of chapters in left sidebar
    function renderChapterList() {
        if (!chapterListContainer) return;
        
        if (state.chapters.length === 0) {
            chapterListContainer.innerHTML = '<p class="empty-list-text">Nenhum capítulo importado ainda.</p>';
            return;
        }

        chapterListContainer.innerHTML = '';
        state.chapters.forEach((chapter, index) => {
            const item = document.createElement('div');
            item.className = 'chapter-item';
            // Exibir em maiúsculo igual à imagem original
            item.textContent = chapter.title.toUpperCase();
            item.setAttribute('data-chapter-id', chapter.id);
            
            // Ativa o primeiro item por padrão
            if (index === 0) {
                item.classList.add('active');
            }
            
            item.addEventListener('click', () => {
                document.querySelectorAll('.chapter-item').forEach(el => el.classList.remove('active'));
                item.classList.add('active');
                
                // Rola suavemente até a página inicial deste capítulo
                const targetPage = document.querySelector(`.page-sheet[data-chapter-id="${chapter.id}"]`);
                if (targetPage) {
                    targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });
                }
            });
            
            chapterListContainer.appendChild(item);
        });
    }

    // ----------------------------------------------------
    // EVENTS BINDING
    // ----------------------------------------------------
    function registerEvents() {
        // Left tab switching logic
        tabBtns.forEach(btn => {
            btn.addEventListener('click', () => {
                const targetTab = btn.getAttribute('data-tab');
                
                tabBtns.forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                
                tabContents.forEach(content => {
                    if (content.id === `tab-content-${targetTab}`) {
                        content.classList.remove('hidden');
                    } else {
                        content.classList.add('hidden');
                    }
                });
            });
        });

        // Right tab switching logic
        tabBtnsRight.forEach(btn => {
            btn.addEventListener('click', () => {
                const targetTab = btn.getAttribute('data-tab');
                
                tabBtnsRight.forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                
                tabContentsRight.forEach(content => {
                    if (content.id === `tab-content-${targetTab}`) {
                        content.classList.remove('hidden');
                    } else {
                        content.classList.add('hidden');
                    }
                });
            });
        });

        // Details Color Picker event
        if (detailsColorPicker) {
            detailsColorPicker.addEventListener('input', (e) => {
                state.decorationsColor = e.target.value;
                if (detailsColorValue) detailsColorValue.textContent = e.target.value.toUpperCase();
                updateDynamicStyle();
            });
        }

        // Toggle Export Dropdown Menu
        if (btnExportDropdown && exportMenu) {
            btnExportDropdown.addEventListener('click', (e) => {
                e.stopPropagation();
                exportMenu.classList.toggle('show');
            });
            document.addEventListener('click', () => {
                exportMenu.classList.remove('show');
            });
        }

        // Export Actions
        if (btnExportPdf) {
            btnExportPdf.addEventListener('click', exportBookPDF);
        }
        if (btnExportEpub) {
            btnExportEpub.addEventListener('click', exportBookEPUB);
        }
        if (btnExportWord) {
            btnExportWord.addEventListener('click', exportBookWord);
        }

        // Restaurar Progresso
        if (btnContinueWork) {
            btnContinueWork.addEventListener('click', loadSavedProgress);
        }

        // Paper Color Select
        if (paperColorSelect) {
            paperColorSelect.addEventListener('change', (e) => {
                state.paperColor = e.target.value;
                console.log("Cor do papel atualizada:", state.paperColor);
                updatePreviewPages();
            });
        }

        // Format Select
        if (bookFormatSelect) {
            bookFormatSelect.addEventListener('change', (e) => {
                state.bookFormat = e.target.value;
                console.log("Formato do livro atualizado:", state.bookFormat);
                updatePreviewPages();
            });
        }

        // Dropcap Select
        if (toggleDropcap) {
            toggleDropcap.addEventListener('change', (e) => {
                state.hasDropCap = e.target.value === 'true';
                console.log("Letra capitular atualizada:", state.hasDropCap);
                updatePreviewPages();
            });
        }

        // Moldura Select
        if (toggleMoldura) {
            toggleMoldura.addEventListener('change', (e) => {
                state.pageMoldura = e.target.value;
                console.log("Moldura de página atualizada:", state.pageMoldura);
                updatePreviewPages();
            });
        }

        // Font Select
        if (bookFontSelect) {
            bookFontSelect.addEventListener('change', (e) => {
                state.globalFont = e.target.value;
                console.log("Fonte global atualizada:", state.globalFont);
                updatePreviewPages();
            });
        }

        // Ornament Grid click handler
        ornamentBtns.forEach(btn => {
            btn.addEventListener('click', function() {
                ornamentBtns.forEach(b => b.classList.remove('active'));
                this.classList.add('active');
                state.sceneOrnament = this.getAttribute('data-ornament');
                console.log("Ornamento selecionado:", state.sceneOrnament);
                updatePreviewPages();
            });
        });

        // Add Chapter Click (Manual)
        if (btnAddChapter) {
            btnAddChapter.addEventListener('click', () => {
                const num = state.chapters.length + 1;
                state.chapters.push({
                    id: 'chapter-' + num,
                    title: 'Capítulo ' + num,
                    content: '<p>Comece a escrever o conteúdo deste capítulo aqui...</p>'
                });
                renderChapterList();
                updatePreviewPages();
            });
        }

        // Right Sidebar Checkboxes
        if (pageHasTitlepage) {
            pageHasTitlepage.addEventListener('change', (e) => {
                state.structure['title-page'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputBookTitle) {
            inputBookTitle.addEventListener('input', (e) => {
                state.bookTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasCopyright) {
            pageHasCopyright.addEventListener('change', (e) => {
                state.structure['copyright'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputCopyrightText) {
            inputCopyrightText.addEventListener('input', (e) => {
                state.structure['copyright'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasDedication) {
            pageHasDedication.addEventListener('change', (e) => {
                state.structure['dedication'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputDedicationText) {
            inputDedicationText.addEventListener('input', (e) => {
                state.structure['dedication'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasEpigraph) {
            pageHasEpigraph.addEventListener('change', (e) => {
                state.structure['epigraph'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputEpigraphText) {
            inputEpigraphText.addEventListener('input', (e) => {
                state.structure['epigraph'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasAcknowledgements) {
            pageHasAcknowledgements.addEventListener('change', (e) => {
                state.structure['acknowledgements'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputAcknowledgementsTitle) {
            inputAcknowledgementsTitle.addEventListener('input', (e) => {
                state.structure['acknowledgements'].title = e.target.value;
                updatePreviewPages();
            });
        }
        if (inputAcknowledgementsText) {
            inputAcknowledgementsText.addEventListener('input', (e) => {
                state.structure['acknowledgements'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasPreface) {
            pageHasPreface.addEventListener('change', (e) => {
                state.structure['preface'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputPrefaceTitle) {
            inputPrefaceTitle.addEventListener('input', (e) => {
                state.structure['preface'].title = e.target.value;
                updatePreviewPages();
            });
        }
        if (inputPrefaceText) {
            inputPrefaceText.addEventListener('input', (e) => {
                state.structure['preface'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasEpilogue) {
            pageHasEpilogue.addEventListener('change', (e) => {
                state.structure['epilogue'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputEpilogueTitle) {
            inputEpilogueTitle.addEventListener('input', (e) => {
                state.structure['epilogue'].title = e.target.value;
                updatePreviewPages();
            });
        }
        if (inputEpilogueText) {
            inputEpilogueText.addEventListener('input', (e) => {
                state.structure['epilogue'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (pageHasBio) {
            pageHasBio.addEventListener('change', (e) => {
                state.structure['bio'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (inputBioText) {
            inputBioText.addEventListener('input', (e) => {
                state.structure['bio'].text = e.target.value;
                updatePreviewPages();
            });
        }
        if (inputBioPhoto) {
            inputBioPhoto.addEventListener('change', (e) => {
                const file = e.target.files[0];
                if (file) {
                    const reader = new FileReader();
                    reader.onload = function(event) {
                        state.structure['bio'].photo = event.target.result;
                        console.log("Foto do autor carregada com sucesso!");
                        updatePreviewPages();
                    };
                    reader.readAsDataURL(file);
                }
            });
        }
        // Lógica de alteração da fonte da biografia tratada no grupo de fontes abaixo
        if (pageHasToc) {
            pageHasToc.addEventListener('change', (e) => {
                state.structure['toc'].active = e.target.checked;
                updatePreviewPages();
            });
        }
        if (pageHasBlank) {
            pageHasBlank.addEventListener('change', (e) => {
                state.structure['blank-page'].active = e.target.checked;
                updatePreviewPages();
            });
        }

        // Font overrides selectors
        if (fontTitlepage) {
            fontTitlepage.addEventListener('change', (e) => {
                state.structure['title-page'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontTitlepageAuthor) {
            fontTitlepageAuthor.addEventListener('change', (e) => {
                state.structure['title-page'].fontAuthor = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontCopyright) {
            fontCopyright.addEventListener('change', (e) => {
                state.structure['copyright'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontCopyrightTitle) {
            fontCopyrightTitle.addEventListener('change', (e) => {
                state.structure['copyright'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontDedication) {
            fontDedication.addEventListener('change', (e) => {
                state.structure['dedication'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontDedicationTitle) {
            fontDedicationTitle.addEventListener('change', (e) => {
                state.structure['dedication'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontEpigraph) {
            fontEpigraph.addEventListener('change', (e) => {
                state.structure['epigraph'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontEpigraphTitle) {
            fontEpigraphTitle.addEventListener('change', (e) => {
                state.structure['epigraph'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontAcknowledgementsTitle) {
            fontAcknowledgementsTitle.addEventListener('change', (e) => {
                state.structure['acknowledgements'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontAcknowledgements) {
            fontAcknowledgements.addEventListener('change', (e) => {
                state.structure['acknowledgements'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontPreface) {
            fontPreface.addEventListener('change', (e) => {
                state.structure['preface'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontPrefaceTitle) {
            fontPrefaceTitle.addEventListener('change', (e) => {
                state.structure['preface'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontEpilogue) {
            fontEpilogue.addEventListener('change', (e) => {
                state.structure['epilogue'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontEpilogueTitle) {
            fontEpilogueTitle.addEventListener('change', (e) => {
                state.structure['epilogue'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (selectBioFont) {
            selectBioFont.addEventListener('change', (e) => {
                state.structure['bio'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontBioTitle) {
            fontBioTitle.addEventListener('change', (e) => {
                state.structure['bio'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontToc) {
            fontToc.addEventListener('change', (e) => {
                state.structure['toc'].font = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontTocTitle) {
            fontTocTitle.addEventListener('change', (e) => {
                state.structure['toc'].fontTitle = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontChapterNumber) {
            fontChapterNumber.addEventListener('change', (e) => {
                state.fontChapterNumber = e.target.value;
                updatePreviewPages();
            });
        }
        if (fontChapterTitle) {
            fontChapterTitle.addEventListener('change', (e) => {
                state.fontChapterTitle = e.target.value;
                updatePreviewPages();
            });
        }

        // Author inputs
        if (inputBookAuthor) {
            inputBookAuthor.addEventListener('input', (e) => {
                state.bookAuthor = e.target.value;
                updatePreviewPages();
            });
        }
        if (showAuthorTitlepage) {
            showAuthorTitlepage.addEventListener('change', (e) => {
                state.structure['title-page'].showAuthor = e.target.checked;
                updatePreviewPages();
            });
        }

        // Action Buttons listeners
        if (btnBackBook) {
            btnBackBook.addEventListener('click', () => {
                if (confirm("Deseja voltar para a tela inicial? Seu progresso atual continuará salvo e você poderá continuar de onde parou.")) {
                    state.showWorkspacePreview = false;
                    updatePreviewPages();
                }
            });
        }

        // Upload handlers
        if (docxUploadMain) {
            docxUploadMain.addEventListener('change', handleFileUpload);
        }
        if (docxUploadSidebar) {
            docxUploadSidebar.addEventListener('change', handleFileUpload);
        }

        // Collapsible Accordions for Structural Pages
        const pageCheckboxItems = document.querySelectorAll('.page-checkbox-item');
        pageCheckboxItems.forEach(item => {
            const header = item.querySelector('.page-checkbox-header');
            const checkbox = item.querySelector('input[type="checkbox"]');
            const section = item.getAttribute('data-section');
            
            // Handle clicking the header block (excluding the checkbox itself)
            if (header) {
                header.addEventListener('click', (e) => {
                    if (e.target !== checkbox) {
                        e.stopPropagation();
                        const isExpanded = item.classList.contains('expanded');
                        
                        // Collapse all others
                        pageCheckboxItems.forEach(el => el.classList.remove('expanded'));
                        
                        // If it wasn't expanded, expand it (only if it has collapsible content / chevron)
                        const hasChevron = item.querySelector('.struct-chevron');
                        if (!isExpanded && hasChevron) {
                            item.classList.add('expanded');
                            
                            // If page is not included in the book, check the checkbox automatically
                            if (checkbox && !checkbox.checked) {
                                checkbox.checked = true;
                                // Update state
                                state.structure[section].active = true;
                                updatePreviewPages();
                            }
                        }
                        
                        // Scroll the preview to this section
                        setTimeout(() => {
                            const targetPage = document.querySelector(`.page-sheet[data-section-id="${section}"]`);
                            if (targetPage) {
                                targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });
                            }
                        }, 100);
                    }
                });
            }
        });

        // General handler for structural checkbox changes to sync accordion expansion
        const structuralCheckboxes = document.querySelectorAll('.page-checkbox-item input[type="checkbox"]');
        structuralCheckboxes.forEach(cb => {
            cb.addEventListener('change', (e) => {
                const item = cb.closest('.page-checkbox-item');
                const section = item.getAttribute('data-section');
                
                if (cb.checked) {
                    // Collapse all others
                    pageCheckboxItems.forEach(el => el.classList.remove('expanded'));
                    // Expand this one (if it has sub-inputs / chevron)
                    if (item.querySelector('.struct-chevron')) {
                        item.classList.add('expanded');
                    }
                    // Scroll to it
                    setTimeout(() => {
                        const targetPage = document.querySelector(`.page-sheet[data-section-id="${section}"]`);
                        if (targetPage) {
                            targetPage.scrollIntoView({ behavior: 'smooth', block: 'start' });
                        }
                    }, 100);
                } else {
                    item.classList.remove('expanded');
                }
            });
        });



        // Spell Checker / Proofreader Event Listeners
        const btnToggleProofreader = document.getElementById('btn-toggle-proofreader');
        if (btnToggleProofreader) {
            btnToggleProofreader.addEventListener('click', () => {
                state.proofreadModeActive = !state.proofreadModeActive;
                if (state.proofreadModeActive) {
                    btnToggleProofreader.classList.add('active');
                    btnToggleProofreader.innerHTML = '<i data-lucide="loader-2" class="animate-spin"></i> Carregando Dicionário...';
                    if (window.lucide) window.lucide.createIcons();
                    
                    initSpellchecker().then(() => {
                        if (state.proofreadModeActive) {
                            btnToggleProofreader.innerHTML = '<i data-lucide="spell-check-2"></i> Desativar Corretor';
                            if (window.lucide) window.lucide.createIcons();
                            updatePreviewPages();
                        }
                    }).catch(err => {
                        btnToggleProofreader.innerHTML = '<i data-lucide="spell-check-2"></i> Desativar Corretor';
                        if (window.lucide) window.lucide.createIcons();
                        alert("Não foi possível carregar o dicionário completo em português offline. O corretor básico continuará ativo.");
                        updatePreviewPages();
                    });
                } else {
                    btnToggleProofreader.classList.remove('active');
                    btnToggleProofreader.innerHTML = '<i data-lucide="spell-check"></i> Ativar Corretor';
                    if (window.lucide) window.lucide.createIcons();
                    updatePreviewPages();
                }
            });
        }

        // Event delegation to catch clicks on proofreader highlighted errors
        document.addEventListener('click', (e) => {
            const errorSpan = e.target.closest('.proofread-error');
            if (errorSpan) {
                e.stopPropagation();
                showProofreadPopover(errorSpan);
            } else {
                // Close active popover if clicked outside
                const popover = document.getElementById('proofread-popover');
                if (popover && !e.target.closest('#proofread-popover')) {
                    popover.remove();
                }
            }
        });

        // Listen to blur events on editable paragraphs to save live edits back to state
        document.addEventListener('blur', (e) => {
            if (e.target.classList.contains('paragraph-editable')) {
                saveParagraph(e.target);
            }
        }, true);

        // Listeners dos botões de Undo/Redo na barra do cabeçalho
        const btnUndo = document.getElementById('btn-undo');
        const btnRedo = document.getElementById('btn-redo');
        if (btnUndo) btnUndo.addEventListener('click', undo);
        if (btnRedo) btnRedo.addEventListener('click', redo);

        // Atalhos de teclado para desfazer e refazer
        document.addEventListener('keydown', (e) => {
            const activeEl = document.activeElement;
            const isTyping = activeEl && (
                activeEl.tagName.toLowerCase() === 'input' || 
                activeEl.tagName.toLowerCase() === 'textarea' ||
                activeEl.isContentEditable
            );
            if (isTyping) return;
            
            // Ctrl+Z
            if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z') {
                e.preventDefault();
                undo();
            }
            // Ctrl+Y ou Ctrl+Shift+Z
            if ((e.ctrlKey || e.metaKey) && (e.key.toLowerCase() === 'y' || (e.shiftKey && e.key.toLowerCase() === 'z'))) {
                e.preventDefault();
                redo();
            }
        });
    }

    // Processamento do upload do arquivo DOCX real usando Mammoth.js
    function handleFileUpload(e) {
        const file = e.target.files[0];
        if (!file) return;
        
        console.log("Iniciando conversão do arquivo:", file.name);
        
        if (typeof mammoth === 'undefined') {
            alert("Erro: A biblioteca de leitura de arquivos Word (Mammoth.js) não pôde ser carregada. Verifique se seu computador está conectado à internet para carregar o leitor da CDN.");
            return;
        }
        
        const reader = new FileReader();
        reader.onload = function(event) {
            const arrayBuffer = event.target.result;
            
            // Converter DOCX para HTML em tempo de execução no navegador
            mammoth.convertToHtml({ arrayBuffer: arrayBuffer })
                .then(function(result) {
                    const html = result.value;
                    const parsedChapters = parseDocxHtml(html);
                    
                    let parsedTitle = file.name.replace(/\.[^/.]+$/, "");
                    // Remove leading numbers followed by dot/dash/space
                    parsedTitle = parsedTitle.replace(/^\d+\s*[-.\s]\s*/, "");
                    state.bookTitle = parsedTitle;
                    state.chapters = parsedChapters;
                    state.showWorkspacePreview = true;
                    
                    // Inicializar copyright padrão se vazio
                    if (!state.structure['copyright'].text) {
                        state.structure['copyright'].text = `Copyright © ${new Date().getFullYear()} ${state.bookAuthor || 'Autor'}. Todos os direitos reservados.`;
                    }
                    
                    syncStateToUI();
                    updatePreviewPages();
                    
                    // Inicializa o histórico para o novo livro
                    lastRecordedState = JSON.stringify(state);
                    undoStack.length = 0;
                    redoStack.length = 0;
                    updateUndoRedoButtons();
                    
                    // Calcula o novo hash do livro e gerencia a licença ativa
                    const novoHash = obterHashLivroAtual();
                    const licencaSalva = localStorage.getItem('bookforge_licenca_ativa');
                    if (licencaSalva) {
                        try {
                            const licenca = JSON.parse(licencaSalva);
                            if (licenca && licenca.hashLivro !== novoHash && licenca.hashLivro !== 'master') {
                                localStorage.removeItem('bookforge_licenca_ativa');
                            }
                        } catch(e) {}
                    }
                    localStorage.setItem('bookforge_hash_livro_atual', novoHash);
                    
                    console.log(`Sucesso: manuscrito carregado com ${state.chapters.length} capítulos.`);
                })
                .catch(function(err) {
                    console.error("Erro no processamento do Mammoth:", err);
                    alert("Erro ao decodificar arquivo Word (.docx). Verifique se o arquivo está no formato correto.");
                });
        };
        reader.onerror = function() {
            alert("Erro ao ler arquivo local.");
        };
        reader.readAsArrayBuffer(file);
    }

    // Analisa o HTML do DOCX para extrair os capítulos com base estritamente na palavra "Capítulo" ou "Capitulo"
    function parseDocxHtml(html) {
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = html;
        
        const chapters = [];
        let currentChapter = null;
        
        function startNewChapter(title) {
            currentChapter = {
                id: 'chapter-' + (chapters.length + 1),
                title: title,
                paragraphs: []
            };
            chapters.push(currentChapter);
        }
        
        const children = Array.from(tempDiv.children);
        for (let i = 0; i < children.length; i++) {
            const el = children[i];
            const text = el.textContent.trim();
            const hasImg = el.querySelector('img') !== null;
            // Ignora elementos vazios, exceto parágrafos (que servem como espaçamento) ou elementos contendo imagens
            if (!text && el.tagName.toLowerCase() !== 'p' && !hasImg) continue;
            
            // Verifica se o parágrafo inicia com "Capítulo", "Capitulo", "Epílogo", "Epilogo", "Prefácio", "Prefacio", "Prólogo", "Prologo", "Introdução" ou "Agradecimentos"
            const isChapterTitle = /^(capítulo|capitulo|epílogo|epilogo|prefácio|prefacio|prólogo|prologo|introdução|introducao|agradecimentos)\b/i.test(text);
                                   
            if (isChapterTitle) {
                let fullTitle = text;
                // Look ahead to see if the next element is a subtitle/description
                let j = i + 1;
                while (j < children.length) {
                    const nextEl = children[j];
                    const nextText = nextEl.textContent.trim();
                    const nextHasImg = nextEl.querySelector('img') !== null;
                    
                    if (!nextText && nextEl.tagName.toLowerCase() !== 'p' && !nextHasImg) {
                        j++;
                        continue;
                    }
                    
                    if (nextText) {
                        const isNextChapterTitle = /^(capítulo|capitulo|epílogo|epilogo|prefácio|prefacio|prólogo|prologo|introdução|introducao|agradecimentos)\b/i.test(nextText);
                        // Heuristic for title description: length < 100, no ending punctuation like . ! ? or quote, no dialogue markers
                        const isDescriptiveTitle = !isNextChapterTitle && 
                                                   nextText.length < 100 && 
                                                   !/[.!?\u2026]$/.test(nextText) && 
                                                   !/^[-—\"\'\u201c\u201d]/.test(nextText);
                        
                        if (isDescriptiveTitle) {
                            fullTitle += ' - ' + nextText;
                            i = j; // Skip this element since it's consumed as title
                        }
                    }
                    break;
                }
                startNewChapter(fullTitle);
            } else {
                if (currentChapter) {
                    currentChapter.paragraphs.push(el.outerHTML);
                }
            }
        }
        
        if (chapters.length === 0) {
            chapters.push({
                id: 'chapter-1',
                title: 'Capítulo I',
                content: '<p>Nenhum capítulo iniciado com a palavra "Capítulo" foi encontrado no arquivo carregado.</p>'
            });
            return chapters;
        }
        
        return chapters.map(c => ({
            id: c.id,
            title: c.title,
            content: c.paragraphs.length > 0 ? c.paragraphs.join('') : '<p>Sem conteúdo de texto neste capítulo.</p>'
        }));
    }

    // Divide recursivamente um nó de elemento (ex: <p>) preservando tags internas
    function splitElementNode(element, maxLength) {
        const cloneA = element.cloneNode(false);
        const cloneB = element.cloneNode(false);
        
        if (element.originalIndex !== undefined) {
            cloneA.originalIndex = element.originalIndex;
            cloneB.originalIndex = element.originalIndex;
        }
        
        if (element.tagName.toLowerCase() === 'p') {
            cloneB.classList.add('paragraph-continuation');
        }
        
        let currentLength = 0;
        let splitDone = false;
        
        Array.from(element.childNodes).forEach(child => {
            if (splitDone) {
                cloneB.appendChild(child.cloneNode(true));
                return;
            }
            
            const childLen = child.textContent.length;
            if (currentLength + childLen <= maxLength) {
                cloneA.appendChild(child.cloneNode(true));
                currentLength += childLen;
            } else {
                const remaining = maxLength - currentLength;
                if (child.nodeType === Node.TEXT_NODE) {
                    const text = child.textContent;
                    let splitIdx = text.lastIndexOf(' ', remaining);
                    if (splitIdx <= 0) splitIdx = remaining;
                    
                    const textA = document.createTextNode(text.substring(0, splitIdx));
                    const textB = document.createTextNode(text.substring(splitIdx));
                    
                    cloneA.appendChild(textA);
                    cloneB.appendChild(textB);
                } else {
                    const [childA, childB] = splitElementNode(child, remaining);
                    cloneA.appendChild(childA);
                    if (childB) cloneB.appendChild(childB);
                }
                splitDone = true;
            }
        });
        
        return [cloneA, cloneB];
    }

    // Mapa de limites de caracteres personalizados por família de fontes (otimizados e seguros contra estouros)
    const fontCharLimits = {
        'eb garamond': { firstOrnament: 450, firstNoOrnament: 850, normal: 1200 },
        'garamond': { firstOrnament: 450, firstNoOrnament: 850, normal: 1200 },
        'ebgaramond': { firstOrnament: 450, firstNoOrnament: 850, normal: 1200 },
        'georgia': { firstOrnament: 380, firstNoOrnament: 700, normal: 1000 },
        'merriweather': { firstOrnament: 350, firstNoOrnament: 650, normal: 950 },
        'lora': { firstOrnament: 420, firstNoOrnament: 750, normal: 1100 },
        'cinzel': { firstOrnament: 380, firstNoOrnament: 700, normal: 1000 },
        'inter': { firstOrnament: 420, firstNoOrnament: 750, normal: 1100 },
        'outfit': { firstOrnament: 420, firstNoOrnament: 750, normal: 1100 },
        'great vibes': { firstOrnament: 250, firstNoOrnament: 450, normal: 600 }
    };

    // Algoritmo de paginação dinâmico baseado em volume de caracteres com quebra inteligente de parágrafos
    function paginateChapter(chapter) {
        const pages = [];
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = chapter.content;
        
        const nodes = Array.from(tempDiv.childNodes).filter(node => {
            if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) return true;
            if (node.nodeType === Node.ELEMENT_NODE) return true;
            return false;
        }).map((node, nodeIdx) => {
            node.originalIndex = nodeIdx;
            return node;
        });
        
        const fontKey = (state.globalFont || 'eb garamond').toLowerCase().replace(/\s+/g, '');
        const limits = fontCharLimits[fontKey] || { firstOrnament: 600, firstNoOrnament: 1100, normal: 1600 };
        
        const queue = [...nodes];
        let currentPageElements = [];
        let currentLength = 0;
        let isFirstPage = true;
        
        while (queue.length > 0) {
            let node = queue.shift();
            
            // Se for nó de texto livre, converter em <p> para seguir a estrutura
            if (node.nodeType === Node.TEXT_NODE) {
                const p = document.createElement('p');
                p.textContent = node.textContent.trim();
                p.originalIndex = node.originalIndex;
                node = p;
            }
            
            let htmlContent = '';
            let textLen = node.textContent.length;
            
            if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'p') {
                node.classList.add('paragraph-editable');
                node.setAttribute('data-chapter-id', chapter.id);
                const idx = (node.originalIndex !== undefined) ? node.originalIndex : 'split';
                node.setAttribute('data-para-index', idx.toString());
                node.setAttribute('contenteditable', state.proofreadModeActive ? 'true' : 'false');
                node.setAttribute('spellcheck', state.proofreadModeActive ? 'true' : 'false');
                htmlContent = node.outerHTML;
            } else {
                htmlContent = node.outerHTML;
            }
            
            // Decide o limite de caracteres de forma dinâmica baseada no tamanho do ornamento
            const isPremium = ['montanhas', 'caravela', 'espada', 'pergaminho', 'revolver', 'cabana', 'arco', 'caneta', 'pena', 'livro', 'aguia', 'voo', 'aguia2', 'pergaminho2', 'pergaminho3', 'livro_fechado', 'princesa', 'livro_aberto'].includes(state.sceneOrnament);
            let firstPageOrnamentLimit = limits.firstOrnament;
            if (state.sceneOrnament && state.sceneOrnament !== 'none') {
                if (isPremium) {
                    // Ornamento premium é alto: limite de caracteres reduzido para não estourar a folha
                    firstPageOrnamentLimit = Math.max(150, limits.firstOrnament - 150);
                } else {
                    // Ornamento padrão é curto: pode ter mais texto
                    firstPageOrnamentLimit = Math.max(200, limits.firstOrnament - 50);
                }
            }
            
            const maxLen = isFirstPage ? ((state.sceneOrnament && state.sceneOrnament !== 'none') ? firstPageOrnamentLimit : limits.firstNoOrnament) : limits.normal;

            if (currentLength + textLen > maxLen) {
                const remaining = maxLen - currentLength;
                
                // Se o espaço restante for muito pequeno (menos de 200 caracteres) ou o parágrafo for curto,
                // apenas jogamos o parágrafo inteiro para a página seguinte para manter a legibilidade.
                if (remaining < 200 || textLen < 250) {
                    if (currentPageElements.length > 0) {
                        pages.push({
                            paragraphs: [...currentPageElements]
                        });
                        currentPageElements = [];
                        currentLength = 0;
                        isFirstPage = false;
                        queue.unshift(node);
                    } else {
                        // Página vazia e o parágrafo não cabe de jeito nenhum: divide
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            const [partA, partB] = splitElementNode(node, remaining);
                            currentPageElements.push(partA.outerHTML);
                            currentLength += partA.textContent.length;
                            
                            if (partB && partB.textContent.trim().length > 0) {
                                queue.unshift(partB);
                            }
                        } else {
                            const text = node.textContent;
                            let splitIdx = text.lastIndexOf(' ', remaining);
                            if (splitIdx <= 0) splitIdx = remaining;
                            
                            const partA = document.createTextNode(text.substring(0, splitIdx));
                            const partB = document.createTextNode(text.substring(splitIdx));
                            
                            currentPageElements.push(partA.textContent);
                            currentLength += partA.textContent.length;
                            if (partB.textContent.trim().length > 0) {
                                queue.unshift(partB);
                            }
                        }
                    }
                } else {
                    // Divide o parágrafo para preencher o restante da página atual
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        const [partA, partB] = splitElementNode(node, remaining);
                        currentPageElements.push(partA.outerHTML);
                        currentLength += partA.textContent.length;
                        
                        pages.push({
                            paragraphs: [...currentPageElements]
                        });
                        currentPageElements = [];
                        currentLength = 0;
                        isFirstPage = false;
                        
                        if (partB && partB.textContent.trim().length > 0) {
                            queue.unshift(partB);
                        }
                    } else {
                        const text = node.textContent;
                        let splitIdx = text.lastIndexOf(' ', remaining);
                        if (splitIdx <= 0) splitIdx = remaining;
                        
                        const partA = document.createTextNode(text.substring(0, splitIdx));
                        const partB = document.createTextNode(text.substring(splitIdx));
                        
                        currentPageElements.push(partA.textContent);
                        currentLength += partA.textContent.length;
                        
                        pages.push({
                            paragraphs: [...currentPageElements]
                        });
                        currentPageElements = [];
                        currentLength = 0;
                        isFirstPage = false;
                        
                        if (partB.textContent.trim().length > 0) {
                            queue.unshift(partB);
                        }
                    }
                }
            } else {
                currentPageElements.push(htmlContent);
                currentLength += textLen;
            }
        }
        
        if (currentPageElements.length > 0) {
            pages.push({
                paragraphs: currentPageElements
            });
        }
        
        return pages;
    }

    // Pagina texto de áreas estruturais (textarea) com quebra de parágrafos longos, limites de fonte e penalidade de parágrafos
    function paginateTextareaText(text, isFirstPageHasHeader = true, customFont = '', firstPageLimitOverride = null) {
        if (!text) return ['<p>&nbsp;</p>'];
        const paragraphs = text.split('\n').map(p => p.trim()).filter(p => p.length > 0);
        const pages = [];
        let currentPageParagraphs = [];
        let currentLength = 0;
        let isFirstPage = true;
        
        const fontName = customFont || state.globalFont || 'eb garamond';
        const fontKey = fontName.toLowerCase().replace(/\s+/g, '');
        const limits = fontCharLimits[fontKey] || { firstOrnament: 600, firstNoOrnament: 1100, normal: 1600 };
        
        const queue = [...paragraphs];
        while (queue.length > 0) {
            const pText = queue.shift();
            // Adiciona penalidade de 60 caracteres por parágrafo para simular margem vertical
            const textLen = pText.length + 60; 
            
            let maxLen = limits.normal;
            if (isFirstPage) {
                if (firstPageLimitOverride !== null) {
                    maxLen = firstPageLimitOverride;
                } else if (isFirstPageHasHeader) {
                    maxLen = limits.firstNoOrnament;
                }
            }
            
            if (currentLength + textLen > maxLen) {
                if (currentPageParagraphs.length > 0) {
                    pages.push(currentPageParagraphs.join(''));
                    currentPageParagraphs = [];
                    currentLength = 0;
                    isFirstPage = false;
                    queue.unshift(pText);
                } else {
                    // Parágrafo único muito longo para caber na página atual, divide em palavras
                    const remaining = maxLen - currentLength - 60;
                    if (remaining <= 50) {
                        // Muito pouco espaço sobrando, manda o parágrafo inteiro para a próxima página
                        pages.push(currentPageParagraphs.join(''));
                        currentPageParagraphs = [];
                        currentLength = 0;
                        isFirstPage = false;
                        queue.unshift(pText);
                    } else {
                        let splitIdx = pText.lastIndexOf(' ', remaining);
                        if (splitIdx <= 0) splitIdx = remaining;
                        
                        const partA = pText.substring(0, splitIdx);
                        const partB = pText.substring(splitIdx).trim();
                        
                        currentPageParagraphs.push(`<p>${partA}</p>`);
                        currentLength += partA.length + 120;
                        if (partB.length > 0) {
                            queue.unshift(partB);
                        }
                    }
                }
            } else {
                currentPageParagraphs.push(`<p>${pText}</p>`);
                currentLength += textLen;
            }
        }
        
        if (currentPageParagraphs.length > 0) {
            pages.push(currentPageParagraphs.join(''));
        }
        
        if (pages.length === 0) {
            pages.push('<p>&nbsp;</p>');
        }
        
        return pages;
    }

    // Injeta estilo CSS dinâmico para a cor dos detalhes (ornamentos e letra capitular)
    function updateDynamicStyle() {
        let styleTag = document.getElementById('dynamic-decorations-style');
        if (!styleTag) {
            styleTag = document.createElement('style');
            styleTag.id = 'dynamic-decorations-style';
            document.head.appendChild(styleTag);
        }
        const color = state.decorationsColor || '#000000';
        styleTag.textContent = `
            .page-ornament {
                color: ${color} !important;
            }
            .page-ornament svg {
                color: ${color} !important;
            }
            .page-ornament svg path {
                color: ${color} !important;
            }
            .has-dropcap p:first-of-type::first-letter {
                color: ${color} !important;
            }
            .page-border-frame {
                border-color: ${color} !important;
                color: ${color} !important;
            }
            .page-border-frame svg {
                color: ${color} !important;
            }
        `;
    }

    // Injeta estilo CSS dinâmico para a impressão (PDF) respeitando o formato e as margens do livro
    function updatePrintStyle() {
        let styleTag = document.getElementById('dynamic-print-style');
        if (!styleTag) {
            styleTag = document.createElement('style');
            styleTag.id = 'dynamic-print-style';
            document.head.appendChild(styleTag);
        }
        
        let sizeStr = '140mm 210mm';
        let widthStr = '140mm';
        let heightStr = '210mm';
        let padStr = '20mm 18mm';
        
        if (state.bookFormat === 'A5') {
            sizeStr = '148mm 210mm';
            widthStr = '148mm';
            heightStr = '210mm';
            padStr = '20mm 18mm';
        } else if (state.bookFormat === '16x23') {
            sizeStr = '160mm 230mm';
            widthStr = '160mm';
            heightStr = '230mm';
            padStr = '22mm 20mm';
        }
        
        styleTag.textContent = `
            @media print {
                @page {
                    size: ${sizeStr} !important;
                    margin: 0 !important;
                }
                .page-sheet {
                    width: ${widthStr} !important;
                    height: ${heightStr} !important;
                    padding: ${padStr} !important;
                }
            }
        `;
    }

    function saveProgress() {
        try {
            localStorage.setItem('bookforge_saved_state', JSON.stringify(state));
            const hash = obterHashLivroAtual();
            localStorage.setItem('bookforge_hash_livro_atual', hash);
            
            // Backup automático em arquivo físico no disco rígido
            fetch('/api/save-backup', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(state)
            }).catch(err => console.error("Erro ao salvar backup em disco:", err));
            
        } catch (e) {
            console.error("Erro ao salvar progresso automaticamente:", e);
        }
    }

    // Carrega o estado salvo anteriormente e reconfigura o workspace
    function loadSavedProgress() {
        const savedData = localStorage.getItem('bookforge_saved_state');
        if (!savedData) return;
        
        try {
            const savedState = JSON.parse(savedData);
            
            // Copiar propriedades para o estado atual
            Object.assign(state, savedState);
            
            // Forçar a visualização do workspace ativo ao carregar progresso salvo
            state.showWorkspacePreview = true;
            
            // Sincronizar inputs
            syncStateToUI();
            
            // Re-renderizar páginas
            updatePreviewPages();
            
            // Inicializa o histórico para o livro carregado
            lastRecordedState = JSON.stringify(state);
            undoStack.length = 0;
            redoStack.length = 0;
            updateUndoRedoButtons();
            
            const hash = obterHashLivroAtual();
            localStorage.setItem('bookforge_hash_livro_atual', hash);
            
            // Ocultar o botão depois de carregado
            if (btnContinueWork) {
                btnContinueWork.style.display = 'none';
            }
            
            console.log("Progresso do livro restaurado com sucesso!");
        } catch (e) {
            console.error("Erro ao restaurar progresso:", e);
            alert("Não foi possível carregar o progresso anterior.");
        }
    }

    // Compila e exporta o livro no formato EPUB (.epub) real via JSZip
    function exportBookEPUB() {
        if (state.chapters.length === 0) {
            alert("Por favor, suba seu livro primeiro antes de exportar!");
            return;
        }

        // Verifica licença
        const hashLivroAtual = localStorage.getItem('bookforge_hash_livro_atual') || obterHashLivroAtual();
        const licencaRaw = localStorage.getItem('bookforge_licenca_ativa');
        let licenca = null;
        try {
            licenca = JSON.parse(licencaRaw);
        } catch(e) {
            licenca = null;
        }

        if (!licenca || (licenca.hashLivro !== hashLivroAtual && licenca.hashLivro !== 'master') || licenca.epub) {
            if (typeof mostrarModalLicenca === 'function') {
                mostrarModalLicenca('EPUB');
            } else {
                alert('⚠️ Licença inválida ou já consumida para este formato.');
            }
            return;
        }

        if (typeof JSZip === 'undefined') {
            alert("Erro: A biblioteca JSZip não foi carregada. Verifique sua conexão com a internet.");
            return;
        }

        // Consome a licença
        licenca.epub = true;
        localStorage.setItem('bookforge_licenca_ativa', JSON.stringify(licenca));

        const zip = new JSZip();

        // 1. Arquivo mimetype (obrigatório sem compressão na raiz do EPUB)
        zip.file('mimetype', 'application/epub+zip', { compression: 'STORE' });

        // 2. Pasta META-INF/container.xml
        zip.file('META-INF/container.xml', `<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
    <rootfiles>
        <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
    </rootfiles>
</container>`);

        // 3. Estilos CSS do EPUB (OEBPS/styles.css)
        const epubCss = `
body {
    font-family: 'Georgia', serif;
    margin: 10% 8%;
    line-height: 1.5;
    text-align: justify;
}
h1, h2, h3 {
    text-align: center;
    text-transform: uppercase;
}
.chapter-number {
    display: block;
    font-size: 1.2em;
    font-weight: bold;
    margin-bottom: 0.5em;
    text-align: center;
}
.chapter-title {
    display: block;
    font-size: 1.6em;
    font-weight: bold;
    text-align: center;
    margin-bottom: 1.5em;
}
p {
    text-indent: 1.5em;
    margin-bottom: 0;
    margin-top: 0;
}
.titlepage {
    text-align: center;
    margin-top: 25%;
}
.titlepage-title {
    font-size: 2em;
    font-weight: bold;
}
.titlepage-author {
    font-size: 1.2em;
    margin-top: 2em;
}
.copyright-page {
    margin-top: 50%;
    font-size: 0.9em;
}
`;
        zip.file('OEBPS/styles.css', epubCss);

        // 4. Montar os arquivos XHTML de conteúdo
        let manifestItems = '';
        let spineItems = '';
        let tocEntries = '';
        let playOrder = 1;

        // Folha de Rosto
        if (state.structure['title-page'] && state.structure['title-page'].active) {
            const titleHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>${state.bookTitle || 'Folha de Rosto'}</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <div class="titlepage">
        <h1 class="titlepage-title">${state.bookTitle || 'Sem Título'}</h1>
        ${state.structure['title-page'].showAuthor ? `<p class="titlepage-author">${state.bookAuthor || 'Autor'}</p>` : ''}
    </div>
</body>
</html>`;
            zip.file('OEBPS/title.xhtml', titleHtml);
            manifestItems += `    <item id="title" href="title.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="title"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>Folha de Rosto</text></navLabel>\n      <content src="title.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Biografia
        if (state.structure['bio'] && state.structure['bio'].active && state.structure['bio'].text) {
            const paragraphsHtml = state.structure['bio'].text.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            
            let bioPhotoHtml = '';
            if (state.structure['bio'].photo) {
                const match = state.structure['bio'].photo.match(/^data:(image\/[a-zA-Z0-9\-\+]+);base64,([\s\S]*)$/);
                if (match) {
                    const mimeType = match[1];
                    const base64Data = match[2];
                    const extension = mimeType.split('/')[1] || 'jpg';
                    
                    zip.file(`OEBPS/author_photo.${extension}`, base64Data, { base64: true });
                    manifestItems += `    <item id="author_photo" href="author_photo.${extension}" media-type="${mimeType}"/>\n`;
                    bioPhotoHtml = `<p style="text-align: center;"><img src="author_photo.${extension}" alt="Autor" width="150" height="150" style="width: 150px; height: 150px; border-radius: 75px;" /></p>\n`;
                }
            }

            const bioHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Sobre o Autor</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <h1>Sobre o Autor</h1>
    ${bioPhotoHtml}
    <div class="chapter-content">
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/bio.xhtml', bioHtml);
            manifestItems += `    <item id="bio" href="bio.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="bio"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>Sobre o Autor</text></navLabel>\n      <content src="bio.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Copyright
        if (state.structure['copyright'] && state.structure['copyright'].active) {
            const copyrightText = state.structure['copyright'].text || `Copyright © ${new Date().getFullYear()} ${state.bookAuthor || 'Autor'}. Todos os direitos reservados.`;
            const paragraphsHtml = copyrightText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            const copyrightHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Copyright</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <div class="copyright-page">
        <h2>Copyright</h2>
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/copyright.xhtml', copyrightHtml);
            manifestItems += `    <item id="copyright" href="copyright.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="copyright"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>Copyright</text></navLabel>\n      <content src="copyright.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Dedicatória
        if (state.structure['dedication'] && state.structure['dedication'].active && state.structure['dedication'].text) {
            const paragraphsHtml = state.structure['dedication'].text.split('\n').map(p => `<p><i>${p.trim()}</i></p>`).join('\n');
            const dedicationHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Dedicatória</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <div style="margin-top: 30%; text-align: center;">
        <h2>Dedicatória</h2>
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/dedication.xhtml', dedicationHtml);
            manifestItems += `    <item id="dedication" href="dedication.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="dedication"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>Dedicatória</text></navLabel>\n      <content src="dedication.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Epígrafe
        if (state.structure['epigraph'] && state.structure['epigraph'].active && state.structure['epigraph'].text) {
            const paragraphsHtml = state.structure['epigraph'].text.split('\n').map(p => `<p><i>${p.trim()}</i></p>`).join('\n');
            const epigraphHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Epígrafe</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <div style="margin-top: 30%; text-align: center;">
        <h2 style="text-align: center; text-transform: uppercase;">Epígrafe</h2>
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/epigraph.xhtml', epigraphHtml);
            manifestItems += `    <item id="epigraph" href="epigraph.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="epigraph"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>Epígrafe</text></navLabel>\n      <content src="epigraph.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Prefácio
        if (state.structure['preface'] && state.structure['preface'].active && state.structure['preface'].text) {
            const paragraphsHtml = state.structure['preface'].text.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            const prefTitle = state.structure['preface'].title || 'Prefácio';
            const prefaceHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>${prefTitle}</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <h1>${prefTitle}</h1>
    <div class="chapter-content">
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/preface.xhtml', prefaceHtml);
            manifestItems += `    <item id="preface" href="preface.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="preface"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>${prefTitle}</text></navLabel>\n      <content src="preface.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Capítulos
        state.chapters.forEach((ch, idx) => {
            const chId = `chapter_${idx + 1}`;
            let bodyContent = ch.content;
            
            let titleHeaderHtml = `<h1>${ch.title}</h1>`;
            const match = ch.title.match(/^(cap\u00edtulo|capitulo)\s+([a-zA-Z0-9\u2160-\u217F]+)(?:\s*[-–—:]\s*|\s+)(.*)$/i);
            if (match) {
                const capWordAndNum = `${match[1]} ${match[2]}`;
                const remainingTitle = match[3].trim();
                titleHeaderHtml = `<span class="chapter-number">${capWordAndNum}</span>\n<span class="chapter-title">${remainingTitle}</span>`;
            }

            const chapterHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>${ch.title}</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    ${titleHeaderHtml}
    <div class="chapter-content">
        ${bodyContent}
    </div>
</body>
</html>`;
            zip.file(`OEBPS/${chId}.xhtml`, chapterHtml);
            manifestItems += `    <item id="${chId}" href="${chId}.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="${chId}"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>${ch.title}</text></navLabel>\n      <content src="${chId}.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        });

        // Epílogo
        if (state.structure['epilogue'] && state.structure['epilogue'].active && state.structure['epilogue'].text) {
            const paragraphsHtml = state.structure['epilogue'].text.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            const epilogueTitle = state.structure['epilogue'].title || 'Epílogo';
            const epilogueHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>${epilogueTitle}</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <h1>${epilogueTitle}</h1>
    <div class="chapter-content">
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/epilogue.xhtml', epilogueHtml);
            manifestItems += `    <item id="epilogue" href="epilogue.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="epilogue"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>${epilogueTitle}</text></navLabel>\n      <content src="epilogue.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // Agradecimentos
        if (state.structure['acknowledgements'] && state.structure['acknowledgements'].active && state.structure['acknowledgements'].text) {
            const paragraphsHtml = state.structure['acknowledgements'].text.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            const ackTitle = state.structure['acknowledgements'].title || 'Agradecimentos';
            const ackHtml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>${ackTitle}</title>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <h1>${ackTitle}</h1>
    <div class="chapter-content">
        ${paragraphsHtml}
    </div>
</body>
</html>`;
            zip.file('OEBPS/acknowledgements.xhtml', ackHtml);
            manifestItems += `    <item id="acknowledgements" href="acknowledgements.xhtml" media-type="application/xhtml+xml"/>\n`;
            spineItems += `    <itemref idref="acknowledgements"/>\n`;
            tocEntries += `    <navPoint id="navPoint-${playOrder}" playOrder="${playOrder}">\n      <navLabel><text>${ackTitle}</text></navLabel>\n      <content src="acknowledgements.xhtml"/>\n    </navPoint>\n`;
            playOrder++;
        }

        // 5. Arquivo OEBPS/toc.ncx (Sumário XML do EPUB)
        const ncxContent = `<?xml version="1.0" encoding="UTF-8"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
    <head>
        <meta name="dtb:uid" content="urn:uuid:bookforge-pro-turbo-${Date.now()}"/>
        <meta name="dtb:depth" content="1"/>
        <meta name="dtb:totalPageCount" content="0"/>
        <meta name="dtb:maxPageNumber" content="0"/>
    </head>
    <docTitle>
        <text>${state.bookTitle || 'Livro'}</text>
    </docTitle>
    <navMap>
${tocEntries}
    </navMap>
</ncx>`;
        zip.file('OEBPS/toc.ncx', ncxContent);

        // 6. Arquivo OEBPS/content.opf (Manifesto XML do EPUB)
        const opfContent = `<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookID" version="2.0">
    <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
        <dc:title>${state.bookTitle || 'Sem Título'}</dc:title>
        <dc:creator opf:role="aut">${state.bookAuthor || 'Autor Anônimo'}</dc:creator>
        <dc:language>pt-BR</dc:language>
        <dc:identifier id="BookID" opf:scheme="UUID">urn:uuid:bookforge-pro-turbo-${Date.now()}</dc:identifier>
    </metadata>
    <manifest>
        <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
        <item id="css" href="styles.css" media-type="text/css"/>
${manifestItems}
    </manifest>
    <spine toc="ncx">
${spineItems}
    </spine>
</package>`;
        zip.file('OEBPS/content.opf', opfContent);

        // Gerar o ZIP e disparar download do arquivo .epub
        zip.generateAsync({ type: 'blob' }).then(function (content) {
            const link = document.createElement('a');
            link.href = URL.createObjectURL(content);
            link.download = `${state.bookTitle || 'Livro'} - ${state.bookAuthor || 'Autor'}.epub`.replace(/[\\/:*?"<>|]/g, '-');
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }).catch(err => {
            console.error("Erro ao gerar EPUB:", err);
            alert("Erro ao exportar arquivo EPUB.");
        });
    }

    // Compila e exporta o livro no formato Word (.doc) compatível com MS Word
    function exportBookWord() {
        if (state.chapters.length === 0) {
            alert("Por favor, suba seu livro primeiro antes de exportar!");
            return;
        }

        // Verifica licença
        const hashLivroAtual = localStorage.getItem('bookforge_hash_livro_atual') || obterHashLivroAtual();
        const licencaRaw = localStorage.getItem('bookforge_licenca_ativa');
        let licenca = null;
        try {
            licenca = JSON.parse(licencaRaw);
        } catch(e) {
            licenca = null;
        }

        if (!licenca || (licenca.hashLivro !== hashLivroAtual && licenca.hashLivro !== 'master') || licenca.word) {
            if (typeof mostrarModalLicenca === 'function') {
                mostrarModalLicenca('Word');
            } else {
                alert('⚠️ Licença inválida ou já consumida para este formato.');
            }
            return;
        }

        // Consome a licença
        licenca.word = true;
        localStorage.setItem('bookforge_licenca_ativa', JSON.stringify(licenca));

        const wrapBase64 = (str) => {
            if (!str) return '';
            const chunks = str.match(/.{1,76}/g);
            return chunks ? chunks.join('\n') : str;
        };

        const nomeArquivo = `${state.bookTitle || 'Livro'} - ${state.bookAuthor || 'Autor'}`.replace(/[\\/:*?"<>|]/g, '-');

        // Formato de tamanho e margens para o Word correspondente
        let sizeStyle = 'size: 14.0cm 21.0cm; margin: 2.0cm 2.0cm 2.0cm 2.0cm;';
        if (state.bookFormat === 'A5') {
            sizeStyle = 'size: 14.8cm 21.0cm; margin: 2.0cm 2.0cm 2.0cm 2.0cm;';
        } else if (state.bookFormat === '16x23') {
            sizeStyle = 'size: 16.0cm 23.0cm; margin: 2.2cm 2.0cm 2.2cm 2.0cm;';
        }

        // Fontes configuradas pelo usuário
        const bodyFont = state.globalFont || 'EB Garamond';
        const titleFont = (state.structure['title-page'] && state.structure['title-page'].font) || 'Cinzel';
        const titleAuthorFont = (state.structure['title-page'] && state.structure['title-page'].fontAuthor) || 'EB Garamond';
        const copyrightFont = (state.structure['copyright'] && state.structure['copyright'].font) || 'EB Garamond';
        const copyrightTitleFont = (state.structure['copyright'] && state.structure['copyright'].fontTitle) || 'Cinzel';
        const dedicationFont = (state.structure['dedication'] && state.structure['dedication'].font) || 'Great Vibes';
        const dedicationTitleFont = (state.structure['dedication'] && state.structure['dedication'].fontTitle) || 'Cinzel';
        const epigraphFont = (state.structure['epigraph'] && state.structure['epigraph'].font) || 'Great Vibes';
        const epigraphTitleFont = (state.structure['epigraph'] && state.structure['epigraph'].fontTitle) || 'Cinzel';
        const ackFont = (state.structure['acknowledgements'] && state.structure['acknowledgements'].font) || 'EB Garamond';
        const ackTitleFont = (state.structure['acknowledgements'] && state.structure['acknowledgements'].fontTitle) || 'Cinzel';
        const prefaceFont = (state.structure['preface'] && state.structure['preface'].font) || 'EB Garamond';
        const prefaceTitleFont = (state.structure['preface'] && state.structure['preface'].fontTitle) || 'Cinzel';
        const epilogueFont = (state.structure['epilogue'] && state.structure['epilogue'].font) || 'EB Garamond';
        const epilogueTitleFont = (state.structure['epilogue'] && state.structure['epilogue'].fontTitle) || 'Cinzel';
        const bioFont = (state.structure['bio'] && state.structure['bio'].font) || 'EB Garamond';
        const bioTitleFont = (state.structure['bio'] && state.structure['bio'].fontTitle) || 'Cinzel';
        const chapterNumberFont = state.fontChapterNumber || 'Cinzel';
        const chapterTitleFont = state.fontChapterTitle || 'EB Garamond';

        // Helper para ornamento textual
        function getWordOrnamentText(name) {
            switch (name) {
                case 'fleur':
                case 'raminho': return '❦';
                case 'oliveira': return '🌿';
                case 'arabesco': return '❧';
                case 'pena': return '✒';
                case 'videira': return '✿';
                case 'crown':
                case 'coroa': return '❖';
                case 'diamante': return '◆';
                case 'divisor': return '───── ❖ ─────';
                case 'lis': return '⚜';
                case 'estrela': return '✦';
                case 'infinito': return '∞';
                case 'espiral': return '◎';
                case 'montanhas': return '🏔';
                case 'castelo': return '🏰';
                case 'caravela': return '⛵';
                case 'espada': return '⚔';
                case 'pergaminho': return '📜';
                case 'balao': return '🎈';
                case 'varinha': return '✨';
                case 'rosas': return '✿ 🌹 ✿';
                case 'revolver': return '🔫';
                case 'cabana': return '🏠';
                case 'arco': return '🏹';
                case 'caneta': return '🖋';
                case 'livro': return '📖';
                case 'aguia':
                case 'voo':
                case 'aguia2': return '🦅';
                case 'pergaminho2':
                case 'pergaminho3': return '📜';
                case 'livro_fechado': return '📖';
                case 'princesa': return '👑';
                case 'livro_aberto': return '📖';
                default: return '';
            }
        }

        // Configuração de MHTML Multipart para embutir imagem base64
        const boundary = 'NEXT.ITEM-BOUNDARY';
        let base64Image = '';
        let mimeType = 'image/jpeg';
        let hasPhoto = false;

        if (state.structure['bio'] && state.structure['bio'].active && state.structure['bio'].photo) {
            const match = state.structure['bio'].photo.match(/^data:(image\/[a-zA-Z0-9\-\+]+);base64,([\s\S]*)$/);
            if (match) {
                mimeType = match[1];
                base64Image = match[2];
                hasPhoto = true;
            }
        }

        let photoExtension = 'jpg';
        if (hasPhoto && mimeType) {
            const ext = mimeType.split('/')[1];
            if (ext) photoExtension = ext;
        }

        let wordHtml = `
            <html xmlns:o="urn:schemas-microsoft-com:office:office" 
                  xmlns:w="urn:schemas-microsoft-com:office:word" 
                  xmlns="http://www.w3.org/TR/REC-html40">
            <head>
                <meta charset="utf-8">
                <title>${state.bookTitle || 'Livro'}</title>
                <!--[if gte mso 9]>
                <xml>
                    <w:WordDocument>
                        <w:View>Print</w:View>
                        <w:Zoom>100</w:Zoom>
                        <w:DoNotOptimizeForBrowser/>
                    </w:WordDocument>
                </xml>
                <![endif]-->
                <link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Great+Vibes&family=EB+Garamond:ital,wght@0,400..700;1,400..700&family=Lora:ital,wght@0,400..700;1,400..700&family=Merriweather:ital,wght@0,300..900;1,300..900&family=Inter:wght@300;400;600&family=Outfit:wght@300;400;600&display=swap" rel="stylesheet">
                <style>
                    @page Section1 {
                        ${sizeStyle}
                        mso-header-margin: 1.0cm;
                        mso-footer-margin: 1.0cm;
                        mso-paper-source: 0;
                    }
                    div.Section1 {
                        page: Section1;
                    }
                    
                    body {
                        font-family: '${bodyFont}', 'Georgia', serif;
                        font-size: 11.5pt;
                        line-height: 1.5;
                        color: #000000;
                    }
                    
                    p {
                        text-align: justify !important;
                        text-indent: 1.25cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0cm !important;
                        line-height: 1.5 !important;
                        font-family: '${bodyFont}', 'Georgia', serif;
                        font-size: 11.5pt;
                    }
                    
                    /* Parágrafos vazios (espaçamentos / quebras de cena) */
                    p.empty-paragraph {
                        text-indent: 0cm !important;
                        margin-top: 12pt !important;
                        margin-bottom: 12pt !important;
                        line-height: 1.0 !important;
                        font-size: 11.5pt;
                    }
                    
                    /* Remove recuo do primeiro parágrafo de cada capítulo */
                    p.first-paragraph, 
                    .first-paragraph {
                        text-indent: 0cm !important;
                    }
                    
                    .titlepage {
                        text-align: center;
                        padding-top: 5cm;
                    }
                    .titlepage-title {
                        font-family: '${titleFont}', 'Georgia', serif;
                        font-size: 28pt;
                        font-weight: bold;
                        margin-bottom: 1cm;
                        text-transform: uppercase;
                    }
                    .titlepage-line {
                        width: 3cm;
                        border-top: 1px solid #c5a059;
                        margin: 1.5cm auto;
                    }
                    .titlepage-author {
                        font-family: '${titleAuthorFont}', 'Georgia', serif;
                        font-size: 14pt;
                        margin-top: 4cm;
                        text-transform: uppercase;
                        letter-spacing: 1px;
                    }
                    
                    .copyright-page {
                        margin-top: 5cm;
                    }
                    .copyright-title {
                        font-family: '${copyrightTitleFont}', 'Georgia', serif;
                        font-size: 16pt;
                        font-weight: bold;
                        text-align: center;
                        margin-bottom: 1.5cm;
                        text-transform: uppercase;
                    }
                    .copyright-page p {
                        font-family: '${copyrightFont}', 'Georgia', serif;
                        font-size: 10pt;
                        text-indent: 0cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                        text-align: justify !important;
                    }
                    
                    .dedication-page {
                        text-align: center;
                        margin-top: 6cm;
                        padding: 0 1cm;
                    }
                    .dedication-title {
                        font-family: '${dedicationTitleFont}', 'Georgia', serif;
                        font-size: 16pt;
                        font-weight: bold;
                        margin-bottom: 1.5cm;
                        text-transform: uppercase;
                    }
                    .dedication-page p {
                        font-family: '${dedicationFont}', 'Georgia', serif;
                        font-size: 13pt;
                        font-style: italic;
                        text-indent: 0cm !important;
                        text-align: center !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                    }
                    
                    .epigraph-page {
                        text-align: center;
                        margin-top: 7cm;
                        padding: 0 1cm;
                    }
                    .epigraph-title {
                        font-family: '${epigraphTitleFont}', 'Georgia', serif;
                        font-size: 16pt;
                        font-weight: bold;
                        margin-bottom: 1.5cm;
                        text-transform: uppercase;
                        text-align: center !important;
                    }
                    .epigraph-page p {
                        font-family: '${epigraphFont}', 'Georgia', serif;
                        font-size: 13pt;
                        font-style: italic;
                        text-indent: 0cm !important;
                        text-align: center !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                    }
                    
                    .chapter-header {
                        text-align: center;
                        margin-top: 3cm;
                        margin-bottom: 1.8cm;
                    }
                    .chapter-number {
                        font-family: '${chapterNumberFont}', 'Georgia', serif;
                        font-size: 12pt;
                        font-weight: bold;
                        display: block;
                        margin-bottom: 0.4cm;
                        text-transform: uppercase;
                        letter-spacing: 2px;
                    }
                    .chapter-title {
                        font-family: '${chapterTitleFont}', 'Georgia', serif;
                        font-size: 22pt;
                        font-weight: bold;
                        display: block;
                        text-transform: uppercase;
                        letter-spacing: 1px;
                    }
                    
                    .ack-page p {
                        font-family: '${ackFont}', 'Georgia', serif;
                        text-indent: 0cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                        text-align: justify !important;
                    }
                    .ack-title {
                        font-family: '${ackTitleFont}', 'Georgia', serif;
                    }
                    
                    .preface-page p {
                        font-family: '${prefaceFont}', 'Georgia', serif;
                        text-indent: 0cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                        text-align: justify !important;
                    }
                    .preface-title {
                        font-family: '${prefaceTitleFont}', 'Georgia', serif;
                    }
                    
                    .epilogue-page p {
                        font-family: '${epilogueFont}', 'Georgia', serif;
                        text-indent: 0cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                        text-align: justify !important;
                    }
                    .epilogue-title {
                        font-family: '${epilogueTitleFont}', 'Georgia', serif;
                    }
                    
                    .bio-page p {
                        font-family: '${bioFont}', 'Georgia', serif;
                        text-indent: 0cm !important;
                        margin-top: 0cm !important;
                        margin-bottom: 0.3cm !important;
                        text-align: justify !important;
                    }
                    .bio-title {
                        font-family: '${bioTitleFont}', 'Georgia', serif;
                    }
                    .bio-photo-container {
                        text-align: center !important;
                        text-indent: 0cm !important;
                        margin-top: 0.5cm !important;
                        margin-bottom: 0.8cm !important;
                    }
                    .bio-photo {
                        width: 120px !important;
                        height: 120px !important;
                        border-radius: 60px !important;
                        border: 1px solid #c5a059 !important;
                    }
                </style>
            </head>
            <body>
                <div class="Section1">
        `;

        let isFirstSection = true;

        // Helper para quebra de página
        function addPageBreak() {
            if (isFirstSection) {
                isFirstSection = false;
                return '';
            }
            return '<p style="page-break-before: always; mso-special-character: page-break; margin: 0; padding: 0; line-height: 1px; font-size: 1pt;"></p>';
        }

        // 1. Folha de Rosto
        if (state.structure['title-page'] && state.structure['title-page'].active) {
            wordHtml += addPageBreak();
            wordHtml += `
                <div class="titlepage">
                    <div class="titlepage-title">${state.bookTitle || 'Sem Título'}</div>
                    <div class="titlepage-line"></div>
                    ${state.structure['title-page'].showAuthor ? `<div class="titlepage-author">${state.bookAuthor || 'Autor Anônimo'}</div>` : ''}
                </div>
            `;
        }

        // 2. Biografia (Moved to position 2 to match book preview!)
        if (state.structure['bio'] && state.structure['bio'].active) {
            wordHtml += addPageBreak();
            const bioText = state.structure['bio'].text || '';
            const paragraphsHtml = bioText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            
            let bioPhotoHtml = '';
            if (hasPhoto) {
                bioPhotoHtml = `<p class="bio-photo-container"><img class="bio-photo" width="120" height="120" src="file:///C:/author_photo.${photoExtension}" /></p>`;
            }

            wordHtml += `
                <div class="chapter-page bio-page">
                    <div class="chapter-header">
                        <span class="chapter-title bio-title">Sobre o Autor</span>
                    </div>
                    <div class="chapter-body bio-body">
                        ${bioPhotoHtml}
                        ${paragraphsHtml}
                    </div>
                </div>
            `;
        }

        // 3. Copyright
        if (state.structure['copyright'] && state.structure['copyright'].active) {
            wordHtml += addPageBreak();
            const copyrightText = state.structure['copyright'].text || `Todos os direitos reservados.\nCopyright © ${new Date().getFullYear()} ${state.bookAuthor || 'Autor'}`;
            const paragraphsHtml = copyrightText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="copyright-page">
                    <div class="copyright-title">COPYRIGHT</div>
                    ${paragraphsHtml}
                </div>
            `;
        }

        // 4. Dedicatória
        if (state.structure['dedication'] && state.structure['dedication'].active) {
            wordHtml += addPageBreak();
            const dedicationText = state.structure['dedication'].text || 'Dedico este livro a todos os leitores que acreditam no recomeço.';
            const paragraphsHtml = dedicationText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="dedication-page">
                    <div class="dedication-title">DEDICATÓRIA</div>
                    ${paragraphsHtml}
                </div>
            `;
        }

        // 5. Epígrafe
        if (state.structure['epigraph'] && state.structure['epigraph'].active) {
            wordHtml += addPageBreak();
            const epigraphText = state.structure['epigraph'].text || 'Uma citação inspiradora no início da obra.';
            const paragraphsHtml = epigraphText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="epigraph-page">
                    <div class="epigraph-title">EPÍGRAFE</div>
                    ${paragraphsHtml}
                </div>
            `;
        }

        // 6. Prefácio
        if (state.structure['preface'] && state.structure['preface'].active) {
            wordHtml += addPageBreak();
            const prefTitle = state.structure['preface'].title || 'Prefácio';
            const prefText = state.structure['preface'].text || '';
            const paragraphsHtml = prefText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="chapter-page preface-page">
                    <div class="chapter-header">
                        <span class="chapter-title preface-title">${prefTitle}</span>
                    </div>
                    <div class="chapter-body">
                        ${paragraphsHtml}
                    </div>
                </div>
            `;
        }

        // 7. Capítulos
        state.chapters.forEach((ch) => {
            wordHtml += addPageBreak();
            
            let titleHeaderHtml = `<div class="chapter-header"><span class="chapter-title">${ch.title}</span></div>`;
            const match = ch.title.match(/^(cap\u00edtulo|capitulo)\s+([a-zA-Z0-9\u2160-\u217F]+)(?:\s*[-–—:]\s*|\s+)(.*)$/i);
            if (match) {
                const capWordAndNum = `${match[1]} ${match[2]}`;
                const remainingTitle = match[3].trim();
                titleHeaderHtml = `
                    <div class="chapter-header">
                        <span class="chapter-number">${capWordAndNum}</span>
                        <span class="chapter-title">${remainingTitle}</span>
                    </div>
                `;
            }

            // Injeta a classe first-paragraph no primeiro parágrafo do capítulo
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = ch.content;
            
            // Marca parágrafos vazios com classe empty-paragraph para não sumirem no Word
            tempDiv.querySelectorAll('p').forEach(p => {
                const text = p.textContent.trim();
                if (!text || text === '\u00a0' || text === '&nbsp;') {
                    p.classList.add('empty-paragraph');
                    p.innerHTML = '&nbsp;'; // Garante caractere de espaço rígido
                }
            });
            
            const firstP = tempDiv.querySelector('p');
            if (firstP && !firstP.classList.contains('empty-paragraph')) {
                firstP.classList.add('first-paragraph');
            }
            const cleanContent = tempDiv.innerHTML;

            // Ornamento textual entre o título e o corpo se configurado
            let ornamentHtml = '';
            if (state.sceneOrnament && state.sceneOrnament !== 'none') {
                const symbolText = getWordOrnamentText(state.sceneOrnament);
                if (symbolText) {
                    ornamentHtml = `<p class="chapter-ornament" style="text-align: center !important; text-indent: 0cm !important; margin-top: 0.5cm !important; margin-bottom: 0.8cm !important; font-size: 14pt; color: ${state.decorationsColor || '#000000'};">${symbolText}</p>`;
                }
            }

            wordHtml += `
                <div class="chapter-page">
                    ${titleHeaderHtml}
                    ${ornamentHtml}
                    <div class="chapter-body">
                        ${cleanContent}
                    </div>
                </div>
            `;
        });

        // 8. Epílogo
        if (state.structure['epilogue'] && state.structure['epilogue'].active) {
            wordHtml += addPageBreak();
            const epilogueTitle = state.structure['epilogue'].title || 'Epílogo';
            const epilogueText = state.structure['epilogue'].text || '';
            const paragraphsHtml = epilogueText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="chapter-page epilogue-page">
                    <div class="chapter-header">
                        <span class="chapter-title epilogue-title">${epilogueTitle}</span>
                    </div>
                    <div class="chapter-body">
                        ${paragraphsHtml}
                    </div>
                </div>
            `;
        }

        // 9. Agradecimentos (Moved to end to match book preview!)
        if (state.structure['acknowledgements'] && state.structure['acknowledgements'].active) {
            wordHtml += addPageBreak();
            const ackTitle = state.structure['acknowledgements'].title || 'Agradecimentos';
            const ackText = state.structure['acknowledgements'].text || '';
            const paragraphsHtml = ackText.split('\n').map(p => `<p>${p.trim()}</p>`).join('\n');
            wordHtml += `
                <div class="chapter-page ack-page">
                    <div class="chapter-header">
                        <span class="chapter-title ack-title">${ackTitle}</span>
                    </div>
                    <div class="chapter-body">
                        ${paragraphsHtml}
                    </div>
                </div>
            `;
        }

        wordHtml += `
                </div>
            </body>
            </html>
        `;

        // Montar string MHTML Multipart para embutir imagem
        let mhtmlContent = `MIME-Version: 1.0
Content-Type: multipart/related; boundary="${boundary}"; type="text/html"

--${boundary}
Content-Type: text/html; charset="utf-8"
Content-Location: file:///C:/book.html

\ufeff${wordHtml}
`;

        if (hasPhoto && base64Image) {
            mhtmlContent += `
--${boundary}
Content-Type: ${mimeType}
Content-Transfer-Encoding: base64
Content-Location: file:///C:/author_photo.${photoExtension}

${wrapBase64(base64Image)}
`;
        }

        mhtmlContent += `\n--${boundary}--`;

        // Downloads em formato MHTML mas com extensão .doc para o Word abrir
        const blob = new Blob([mhtmlContent], { type: 'application/msword;charset=utf-8' });
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = `${nomeArquivo}.doc`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }

    // Abre a tela de impressão nativa configurada exatamente para PDF em uma nova janela para evitar fechar o app
    function exportBookPDF() {
        if (state.chapters.length === 0) {
            alert("Por favor, suba seu livro primeiro antes de exportar!");
            return;
        }

        // Verifica licença
        const hashLivroAtual = localStorage.getItem('bookforge_hash_livro_atual') || obterHashLivroAtual();
        const licencaRaw = localStorage.getItem('bookforge_licenca_ativa');
        let licenca = null;
        try {
            licenca = JSON.parse(licencaRaw);
        } catch(e) {
            licenca = null;
        }

        if (!licenca || (licenca.hashLivro !== hashLivroAtual && licenca.hashLivro !== 'master') || licenca.pdf) {
            if (typeof mostrarModalLicenca === 'function') {
                mostrarModalLicenca('PDF');
            } else {
                alert('⚠️ Licença inválida ou já consumida para este formato.');
            }
            return;
        }

        // Consome a licença
        licenca.pdf = true;
        localStorage.setItem('bookforge_licenca_ativa', JSON.stringify(licenca));
        const nomeArquivo = `${state.bookTitle || 'Livro'} - ${state.bookAuthor || 'Autor'}`.replace(/[\\/:*?"<>|]/g, '-');

        // Copiar todos os links de estilos e tags style do head principal
        const headHtml = Array.from(document.querySelectorAll('link, style'))
            .map(el => el.outerHTML)
            .join('\n');

        const pagesContainerHtml = document.getElementById('pages-container').innerHTML;

        // Cria um overlay visual de carregamento rápido
        const statusMsg = document.createElement('div');
        statusMsg.id = 'print-status-overlay';
        statusMsg.style = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);color:white;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:99999;font-family:sans-serif;';
        statusMsg.innerHTML = `
            <div style="background:#1a1714;padding:35px;border-radius:12px;border:2px solid #c8a55a;text-align:center;max-width:400px;box-shadow:0 10px 30px rgba(0,0,0,0.5);">
                <div style="font-size:2.5rem;margin-bottom:15px;animation:spin 2s linear infinite;">⚙️</div>
                <h3 style="margin:0 0 10px 0;color:#c8a55a;font-family:serif;font-size:1.3rem;">Preparando visualização...</h3>
                <p style="margin:0;font-size:0.9rem;color:#ccc;line-height:1.4;">Transferindo páginas do livro para o navegador de impressão. Por favor, aguarde.</p>
            </div>
            <style>
                @keyframes spin {
                    0% { transform: rotate(0deg); }
                    100% { transform: rotate(360deg); }
                }
            </style>
        `;
        document.body.appendChild(statusMsg);

        // Salva o print job no servidor local
        fetch('/api/save-print-job', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                html: pagesContainerHtml,
                head: headHtml,
                filename: nomeArquivo
            })
        })
        .then(res => res.json())
        .then(resData => {
            document.getElementById('print-status-overlay')?.remove();
            if (resData.status === 'ok') {
                // Mostra as instruções antes de abrir a janela
                alert('📄 Para salvar o seu livro em PDF:\n\n1. Na tela que vai abrir, selecione a impressora "Salvar como PDF"\n2. Em "Margens", mude para "Nenhuma" (IMPORTANTE!)\n3. Salve o arquivo em seu computador.');
                
                // Abre a janela de impressão com o ID do job
                window.open('print.html?id=' + resData.id, '_blank', 'noopener');
            } else {
                alert('❌ Erro ao preparar exportação: ' + (resData.error || 'Erro desconhecido.'));
            }
        })
        .catch(err => {
            document.getElementById('print-status-overlay')?.remove();
            console.error(err);
            alert('❌ Falha na conexão com o servidor local ao preparar a exportação.');
        });
    }

    // Formata o título do capítulo dividindo o número do capítulo do seu subtítulo
    function getChapterTitleHtml(fullTitle) {
        const numFont = (state.fontChapterNumber || 'Cinzel').toLowerCase().replace(/\s+/g, '');
        const titleFont = (state.fontChapterTitle || 'EB Garamond').toLowerCase().replace(/\s+/g, '');
        
        // Verifica se inicia com "Capítulo X" (incluindo números romanos e normais) seguido de separador ou texto
        const match = fullTitle.match(/^(cap\u00edtulo|capitulo)\s+([a-zA-Z0-9\u2160-\u217F]+)(?:\s*[-–—:]\s*|\s+)(.*)$/i);
        
        if (match) {
            const capWordAndNum = `${match[1]} ${match[2]}`; // ex: "Capítulo I"
            const remainingTitle = match[3].trim(); // ex: "O Recomeço"
            
            if (remainingTitle) {
                return `
                    <span class="chapter-number font-${numFont}">${capWordAndNum}</span>
                    <span class="chapter-title-sep"></span>
                    <span class="chapter-title-text font-${titleFont}">${remainingTitle}</span>
                `;
            }
        }
        
        // Se for apenas "Capítulo X" sem subtítulo
        const singleCapMatch = fullTitle.match(/^(cap\u00edtulo|capitulo)\s+([a-zA-Z0-9\u2160-\u217F]+)$/i);
        if (singleCapMatch) {
            return `<span class="chapter-number font-${numFont}">${fullTitle}</span>`;
        }

        // Se for apenas um título comum (ex: "Introdução")
        return `<span class="chapter-title-text font-${titleFont}">${fullTitle}</span>`;
    }

    // Tradutor de nomes de ornamentos para os SVGs originais
    function getOrnamentSymbol(name) {
        const premiumOrnaments = ['montanhas', 'caravela', 'espada', 'pergaminho', 'revolver', 'cabana', 'arco', 'caneta', 'pena', 'livro', 'aguia', 'voo', 'aguia2', 'pergaminho2', 'pergaminho3', 'livro_fechado', 'princesa', 'livro_aberto'];
        if (premiumOrnaments.includes(name)) {
            const color = state.decorationsColor || '#000000';
            if (['livro_fechado', 'princesa', 'livro_aberto'].includes(name)) {
                const maxH = name === 'princesa' ? '230px' : '220px';
                return `
                    <div class="premium-ornament-container" style="text-align: center; margin: 15px auto 25px auto;">
                        <!-- Desenho com Cores Originais -->
                        <img src="assets/ornaments/${name}.png" style="max-height: ${maxH}; max-width: 100%; width: auto; display: block; margin: 0 auto;">
                        
                        <!-- Divisor Inferior -->
                        <div style="display: flex; align-items: center; width: 100%; color: ${color}; margin-top: 15px;">
                            <div style="flex: 1; height: 1px; background-color: currentColor; opacity: 0.22;"></div>
                            <div style="margin: 0 10px; font-size: 14px; opacity: 0.65; transform: translateY(-1px);">❖</div>
                            <div style="flex: 1; height: 1px; background-color: currentColor; opacity: 0.22;"></div>
                        </div>
                    </div>
                `;
            }
            return `
                <div class="premium-ornament-container">
                    <!-- Desenho Croppado -->
                    <div class="premium-ornament-mask" style="-webkit-mask-image: url('assets/ornaments/${name}.png'); mask-image: url('assets/ornaments/${name}.png'); background-color: ${color} !important;"></div>
                    
                    <!-- Divisor Inferior -->
                    <div style="display: flex; align-items: center; width: 100%; color: ${color};">
                        <div style="flex: 1; height: 1px; background-color: currentColor; opacity: 0.22;"></div>
                        <div style="margin: 0 10px; font-size: 14px; opacity: 0.65; transform: translateY(-1px);">❖</div>
                        <div style="flex: 1; height: 1px; background-color: currentColor; opacity: 0.22;"></div>
                    </div>
                </div>
            `;
        }

        switch (name) {
            case 'fleur':
            case 'raminho':
                return `<svg viewBox="0 0 100 20"><path d="M10 10 Q30 10 50 10 T90 10 M30 10 L25 5 M35 10 L30 5 M50 10 L45 5 M55 10 L50 5" fill="none" stroke="currentColor" stroke-width="0.8"/></svg>`;
            case 'oliveira': 
                return `<svg viewBox="0 0 100 20"><path d="M20 15 Q50 5 80 15" fill="none" stroke="currentColor" stroke-width="0.8"/><path d="M30 12 L25 8 M40 9 L35 5 M50 8 L50 3" stroke="currentColor" fill="none" stroke-width="0.8"/></svg>`;
            case 'arabesco': 
                return `<svg viewBox="0 0 100 20"><path d="M10 10 C30 0 40 20 50 10 C60 0 70 20 90 10" fill="none" stroke="currentColor" stroke-width="1"/></svg>`;
            case 'pena': 
                return `<svg viewBox="0 0 100 20"><path d="M30 15 L70 5 M50 10 L45 12 M55 8 L50 10" stroke="currentColor" fill="none" stroke-width="1"/></svg>`;
            case 'videira': 
                return `<svg viewBox="0 0 100 20"><path d="M20 10 Q50 20 80 10" fill="none" stroke="currentColor" stroke-width="1"/><circle cx="50" cy="12" r="2" fill="currentColor"/></svg>`;
            case 'crown': 
            case 'coroa':
                return `<svg viewBox="0 0 100 20"><path d="M40 15 L35 5 L45 10 L50 5 L55 10 L65 5 L60 15 Z" fill="currentColor"/></svg>`;
            case 'diamante': 
                return `<svg viewBox="0 0 100 20"><path d="M10 10 L45 10 M55 10 L90 10 M50 5 L55 10 L50 15 L45 10 Z" fill="currentColor"/></svg>`;
            case 'divisor': 
                return `<svg viewBox="0 0 100 20"><path d="M5 10 L40 10 M60 10 L95 10 M45 10 L50 5 L55 10 L50 15 Z" fill="none" stroke="currentColor" stroke-width="0.5"/></svg>`;
            case 'lis': 
                return `<svg viewBox="0 0 100 20"><path d="M50 2 C48 7, 43 10, 45 15 C47 15, 53 15, 55 15 C57 10, 52 7, 50 2 Z M42 8 C38 9, 32 11, 34 15 C38 17, 44 13, 46 10 Z M58 8 C62 9, 68 11, 66 15 C62 17, 56 13, 54 10 Z M38 15 L62 15 C58 17, 42 17, 38 15 Z" fill="currentColor"/></svg>`;
            case 'estrela': 
                return `<svg viewBox="0 0 100 20"><path d="M10 10 L42 10 M58 10 L90 10 M50 2 L50 18 M46 10 L50 7 L54 10 L50 13 Z" fill="none" stroke="currentColor" stroke-width="0.8"/><polygon points="50,4 52,9 57,9 53,12 55,17 50,14 45,17 47,12 43,9 48,9" fill="currentColor"/></svg>`;
            case 'infinito': 
                return `<svg viewBox="0 0 100 20"><path d="M50 10 C38 3, 32 17, 50 10 C68 3, 62 17, 50 10 Z M10 10 L30 10 M70 10 L90 10" fill="none" stroke="currentColor" stroke-width="0.8"/></svg>`;
            case 'espiral': 
                return `<svg viewBox="0 0 100 20"><path d="M10 10 L30 10 M70 10 L90 10 M30 10 C32 6, 38 6, 38 10 C38 14, 34 14, 34 10 C34 8, 36 8, 36 10 M70 10 C68 6, 62 6, 62 10 C62 14, 66 14, 66 10 C66 8, 64 8, 64 10" fill="none" stroke="currentColor" stroke-width="0.8"/></svg>`;
            case 'montanhas':
                return `<svg viewBox="0 0 100 25"><circle cx="50" cy="12" r="6" fill="none" stroke="currentColor" stroke-width="0.5" stroke-dasharray="1 1"/><path d="M15 22 L32 10 L48 21 L62 8 L85 22" fill="none" stroke="currentColor" stroke-width="0.8" stroke-linejoin="round"/><path d="M30 13 L36 19 M58 11 L66 18" stroke="currentColor" stroke-width="0.5"/><path d="M22 22 L22 18 L20 19 L22 18 L24 19 M28 22 L28 17 L25 18 L28 17 L31 18 M72 22 L72 17 L69 18 L72 17 L75 18 M78 22 L78 19 L76 20 L78 19 L80 20" stroke="currentColor" stroke-width="0.5"/><path d="M10 22 L90 22" stroke="currentColor" stroke-width="0.6"/></svg>`;
            case 'castelo':
                return `<svg viewBox="0 0 100 25"><path d="M38 22 L38 12 L43 12 L43 22 M57 22 L57 12 L62 12 L62 22 M43 22 L43 10 L57 10 L57 22" fill="none" stroke="currentColor" stroke-width="0.8"/><polygon points="36,12 40.5,7 45,12" fill="currentColor"/><polygon points="55,12 59.5,7 64,12" fill="currentColor"/><path d="M45 10 L45 8 L47 8 L47 10 M49 10 L49 8 L51 8 L51 10 M53 10 L53 8 L55 8 L55 10" stroke="currentColor" stroke-width="0.8" fill="none"/><path d="M47 22 L47 16 C47 14, 53 14, 53 16 L53 22 Z" fill="currentColor"/><path d="M40.5 7 L40.5 4 L44 5.5 Z M59.5 7 L59.5 4 L63 5.5 Z" fill="currentColor"/><path d="M10 22 L90 22" stroke="currentColor" stroke-width="0.6"/><circle cx="20" cy="8" r="1.5" fill="currentColor"/><polygon points="78,5 79,7 81,7 79,8 80,10 78,9 76,10 77,8 75,7 77,7" fill="currentColor"/></svg>`;
            case 'caravela':
                return `<svg viewBox="0 0 100 25"><path d="M45 5 L45 20 M55 8 L55 20 M35 10 L35 20" stroke="currentColor" stroke-width="0.8"/><path d="M45 5 Q50 10 45 15 Q40 10 45 5 Z M55 8 Q58 12 55 16 Q52 12 55 8 Z M35 10 Q38 14 35 17 Q32 14 35 10 Z" fill="currentColor"/><path d="M45 5 L49 3.5 L45 2 Z" fill="currentColor"/><path d="M25 18 Q50 24 75 18 L70 21 L30 21 Z" fill="currentColor"/><path d="M10 22 Q20 20 30 22 T50 22 T70 22 T90 22" fill="none" stroke="currentColor" stroke-width="0.8"/><path d="M15 24 Q25 23 35 24 T55 24 T75 24 T85 24" fill="none" stroke="currentColor" stroke-width="0.5"/></svg>`;
            case 'espada':
                return `<svg viewBox="0 0 100 25"><path d="M49 2 L51 2 L52 15 L48 15 Z" fill="currentColor"/><path d="M40 15 Q50 13 60 15 L60 17 Q50 15 40 17 Z" fill="currentColor"/><path d="M49 17 L51 17 L51 21 L49 21 Z" fill="currentColor"/><circle cx="50" cy="22" r="1.2" fill="currentColor"/><path d="M34 13 L39 15 L34 17 Z M66 13 L61 15 L66 17 Z" fill="currentColor"/><path d="M10 22 L90 22" stroke="currentColor" stroke-width="0.5"/></svg>`;
            case 'pergaminho':
                return `<svg viewBox="0 0 100 25"><path d="M52 11 C48 7, 40 4, 32 2 C35 8, 42 13, 46 15 L55 18 Z" fill="none" stroke="currentColor" stroke-width="0.8"/><path d="M46 15 L55 18" stroke="currentColor" stroke-width="1.2"/><path d="M35 19 C32 19, 30 17, 30 15 C30 13, 32 11, 35 11 L65 11 C68 11, 70 13, 70 15 C70 17, 68 19, 65 19 Z" fill="none" stroke="currentColor" stroke-width="0.8"/><path d="M33 15 C33 16, 34 17, 35 17 C36 17, 37 16, 37 15 C37 14, 36 13, 35 13 C34 13, 33 14, 33 15 Z" fill="none" stroke="currentColor" stroke-width="0.5"/><path d="M63 15 C63 16, 64 17, 65 17 C66 17, 67 16, 67 15 C67 14, 66 13, 65 13 C64 13, 63 14, 63 15 Z" fill="none" stroke="currentColor" stroke-width="0.5"/><path d="M35 19 L35 22 L65 22 L65 19" fill="none" stroke="currentColor" stroke-width="0.8"/></svg>`;
            case 'balao':
                return `<svg viewBox="0 0 100 25"><path d="M18 20 C16 20, 14 18, 15 16 C16 14, 20 14, 22 16 C24 14, 28 14, 29 16 C30 18, 28 20, 26 20 Z" fill="currentColor" opacity="0.6"/><path d="M82 20 C80 20, 78 18, 79 16 C80 14, 84 14, 86 16 C88 14, 92 14, 93 16 C94 18, 92 20, 90 20 Z" fill="currentColor" opacity="0.6"/><path d="M50 3 C43 3, 38 8, 38 14 C38 18, 44 21, 47 21 L53 21 C56 21, 62 18, 62 14 C62 8, 57 3, 50 3 Z" fill="none" stroke="currentColor" stroke-width="0.8"/><path d="M50 3 C47 7, 47 16, 50 21 M50 3 C53 7, 53 16, 50 21" fill="none" stroke="currentColor" stroke-width="0.5"/><rect x="48.5" y="23" width="3" height="2" fill="currentColor"/><line x1="47.5" y1="21" x2="48.5" y2="23" stroke="currentColor" stroke-width="0.5"/><line x1="52.5" y1="21" x2="51.5" y2="23" stroke="currentColor" stroke-width="0.5"/></svg>`;
            case 'varinha':
                return `<svg viewBox="0 0 100 25"><line x1="30" y1="21" x2="65" y2="7" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/><circle cx="65" cy="7" r="1.2" fill="currentColor"/><path d="M70 3 L71.5 6 L75 6 L72 8 L73 11.5 L70 9.5 L67 11.5 L68 8 L65 6 L68.5 6 Z" fill="currentColor"/><polygon points="58,3 59,5 61,5 59,6 60,8 58,7 56,8 57,6 55,5 57,5" fill="currentColor"/><polygon points="76,11 77,12 79,12 77,13 78,15 76,14 74,15 75,13 73,12 75,12" fill="currentColor"/></svg>`;
            case 'rosas':
                return `<svg viewBox="0 0 100 20"><path d="M50 10 C47 7, 43 7, 41 10 C43 13, 47 13, 50 10 Z" fill="currentColor"/><path d="M50 10 C53 7, 57 7, 59 10 C57 13, 53 13, 50 10 Z" fill="currentColor"/><path d="M50 10 C48 5, 52 5, 50 10" stroke="currentColor" stroke-width="0.8" fill="none"/><path d="M15 10 Q30 7 40 10 M85 10 Q70 7 60 10" fill="none" stroke="currentColor" stroke-width="0.6"/><path d="M25 9 Q23 6 20 8 Q23 10 25 9" fill="currentColor"/><path d="M33 10 Q35 13 38 11 Q35 8 33 10" fill="currentColor"/><path d="M75 9 Q77 6 80 8 Q77 10 75 9" fill="currentColor"/><path d="M67 10 Q65 13 62 11 Q65 8 67 10" fill="currentColor"/></svg>`;
            default:
                return '';
        }
    }

    function getMolduraHtml(style) {
        let pathData = '';
        let viewBox = "0 0 100 100";
        if (style === 'vitoriana') {
            pathData = `
                <path d="M 10 10 L 80 10 M 10 10 L 10 80" fill="none" stroke="currentColor" stroke-width="1.5"/>
                <path d="M 5 5 L 90 5 M 5 5 L 5 90" fill="none" stroke="currentColor" stroke-width="0.5"/>
                <path d="M 10 10 C 25 15, 30 30, 20 40 C 15 45, 12 35, 10 25 C 8 35, 5 45, 0 40" fill="none" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
                <path d="M 10 10 C 15 25, 30 30, 40 20 C 45 15, 35 12, 25 10 C 35 8, 45 5, 40 0" fill="none" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
                <circle cx="20" cy="20" r="2.5" fill="currentColor"/>
            `;
        } else if (style === 'artdeco') {
            pathData = `
                <path d="M 5 5 L 95 5 M 5 5 L 5 95" fill="none" stroke="currentColor" stroke-width="1.5"/>
                <path d="M 12 12 L 80 12 M 12 12 L 12 80" fill="none" stroke="currentColor" stroke-width="0.8"/>
                <polygon points="12,12 25,12 25,25 12,25" fill="none" stroke="currentColor" stroke-width="1"/>
                <polygon points="5,5 12,12 18,12 12,18 12,12" fill="currentColor"/>
                <path d="M 15 15 L 45 15 M 15 15 L 15 45" fill="none" stroke="currentColor" stroke-width="2"/>
                <polygon points="30,30 35,25 40,30 35,35" fill="currentColor"/>
            `;
        } else if (style === 'floral') {
            pathData = `
                <path d="M 5 5 L 90 5 M 5 5 L 5 90" fill="none" stroke="currentColor" stroke-width="0.8"/>
                <path d="M 5 5 Q 40 10 80 15 M 5 5 Q 10 40 15 80" fill="none" stroke="currentColor" stroke-width="1.2"/>
                <path d="M 25 7 Q 30 2 35 8 Q 28 10 25 7 Z" fill="currentColor"/>
                <path d="M 50 11 Q 57 7 62 13 Q 55 15 50 11 Z" fill="currentColor"/>
                <path d="M 7 25 Q 2 30 8 35 Q 10 28 7 25 Z" fill="currentColor"/>
                <path d="M 11 50 Q 7 57 13 62 Q 15 55 11 50 Z" fill="currentColor"/>
                <circle cx="12" cy="12" r="3" fill="currentColor"/>
                <circle cx="8" cy="8" r="1.5" fill="currentColor"/>
                <circle cx="16" cy="8" r="1.5" fill="currentColor"/>
                <circle cx="8" cy="16" r="1.5" fill="currentColor"/>
                <circle cx="16" cy="16" r="1.5" fill="currentColor"/>
            `;
        } else if (style === 'minimalista') {
            pathData = `
                <path d="M 5 5 L 95 5 M 5 5 L 5 95" fill="none" stroke="currentColor" stroke-width="1"/>
                <path d="M 10 10 L 85 10 M 10 10 L 10 85" fill="none" stroke="currentColor" stroke-width="0.5"/>
            `;
        } else if (style === 'botanica') {
            viewBox = "0 0 100 120";
            pathData = `
                <path d="M 10 110 C 10 40, 40 10, 110 10" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
                <path d="M 10 80 C 12 45, 45 12, 80 10" fill="none" stroke="currentColor" stroke-width="0.8" stroke-linecap="round"/>
                <path d="M 10 50 Q 2 40, 8 35 Q 15 40, 10 50 Z" fill="currentColor"/>
                <path d="M 12 32 Q 4 22, 10 17 Q 17 22, 12 32 Z" fill="currentColor"/>
                <path d="M 50 10 Q 40 2, 35 8 Q 40 15, 50 10 Z" fill="currentColor"/>
                <path d="M 32 12 Q 22 4, 17 10 Q 22 17, 32 12 Z" fill="currentColor"/>
                <path d="M 70 10 Q 80 2, 87 8 Q 80 15, 70 10 Z" fill="currentColor"/>
                <path d="M 10 70 Q 2 80, 8 87 Q 15 80, 10 70 Z" fill="currentColor"/>
                <circle cx="24" cy="24" r="2.5" fill="currentColor"/>
                <circle cx="18" cy="18" r="1.8" fill="currentColor"/>
                <circle cx="30" cy="30" r="1.8" fill="currentColor"/>
                <circle cx="38" cy="8" r="1.5" fill="currentColor"/>
                <circle cx="8" cy="38" r="1.5" fill="currentColor"/>
                <path d="M 24 24 L 18 18 M 24 24 L 30 30" stroke="currentColor" stroke-width="0.5"/>
            `;
        } else if (style === 'barroco') {
            viewBox = "0 0 100 100";
            pathData = `
                <path d="M 5 5 C 22 5, 42 17, 47 32 C 52 47, 37 62, 22 52 C 12 44, 14 27, 27 22 C 37 18, 47 27, 42 40" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
                <path d="M 5 5 C 5 22, 17 42, 32 47 C 47 52, 62 37, 52 22 C 44 12, 27 14, 22 27 C 18 37, 27 47, 40 42" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
                <path d="M 12 12 C 27 14, 37 27, 30 37 C 24 44, 17 37, 20 27 C 22 20, 14 17, 12 12" fill="currentColor"/>
                <path d="M 12 12 C 14 27, 27 37, 37 30 C 44 24, 37 17, 27 20 C 20 22, 17 14, 12 12" fill="currentColor"/>
                <path d="M 5 5 C 17 10, 24 7, 27 3 C 24 1, 17 3, 5 5" fill="currentColor"/>
                <path d="M 5 5 C 10 17, 7 24, 3 27 C 1 24, 3 17, 5 5" fill="currentColor"/>
                <circle cx="30" cy="30" r="2" fill="currentColor"/>
                <circle cx="38" cy="38" r="1.5" fill="currentColor"/>
            `;
        } else if (style === 'rosas') {
            viewBox = "0 0 100 100";
            pathData = ``;
        } else {
            return '';
        }
        
        return `
            <svg viewBox="${viewBox}" class="corner top-left">${pathData}</svg>
            <svg viewBox="${viewBox}" class="corner top-right">${pathData}</svg>
            <svg viewBox="${viewBox}" class="corner bottom-left">${pathData}</svg>
            <svg viewBox="${viewBox}" class="corner bottom-right">${pathData}</svg>
        `;
    }

    // Cria e insere no DOM um elemento representando uma página física de livro (.page-sheet)
    function createPageElement(pageNum, contentHtml, isChapterStart = false, chapterTitle = '', headerText = '', layoutClass = '', customFont = '') {
        const pageSheet = document.createElement('div');
        pageSheet.className = `page-sheet format-${state.bookFormat} paper-${state.paperColor} ${layoutClass}`;
        
        const molduraStyle = state.pageMoldura || 'none';
        if (molduraStyle !== 'none' && isChapterStart) {
            const borderEl = document.createElement('div');
            borderEl.className = `page-border-frame style-${molduraStyle}`;
            borderEl.innerHTML = getMolduraHtml(molduraStyle);
            pageSheet.appendChild(borderEl);
        }

        if (state.hasDropCap && isChapterStart) {
            pageSheet.classList.add('has-dropcap');
        }

        
        // Cabeçalho da página (nome do livro ou capítulo alternadamente)
        const headerEl = document.createElement('div');
        headerEl.className = 'page-header';
        if (!isChapterStart && headerText && !layoutClass) {
            headerEl.textContent = headerText;
        } else {
            headerEl.innerHTML = '&nbsp;';
        }
        
        // Corpo do texto com a tipografia escolhida pelo usuário
        const fontName = customFont ? customFont : state.globalFont;
        const bodyEl = document.createElement('div');
        bodyEl.className = `page-body font-${fontName.toLowerCase().replace(/\s+/g, '')}`;
        
        if (isChapterStart) {
            const titleEl = document.createElement('h2');
            titleEl.className = 'page-chapter-title';
            titleEl.innerHTML = getChapterTitleHtml(chapterTitle);
            bodyEl.appendChild(titleEl);
            
            if (state.sceneOrnament !== 'none') {
                const ornamentEl = document.createElement('div');
                ornamentEl.className = 'page-ornament';
                ornamentEl.innerHTML = getOrnamentSymbol(state.sceneOrnament);
                bodyEl.appendChild(ornamentEl);
            }
        }
        
        const contentWrap = document.createElement('div');
        contentWrap.innerHTML = contentHtml;
        bodyEl.appendChild(contentWrap);
        
        // Rodapé (Número da Página)
        const footerEl = document.createElement('div');
        footerEl.className = 'page-footer';
        if (layoutClass !== 'titlepage-layout') {
            footerEl.textContent = pageNum;
        } else {
            footerEl.innerHTML = '&nbsp;';
        }
        
        pageSheet.appendChild(headerEl);
        pageSheet.appendChild(bodyEl);
        pageSheet.appendChild(footerEl);
        
        return pageSheet;
    }

    // Proofreader / Corrector Ortográfico e de Pontuação local para o texto do miolo
    const ignoredErrors = new Set();

    function getProofreadErrors(text, chapterId) {
        try {
            const errors = [];
            const flaggedRanges = [];
            
            function addError(err) {
                const start = err.index;
                const end = err.index + err.length;
                const overlaps = flaggedRanges.some(r => start < r.end && end > r.start);
                if (!overlaps) {
                    errors.push(err);
                    flaggedRanges.push({ start, end });
                }
            }
            
            // 1. Dicionário de erros comuns em Português
            const commonMisspellings = [
                { regex: /\bconcerteza\b/gi, suggestion: "com certeza", type: "Ortografia" },
                { regex: /\bderrepente\b/gi, suggestion: "de repente", type: "Ortografia" },
                { regex: /\bporisso\b/gi, suggestion: "por isso", type: "Ortografia" },
                { regex: /\bmenas\b/gi, suggestion: "menos", type: "Ortografia" },
                { regex: /\bnada\s+haver\b/gi, suggestion: "nada a ver", type: "Ortografia" },
                { regex: /\bhá\s+muito\s+tempo\s+atrás\b/gi, suggestion: "há muito tempo", type: "Redundância" },
                { regex: /\bpara\s+mim\s+fazer\b/gi, suggestion: "para eu fazer", type: "Gramática" },
                { regex: /\bpara\s+mim\s+escrever\b/gi, suggestion: "para eu escrever", type: "Gramática" },
                { regex: /\bpara\s+mim\s+ler\b/gi, suggestion: "para eu ler", type: "Gramática" },
                { regex: /\ba\s+muito\s+tempo\b/gi, suggestion: "há muito tempo", type: "Gramática" },
                { regex: /\bfazem\s+(\d+)\s+anos\b/gi, suggestion: "faz $1 anos", type: "Gramática" },
                { regex: /\bhouveram\s+problemas\b/gi, suggestion: "houve problemas", type: "Gramática" },
                { regex: /\bhouveram\s+muitos\b/gi, suggestion: "houve muitos", type: "Gramática" }
            ];

            commonMisspellings.forEach(item => {
                let match;
                const tempRegex = new RegExp(item.regex);
                while ((match = tempRegex.exec(text)) !== null) {
                    const original = match[0];
                    const suggestion = original.replace(item.regex, item.suggestion);
                    const key = `${chapterId}_${original}`;
                    if (!ignoredErrors.has(key)) {
                        addError({
                            index: match.index,
                            length: original.length,
                            original: original,
                            suggestion: suggestion,
                            type: item.type
                        });
                    }
                }
            });

            // 2. Pontuação: mas sem vírgula antes (ex: " ... mas ... ")
            const masRegex = /\b([a-zA-ZáéíóúâêîôûãõçÁÉÍÓÚÂÊÎÔÛÃÕÇ0-9]+)\s+mas\b/gi;
            let masMatch;
            while ((masMatch = masRegex.exec(text)) !== null) {
                const wordBefore = masMatch[1].toLowerCase();
                const excludedWords = ["e", "ou", "não", "mas", "um", "uma", "o", "a", "os", "as"];
                if (!excludedWords.includes(wordBefore)) {
                    const original = masMatch[0];
                    const suggestion = original.replace(/\s+mas\b/i, ", mas");
                    const key = `${chapterId}_${original}`;
                    if (!ignoredErrors.has(key)) {
                        addError({
                            index: masMatch.index,
                            length: original.length,
                            original: original,
                            suggestion: suggestion,
                            type: "Pontuação (Adversativa)"
                        });
                    }
                }
            }

            // 3. Espaços duplos ou triplos: "   " -> " "
            const spaceRegex = / {2,}/g;
            let spaceMatch;
            while ((spaceMatch = spaceRegex.exec(text)) !== null) {
                const original = spaceMatch[0];
                const key = `${chapterId}_${original}`;
                if (!ignoredErrors.has(key)) {
                    addError({
                        index: spaceMatch.index,
                        length: original.length,
                        original: original,
                        suggestion: " ",
                        type: "Espaço Extra"
                    });
                }
            }

            // 4. Espaço antes de pontuação: "palavra ," -> "palavra,"
            const spaceBeforePunctRegex = /\s+([.,;:!?])/g;
            let punctMatch;
            while ((punctMatch = spaceBeforePunctRegex.exec(text)) !== null) {
                const original = punctMatch[0];
                const suggestion = punctMatch[1];
                const key = `${chapterId}_${original}`;
                if (!ignoredErrors.has(key)) {
                    addError({
                        index: punctMatch.index,
                        length: original.length,
                        original: original,
                        suggestion: suggestion,
                        type: "Espaçamento Incorreto"
                    });
                }
            }

            // 5. Falta de espaço após pontuação: "palavra,outra" -> "palavra, outra"
            const missingSpaceRegex = /([.,;:!?])([a-zA-ZáéíóúâêîôûãõçÁÉÍÓÚÂÊÎÔÛÃÕÇ])/g;
            let missingMatch;
            while ((missingMatch = missingSpaceRegex.exec(text)) !== null) {
                const original = missingMatch[0];
                const suggestion = missingMatch[1] + " " + missingMatch[2];
                const key = `${chapterId}_${original}`;
                if (!ignoredErrors.has(key)) {
                    addError({
                        index: missingMatch.index,
                        length: original.length,
                        original: original,
                        suggestion: suggestion,
                        type: "Falta Espaço"
                    });
                }
            }

            // 6. Dicionário Hunspell completo (se carregado) para detectar palavras escritas errado arbitrárias
            if (typoInstance) {
                const wordRegex = /[a-zA-ZáéíóúâêîôûãõçÁÉÍÓÚÂÊÎÔÛÃÕÇ]+/g;
                let match;
                while ((match = wordRegex.exec(text)) !== null) {
                    const word = match[0];
                    const key = `${chapterId}_${word}`;
                    if (!ignoredErrors.has(key)) {
                        if (!isWordCorrect(word)) {
                            const suggestions = typoInstance.suggest(word);
                            const suggestion = suggestions[0] || "";
                            addError({
                                index: match.index,
                                length: word.length,
                                original: word,
                                suggestion: suggestion,
                                allSuggestions: suggestions,
                                type: "Ortografia"
                            });
                        }
                    }
                }
            }

            // Ordenar erros por index decrescente para substituição segura
            errors.sort((a, b) => b.index - a.index);
            return errors;
        } catch (e) {
            console.error("Erro em getProofreadErrors:", e);
            return [];
        }
    }

    function highlightErrorsInHtml(htmlContent, chapterId) {
        return htmlContent;
    }

    function showProofreadPopover(span) {
        // Remover popover anterior se existir
        const oldPopover = document.getElementById('proofread-popover');
        if (oldPopover) oldPopover.remove();
        
        const chapterId = span.getAttribute('data-chapter-id');
        const originalText = decodeURIComponent(span.getAttribute('data-original'));
        const suggestionText = decodeURIComponent(span.getAttribute('data-suggestion'));
        const errorType = span.getAttribute('data-error-type');
        
        const allSuggestionsAttr = span.getAttribute('data-all-suggestions');
        let allSuggestions = [];
        if (allSuggestionsAttr) {
            try {
                allSuggestions = JSON.parse(decodeURIComponent(allSuggestionsAttr));
            } catch(e) {}
        }
        
        // Criar o popover no body
        const popover = document.createElement('div');
        popover.id = 'proofread-popover';
        popover.className = 'proofread-popover';
        
        // Se for Ortografia, vamos mostrar a lista de alternativas e o input personalizado
        let bodyHtml = `
            <div class="proofread-popover-type">Tipo: <strong>${errorType}</strong></div>
            <div class="proofread-popover-diff">
                <span class="diff-original">${originalText}</span>
                <span class="diff-arrow">➔</span>
                <span class="diff-suggestion">${suggestionText === ' ' ? '<i>[espaço simples]</i>' : (suggestionText || '<i>[nenhuma]</i>')}</span>
            </div>
        `;
        
        if (errorType === 'Ortografia') {
            bodyHtml += `
                <div style="font-size: 11px; margin-top: 4px; color: #a0a0a5;">Outras sugestões:</div>
                <div class="proofread-suggestions-list" style="margin-top: 4px; display: flex; flex-wrap: wrap; gap: 4px;">
                    ${allSuggestions.length > 0 
                        ? allSuggestions.map(sug => `<button class="btn-sug-pill" data-val="${sug}">${sug}</button>`).join('')
                        : '<span style="font-size: 11px; color: #777; font-style: italic;">Nenhuma alternativa</span>'
                    }
                </div>
                <div style="margin-top: 8px; display: flex; flex-direction: column; gap: 4px;">
                    <label style="font-size: 11px; color: #a0a0a5;">Editar correção:</label>
                    <input type="text" class="custom-correction-input" value="${suggestionText}" placeholder="Digite a correção...">
                </div>
            `;
        }
        
        popover.innerHTML = `
            <div class="proofread-popover-header">
                <span>Sugestão de Correção</span>
                <button class="proofread-popover-close">✕</button>
            </div>
            <div class="proofread-popover-body">
                ${bodyHtml}
            </div>
            <div class="proofread-popover-footer">
                <button class="btn btn-primary btn-xs btn-accept">Corrigir</button>
                <button class="btn btn-secondary btn-xs btn-ignore">Ignorar</button>
            </div>
        `;
        
        document.body.appendChild(popover);
        
        // Posicionar popover acima do span
        const rect = span.getBoundingClientRect();
        
        // Ajustar com scroll da página. A altura do popover muda dependendo de ser ortográfico ou não,
        // então calculamos a altura dinamicamente para posicionar acima
        const popoverHeight = popover.offsetHeight || (errorType === 'Ortografia' ? 200 : 110);
        const top = rect.top + window.scrollY - popoverHeight - 10; 
        const left = rect.left + window.scrollX + (rect.width / 2) - 140; // 140 é a metade de 280 (largura do popover)
        
        popover.style.top = `${top}px`;
        popover.style.left = `${left}px`;
        
        // Event listeners
        popover.querySelector('.proofread-popover-close').addEventListener('click', () => popover.remove());
        
        const inputCorrection = popover.querySelector('.custom-correction-input');
        
        function applyCorrection(val) {
            // Substituir o span no DOM
            const parent = span.parentNode;
            const textNode = document.createTextNode(val);
            parent.replaceChild(textNode, span);
            
            // Salvar no estado
            const paraEl = parent.closest('.paragraph-editable');
            if (paraEl) {
                saveParagraph(paraEl);
            } else {
                // Fallback se não estiver dentro de um parágrafo editável
                const chapter = state.chapters.find(ch => ch.id === chapterId);
                if (chapter) {
                    chapter.content = chapter.content.replace(originalText, val);
                    updatePreviewPages();
                }
            }
            popover.remove();
            console.log(`Corrigido: "${originalText}" -> "${val}"`);
        }
        
        // Registrar cliques nos botões de sugestões
        popover.querySelectorAll('.btn-sug-pill').forEach(pill => {
            pill.addEventListener('click', () => {
                const val = pill.getAttribute('data-val');
                applyCorrection(val);
            });
        });
        
        // Botão Corrigir
        popover.querySelector('.btn-accept').addEventListener('click', () => {
            const val = inputCorrection ? inputCorrection.value : suggestionText;
            applyCorrection(val);
        });
        
        // Botão Ignorar
        popover.querySelector('.btn-ignore').addEventListener('click', () => {
            const key = `${chapterId}_${originalText}`;
            ignoredErrors.add(key);
            popover.remove();
            updatePreviewPages();
            console.log(`Ignorado: "${originalText}"`);
        });
    }

    // Renderiza e insere todas as folhas do livro (folhas especiais, sumário e capítulos) em sequência vertical
    function updatePreviewPages() {
        recordHistoryState();
        updateDynamicStyle();
        updatePrintStyle();
        const pagesContainer = document.getElementById('pages-container');
        const centerBranding = document.querySelector('.center-branding');
        const uploadCard = document.querySelector('.upload-card');
        const waitingBadge = document.querySelector('.waiting-badge');
        const workspaceCenter = document.querySelector('.workspace-center');
        
        if (state.chapters.length === 0 || !state.showWorkspacePreview) {
            if (workspaceCenter) workspaceCenter.classList.remove('has-book');
            if (pagesContainer) pagesContainer.style.display = 'none';
            if (centerBranding) centerBranding.style.display = 'block';
            if (uploadCard) uploadCard.style.display = 'flex';
            if (waitingBadge) {
                waitingBadge.textContent = 'AGUARDANDO';
                waitingBadge.style.color = 'var(--color-primary)';
                waitingBadge.style.borderColor = 'var(--color-primary)';
            }
            // Exibir o botão de continuar trabalho se houver progresso salvo
            if (localStorage.getItem('bookforge_saved_state') && btnContinueWork) {
                btnContinueWork.style.display = 'flex';
            }
            return;
        }
        
        if (btnContinueWork) {
            btnContinueWork.style.display = 'none';
        }
        if (workspaceCenter) workspaceCenter.classList.add('has-book');
        if (centerBranding) centerBranding.style.display = 'none';
        if (uploadCard) uploadCard.style.display = 'none';
        if (pagesContainer) {
            pagesContainer.style.display = 'flex';
            pagesContainer.innerHTML = '';
        }
        
        let currentPageNum = 1;
        
        function addPage(element) {
            pagesContainer.appendChild(element);
        }
        
        // 1. FOLHA DE ROSTO
        if (state.structure['title-page'].active) {
            const titlepageHtml = `
                <div class="titlepage-layout">
                    <div>&nbsp;</div>
                    <div>
                        <div class="titlepage-title font-${state.structure['title-page'].font.toLowerCase().replace(/\s+/g, '')}">${state.bookTitle || 'Sem Título'}</div>
                        <div class="titlepage-line"></div>
                        ${state.structure['title-page'].showAuthor ? `<div class="titlepage-author font-${state.structure['title-page'].fontAuthor.toLowerCase().replace(/\s+/g, '')}">${state.bookAuthor || 'Autor Anônimo'}</div>` : ''}
                    </div>
                    <div>&nbsp;</div>
                </div>
            `;
            const pageEl = createPageElement(
                currentPageNum++, 
                titlepageHtml, 
                false, 
                '', 
                '', 
                'titlepage-layout',
                state.structure['title-page'].font
            );
            pageEl.setAttribute('data-section-id', 'title-page');
            addPage(pageEl);
        }
        
        // 2. BIOGRAFIA
        if (state.structure['bio'].active) {
            const bioPhotoHtml = state.structure['bio'].photo 
                ? `<img class="bio-photo" src="${state.structure['bio'].photo}" alt="Autor">` 
                : `<div class="bio-photo-placeholder"><i data-lucide="user" style="width: 32px; height: 32px;"></i></div>`;
                
            const bioText = state.structure['bio'].text 
                ? state.structure['bio'].text 
                : 'Insira a biografia do autor nas configurações da barra lateral para exibi-la nesta página final.';
            
            const fontKey = state.structure['bio'].font.toLowerCase().replace(/\s+/g, '');
            const limits = fontCharLimits[fontKey] || { firstOrnament: 600, firstNoOrnament: 1100, normal: 1600 };
            const hasPhoto = !!state.structure['bio'].photo;
            const firstPageLimit = hasPhoto ? 800 : 1400;
            
            const bioPages = paginateTextareaText(bioText, true, state.structure['bio'].font, firstPageLimit);
            
            bioPages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['bio'].font;
                
                let contentHtml = '';
                if (isFirstPage) {
                    contentHtml = `
                        <div class="bio-layout">
                            <h2 class="font-${state.structure['bio'].fontTitle.toLowerCase().replace(/\s+/g, '')}">Sobre o Autor</h2>
                            <div class="titlepage-line" style="margin: 10px auto;"></div>
                            ${bioPhotoHtml}
                            ${pageHtml}
                        </div>
                    `;
                } else {
                    contentHtml = `
                        <div class="bio-layout">
                            ${pageHtml}
                        </div>
                    `;
                }
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    contentHtml, 
                    false, 
                    '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'bio');
                addPage(pageEl);
            });
            
            if (!state.structure['bio'].photo) {
                setTimeout(() => {
                    if (window.lucide) window.lucide.createIcons();
                }, 10);
            }
        }
        
        // 3. COPYRIGHT
        if (state.structure['copyright'].active) {
            const copyrightText = state.structure['copyright'].text 
                ? state.structure['copyright'].text 
                : `Todos os direitos reservados.\nCopyright © ${new Date().getFullYear()} ${state.bookAuthor || 'Autor'}`;
                
            const copyrightPages = paginateTextareaText(copyrightText, true, state.structure['copyright'].font, 2000);
            copyrightPages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['copyright'].font;
                const fontTitle = state.structure['copyright'].fontTitle;
                
                let contentHtml = '';
                if (isFirstPage) {
                    contentHtml = `
                        <div class="copyright-layout first-page">
                            <h2 class="page-chapter-title font-${fontTitle.toLowerCase().replace(/\s+/g, '')}" style="margin-top: 0; margin-bottom: 20px; text-align: center;">Copyright</h2>
                            <div class="copyright-text font-${customFont.toLowerCase().replace(/\s+/g, '')}" style="padding-top: 28px;">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                } else {
                    contentHtml = `
                        <div class="copyright-layout subsequent-page">
                            <div class="copyright-text font-${customFont.toLowerCase().replace(/\s+/g, '')}">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                }
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    contentHtml, 
                    false, 
                    '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'copyright');
                addPage(pageEl);
            });
        }
        
        // 4. DEDICATÓRIA
        if (state.structure['dedication'].active) {
            const dedicationText = state.structure['dedication'].text 
                ? state.structure['dedication'].text 
                : 'Dedico este livro a todos os leitores que acreditam no recomeço.';
                
            const dedicationPages = paginateTextareaText(dedicationText, true, state.structure['dedication'].font, 2000);
            dedicationPages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['dedication'].font;
                const fontTitle = state.structure['dedication'].fontTitle;
                
                let contentHtml = '';
                if (isFirstPage) {
                    contentHtml = `
                        <div class="dedication-layout first-page">
                            <h2 class="page-chapter-title font-${fontTitle.toLowerCase().replace(/\s+/g, '')}" style="margin-top: 0; margin-bottom: 20px; text-align: center;">Dedicatória</h2>
                            <div class="dedication-text font-${customFont.toLowerCase().replace(/\s+/g, '')}" style="padding-top: 28px;">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                } else {
                    contentHtml = `
                        <div class="dedication-layout subsequent-page">
                            <div class="dedication-text font-${customFont.toLowerCase().replace(/\s+/g, '')}">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                }
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    contentHtml, 
                    false, 
                    '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'dedication');
                addPage(pageEl);
            });
        }
        
        // 5. EPÍGRAFE
        if (state.structure['epigraph'].active) {
            const epigraphText = state.structure['epigraph'].text 
                ? state.structure['epigraph'].text 
                : '“O verdadeiro segredo do recomeço está em dar o primeiro passo.”';
                
            const epigraphPages = paginateTextareaText(epigraphText, true, state.structure['epigraph'].font, 2000);
            epigraphPages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['epigraph'].font;
                const fontTitle = state.structure['epigraph'].fontTitle;
                
                let contentHtml = '';
                if (isFirstPage) {
                    contentHtml = `
                        <div class="epigraph-layout first-page">
                            <h2 class="page-chapter-title font-${fontTitle.toLowerCase().replace(/\s+/g, '')}" style="margin-top: 0; margin-bottom: 20px; text-align: center;">Epígrafe</h2>
                            <div class="epigraph-text font-${customFont.toLowerCase().replace(/\s+/g, '')}" style="padding-top: 28px;">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                } else {
                    contentHtml = `
                        <div class="epigraph-layout subsequent-page">
                            <div class="epigraph-text font-${customFont.toLowerCase().replace(/\s+/g, '')}">
                                ${pageHtml}
                            </div>
                        </div>
                    `;
                }
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    contentHtml, 
                    false, 
                    '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'epigraph');
                addPage(pageEl);
            });
        }
        
        // 6. PREFÁCIO
        if (state.structure['preface'].active) {
            const prefaceTitle = state.structure['preface'].title || 'Prefácio';
            const prefaceText = state.structure['preface'].text 
                ? state.structure['preface'].text 
                : 'Esta é a página de prefácio do seu livro. Adicione o texto explicativo ou a introdução escrita por um convidado nas configurações.';
                
            const prefacePages = paginateTextareaText(prefaceText, true, state.structure['preface'].font, 1400);
            prefacePages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['preface'].font;
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    pageHtml, 
                    isFirstPage, 
                    isFirstPage ? prefaceTitle : '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'preface');
                addPage(pageEl);
            });
        }
        
        // Pré-calcular páginas dos capítulos para construir o Sumário dinâmico
        const chapterStartPages = {};
        let tempPageCounter = currentPageNum;
        
        let tocPagesCount = 0;
        const tocItemsPerPage = 15;
        if (state.structure['toc'].active && state.chapters.length > 0) {
            tocPagesCount = Math.ceil(state.chapters.length / tocItemsPerPage);
        }
        
        if (state.structure['toc'].active) {
            tempPageCounter += tocPagesCount; // Espaço reservado para o Sumário
        }
        if (state.structure['blank-page'].active) {
            tempPageCounter++; // Espaço reservado para a Página em Branco que fica após o Sumário
        }
        
        const paginatedChapters = state.chapters.map(chapter => {
            const chapterPages = paginateChapter(chapter);
            chapterStartPages[chapter.id] = tempPageCounter;
            tempPageCounter += chapterPages.length;
            return { chapter, pages: chapterPages };
        });
        
        // 7. SUMÁRIO (TOC)
        if (state.structure['toc'].active && state.chapters.length > 0) {
            for (let pageIdx = 0; pageIdx < tocPagesCount; pageIdx++) {
                const startIdx = pageIdx * tocItemsPerPage;
                const endIdx = Math.min(startIdx + tocItemsPerPage, state.chapters.length);
                const pageChapters = state.chapters.slice(startIdx, endIdx);
                
                let tocListHtml = '<div class="toc-list">';
                pageChapters.forEach(ch => {
                    const startPage = chapterStartPages[ch.id] || currentPageNum;
                    tocListHtml += `
                        <div class="toc-row">
                            <span>${ch.title.toUpperCase()}</span>
                            <span class="toc-leader"></span>
                            <span>${startPage}</span>
                        </div>
                    `;
                });
                tocListHtml += '</div>';
                
                const titleHtml = pageIdx === 0 
                    ? `<h2 class="font-${state.structure['toc'].fontTitle.toLowerCase().replace(/\s+/g, '')}">Sumário</h2>`
                    : `<h2 class="font-${state.structure['toc'].fontTitle.toLowerCase().replace(/\s+/g, '')}" style="visibility: hidden; height: 0; margin: 0; padding: 0;">Sumário</h2>`;
                
                const tocHtml = `
                    <div class="toc-layout">
                        ${titleHtml}
                        <div class="toc-list font-${state.structure['toc'].font.toLowerCase().replace(/\s+/g, '')}">
                            ${tocListHtml}
                        </div>
                    </div>
                `;
                const pageEl = createPageElement(
                    currentPageNum++, 
                    tocHtml, 
                    false, 
                    '', 
                    '', 
                    '',
                    state.structure['toc'].font
                );
                pageEl.setAttribute('data-section-id', 'toc');
                addPage(pageEl);
            }
        }
        
        // 8. PÁGINA EM BRANCO
        if (state.structure['blank-page'].active) {
            const pageEl = createPageElement(
                currentPageNum++, 
                '<div style="height: 100%;">&nbsp;</div>', 
                false, 
                '', 
                '', 
                ''
            );
            pageEl.setAttribute('data-section-id', 'blank-page');
            addPage(pageEl);
        }
        
        // 9. RENDERIZAR OS CAPÍTULOS DO LIVRO (Renderiza todas as páginas com o texto corrido do miolo)
        paginatedChapters.forEach(({ chapter, pages }) => {
            pages.forEach((pageInfo, index) => {
                const isChapterStart = index === 0;
                let contentHtml = pageInfo.paragraphs.join('');
                if (state.proofreadModeActive) {
                    contentHtml = highlightErrorsInHtml(contentHtml, chapter.id);
                }
                
                const isEven = currentPageNum % 2 === 0;
                const headerText = isEven ? (state.bookTitle || '') : chapter.title;
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    contentHtml, 
                    isChapterStart, 
                    chapter.title, 
                    headerText, 
                    ''
                );
                
                if (isChapterStart) {
                    pageEl.setAttribute('data-chapter-id', chapter.id);
                }
                
                addPage(pageEl);
            });
        });
        
        // 10. EPÍLOGO
        if (state.structure['epilogue'].active) {
            const epilogueTitle = state.structure['epilogue'].title || 'Epílogo';
            const epilogueText = state.structure['epilogue'].text 
                ? state.structure['epilogue'].text 
                : 'Esta é a página de epílogo do seu livro. Adicione o texto de fechamento do livro nas configurações.';
                
            const epiloguePages = paginateTextareaText(epilogueText, true, state.structure['epilogue'].font, 1400);
            epiloguePages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['epilogue'].font;
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    pageHtml, 
                    isFirstPage, 
                    isFirstPage ? epilogueTitle : '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'epilogue');
                addPage(pageEl);
            });
        }
        
        // 11. AGRADECIMENTOS
        if (state.structure['acknowledgements'].active) {
            const acknowledgementsTitle = state.structure['acknowledgements'].title || 'Agradecimentos';
            const acknowledgementsText = state.structure['acknowledgements'].text 
                ? state.structure['acknowledgements'].text 
                : 'Escreva seus agradecimentos nas configurações da barra lateral para exibi-los nesta página.';
                
            const acknowledgementsPages = paginateTextareaText(acknowledgementsText, true, state.structure['acknowledgements'].font, 1400);
            acknowledgementsPages.forEach((pageHtml, index) => {
                const isFirstPage = index === 0;
                const customFont = state.structure['acknowledgements'].font;
                
                const pageEl = createPageElement(
                    currentPageNum++, 
                    pageHtml, 
                    isFirstPage, 
                    isFirstPage ? acknowledgementsTitle : '', 
                    '', 
                    '',
                    customFont
                );
                pageEl.setAttribute('data-section-id', 'acknowledgements');
                addPage(pageEl);
            });
        }
        
        // Atualiza o crachá de contagem total de páginas no canto esquerdo
        const totalPages = currentPageNum - 1;
        if (waitingBadge) {
            waitingBadge.textContent = `${totalPages} PÁGS (OK)`;
            waitingBadge.style.color = '#ffc83b';
            waitingBadge.style.borderColor = '#ffc83b';
        }
        
        // Salva a quantidade de páginas para a capa poder importar
        localStorage.setItem('bookforge_paginas_diagramacao', totalPages);
        
        // Salva o progresso no localStorage automaticamente
        saveProgress();
    }

    init();
});
