// Configuração do Markdown parser personalizado com Highlight.js integrado
const renderer = new marked.Renderer();

// Função auxiliar para escapar caracteres HTML
function escapeHtml(text) {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

// Helper global para extração segura de erros de resposta HTTP no frontend
async function safeExtractError(resp, defaultMsg = 'Erro na operação') {
  if (!resp) return defaultMsg;
  try {
    const text = await resp.text();
    try {
      const json = JSON.parse(text);
      return json.error || defaultMsg;
    } catch (e) {
      if (resp.status === 502 || text.includes('Bad Gateway')) {
        return 'O servidor está temporariamente ocupado processando a requisição. Por favor, tente novamente em instantes.';
      }
      return text.slice(0, 160) || defaultMsg;
    }
  } catch (e) {
    return defaultMsg;
  }
}


// Função global para exibir notificações elegantes estilo Toast
function showToast(message, type = 'info') {
  let container = document.getElementById('toast-container');
  if (!container) {
    container = document.createElement('div');
    container.id = 'toast-container';
    container.style.position = 'fixed';
    container.style.bottom = '24px';
    container.style.right = '24px';
    container.style.zIndex = '99999';
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.gap = '10px';
    document.body.appendChild(container);
  }

  const toast = document.createElement('div');
  toast.className = `custom-toast toast-${type}`;
  toast.style.background = type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6';
  toast.style.color = '#fff';
  toast.style.padding = '12px 24px';
  toast.style.borderRadius = '8px';
  toast.style.boxShadow = '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)';
  toast.style.fontFamily = "'Outfit', sans-serif";
  toast.style.fontSize = '0.9rem';
  toast.style.fontWeight = '500';
  toast.style.minWidth = '250px';
  toast.style.transition = 'all 0.3s ease';
  toast.style.opacity = '0';
  toast.style.transform = 'translateY(20px)';
  toast.style.display = 'flex';
  toast.style.alignItems = 'center';

  // Icon
  const icon = type === 'success' ? '✅' : type === 'error' ? '❌' : 'ℹ️';
  toast.innerHTML = `<span style="margin-right: 10px; font-size: 1.1rem;">${icon}</span><span>${message}</span>`;

  container.appendChild(toast);

  // Trigger animation
  setTimeout(() => {
    toast.style.opacity = '1';
    toast.style.transform = 'translateY(0)';
  }, 10);

  // Auto remove
  setTimeout(() => {
    toast.style.opacity = '0';
    toast.style.transform = 'translateY(-20px)';
    setTimeout(() => {
      toast.remove();
    }, 300);
  }, 3500);
}
window.showToast = showToast; // Tornar acessível globalmente

// Função auxiliar para exibir alerta customizado e elegante (substitui o alert nativo)
function showCustomAlert(title, message) {
  return new Promise((resolve) => {
    const overlay = document.createElement('div');
    overlay.className = 'custom-dialog-overlay';
    
    overlay.innerHTML = `
      <div class="custom-dialog-card">
        <div class="custom-dialog-header">
          <span>🔔</span>
          <span>${escapeHtml(title)}</span>
        </div>
        <p class="custom-dialog-body">${escapeHtml(message)}</p>
        <div class="custom-dialog-footer">
          <button class="btn-dialog btn-dialog-confirm">OK</button>
        </div>
      </div>
    `;
    
    const btn = overlay.querySelector('.btn-dialog-confirm');
    btn.addEventListener('click', () => {
      overlay.remove();
      resolve();
    });
    
    document.body.appendChild(overlay);
  });
}

// Função auxiliar para exibir diálogo de confirmação elegante (substitui o confirm nativo)
function showCustomConfirm(title, message, isDanger = false) {
  return new Promise((resolve) => {
    const overlay = document.createElement('div');
    overlay.className = 'custom-dialog-overlay';
    
    overlay.innerHTML = `
      <div class="custom-dialog-card">
        <div class="custom-dialog-header">
          <span>${isDanger ? '⚠️' : '❓'}</span>
          <span>${escapeHtml(title)}</span>
        </div>
        <p class="custom-dialog-body">${escapeHtml(message)}</p>
        <div class="custom-dialog-footer">
          <button class="btn-dialog btn-dialog-cancel">Cancelar</button>
          <button class="btn-dialog ${isDanger ? 'btn-dialog-danger' : 'btn-dialog-confirm'}">${isDanger ? 'Excluir' : 'Confirmar'}</button>
        </div>
      </div>
    `;
    
    const btnCancel = overlay.querySelector('.btn-dialog-cancel');
    const btnConfirm = overlay.querySelector(isDanger ? '.btn-dialog-danger' : '.btn-dialog-confirm');
    
    btnCancel.addEventListener('click', () => {
      overlay.remove();
      resolve(false);
    });
    
    btnConfirm.addEventListener('click', () => {
      overlay.remove();
      resolve(true);
    });
    
    document.body.appendChild(overlay);
  });
}

// Função auxiliar para gerar nome de arquivo de download formatado como <nome_data_hora>.<extensao>
function getDownloadFileName(type, ext) {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');
  const seconds = String(now.getSeconds()).padStart(2, '0');
  return `${type}_${year}-${month}-${day}_${hours}-${minutes}-${seconds}.${ext}`;
}

renderer.code = function(code, language) {
  // Ajuste para lidar com as diferenças na assinatura do marked.js
  const codeContent = typeof code === 'object' ? code.text : code;
  const lang = (typeof code === 'object' ? code.lang : language) || 'txt';
  
  return `
    <div class="code-container">
      <div class="code-header">
        <span class="code-lang">${lang}</span>
        <button class="btn-copy-code" onclick="copyCode(this)">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H5.25m11.9-3.664A2.251 2.251 0 0 0 15 2.25h-3a2.251 2.251 0 0 0-2.15 1.586m5.8 0c.065.21.1.433.1.664v.75h-6V4.5c0-.231.035-.454.1-.664M6.75 7.5H4.875c-.621 0-1.125.504-1.125 1.125v12c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V16.5M16.5 9h3.75c.621 0 1.125.504 1.125 1.125v8.25c0 .621-.504 1.125-1.125 1.125H16.5m-3-12h3m-3 3h3M13.5 14.25h3" />
          </svg>
          <span>Copiar</span>
        </button>
      </div>
      <pre><code class="hljs language-${lang}">${escapeHtml(codeContent)}</code></pre>
    </div>
  `;
};

marked.use({ renderer });

// Função global de copiar código para que funcione no onclick
window.copyCode = function(button) {
  const container = button.closest('.code-container');
  const codeElement = container.querySelector('code');
  const textToCopy = codeElement.textContent;

  navigator.clipboard.writeText(textToCopy).then(() => {
    const textSpan = button.querySelector('span');
    const originalText = textSpan.textContent;
    textSpan.textContent = 'Copiado!';
    button.style.color = 'var(--success)';
    
    setTimeout(() => {
      textSpan.textContent = originalText;
      button.style.color = '';
    }, 2000);
  }).catch(err => {
    console.error('Erro ao copiar código:', err);
  });
};

const initApp = () => {
  // Elementos do DOM
  const sidebar = document.getElementById('sidebar');
  const btnMenu = document.getElementById('btnMenu');
  const btnCloseSidebar = document.getElementById('btnCloseSidebar');
  const sidebarOverlay = document.getElementById('sidebarOverlay');
  
  const userInput = document.getElementById('userInput');
  const btnSend = document.getElementById('btnSend');
  const btnVoice = document.getElementById('btnVoice');
  const chatForm = document.getElementById('chatForm');
  const messagesContainer = document.getElementById('messagesContainer');
  const welcomeContainer = document.getElementById('welcomeContainer');
  const conversationList = document.getElementById('conversationList');
  
  const btnNewChat = document.getElementById('btnNewChat');
  const btnNewChatMobile = document.getElementById('btnNewChatMobile');
  const historyItems = document.getElementById('historyItems');
  const btnLogout = document.getElementById('btnLogout');
  const suggestionCards = document.querySelectorAll('.suggestion-card');
  const searchInput = document.getElementById('searchInput');
  const searchClear = document.getElementById('searchClear');
  const searchResultsHeader = document.getElementById('searchResultsHeader');
  const searchResultsCount = document.getElementById('searchResultsCount');
  const searchClearAll = document.getElementById('searchClearAll');
  const sidebarTags = document.getElementById('sidebarTags');

  // Configuração de Identidade do Agente (PedagogIA/Pedagog)
  const btnSettings = document.getElementById('btnSettings');
  const settingsModal = document.getElementById('settingsModal');
  const closeSettingsModal = document.getElementById('closeSettingsModal');
  const btnSaveSettings = document.getElementById('btnSaveSettings');
  const settingAgentName = document.getElementById('settingAgentName');
  const previewIaAvatar = document.getElementById('previewIaAvatar');
  const uploadIaAvatar = document.getElementById('uploadIaAvatar');
  const previewUserAvatar = document.getElementById('previewUserAvatar');
  const uploadUserAvatar = document.getElementById('uploadUserAvatar');
  const welcomeTitle = document.getElementById('welcomeTitle');
  const welcomeAvatarImg = document.getElementById('welcomeAvatarImg');
  const sidebarAvatarImg = document.getElementById('sidebarAvatarImg');
  const temperatureOptions = document.getElementById('temperatureOptions');
  const knowledgeList = document.getElementById('knowledgeList');
  const manualKnowledgeInput = document.getElementById('manualKnowledgeInput');
  const btnAddKnowledge = document.getElementById('btnAddKnowledge');

  window.agentConfig = {
    agentName: "PedagogIA",
    iaAvatarUrl: "assets/pedagog_ia.png",
    userAvatarUrl: "assets/pedagog_user.png",
    temperaturePreset: 'equilibrado'
  };

  window.temperaturePresets = {
    tecnico: { value: 0.2, label: 'Técnico e Direto', description: 'Respostas curtas, objetivas, sem rodeios. Ideal para quando precisa só do essencial.' },
    equilibrado: { value: 0.6, label: 'Equilibrado', description: 'Bom para uso geral — nem muito curto, nem muito longo.' },
    detalhista: { value: 1.0, label: 'Detalhista e Falante', description: 'Respostas extensas, explicações completas, contextualização máxima. Ideal para estudo e revisão.' }
  };

  window.conhecimento = { facts: [], lastUpdated: null };

  // Carrega as configurações do servidor
  const loadAgentConfig = async () => {
    try {
      const res = await fetch('/api/agent-config');
      if (res.ok) {
        window.agentConfig = await res.json();
        updateAgentIdentityUI();
      }
    } catch (e) {
      console.error('Erro ao carregar configurações do agente:', e);
    }
  };

  const updateAgentIdentityUI = () => {
    if (welcomeTitle) {
      welcomeTitle.innerText = `Olá! Sou sua assistente virtual e me chamo ${window.agentConfig.agentName || 'PedagogIA'}. Como posso ajudar?`;
    }
    if (welcomeAvatarImg) {
      welcomeAvatarImg.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
    }
    if (sidebarAvatarImg) {
      sidebarAvatarImg.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
    }
    if (settingAgentName) {
      settingAgentName.value = window.agentConfig.agentName || 'PedagogIA';
    }
    if (previewIaAvatar) {
      previewIaAvatar.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
    }
    if (previewUserAvatar) {
      previewUserAvatar.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
    }
    // Atualiza seleção de temperatura
    renderTemperatureOptions();
  };

  // Carregar presets de temperatura do servidor
  const loadTemperaturePresets = async () => {
    try {
      const res = await fetch('/api/temperature-presets');
      if (res.ok) {
        window.temperaturePresets = await res.json();
        renderTemperatureOptions();
      }
    } catch (e) {
      console.error('Erro ao carregar presets de temperatura:', e);
    }
  };

  // Renderizar opções de temperatura
  const renderTemperatureOptions = () => {
    if (!temperatureOptions) return;
    const preset = window.agentConfig.temperaturePreset || 'equilibrado';
    temperatureOptions.innerHTML = Object.entries(window.temperaturePresets).map(([key, t]) => `
      <label class="temperature-option ${preset === key ? 'selected' : ''}" data-preset="${key}">
        <input type="radio" name="temperature" value="${key}" ${preset === key ? 'checked' : ''}>
        <div class="temperature-option-content">
          <strong>${t.label}</strong>
          <span>${t.description}</span>
        </div>
      </label>
    `).join('');

    // Event listeners para as opções
    temperatureOptions.querySelectorAll('.temperature-option').forEach(opt => {
      opt.addEventListener('click', () => {
        temperatureOptions.querySelectorAll('.temperature-option').forEach(o => o.classList.remove('selected'));
        opt.classList.add('selected');
        opt.querySelector('input').checked = true;
      });
    });
  };

  // Carregar conhecimento do servidor
  const loadConhecimento = async () => {
    try {
      const res = await fetch('/api/conhecimento');
      if (res.ok) {
        window.conhecimento = await res.json();
        renderKnowledgeList();
      }
    } catch (e) {
      console.error('Erro ao carregar conhecimento:', e);
    }
  };

  // Renderizar lista de conhecimento
  const renderKnowledgeList = () => {
    if (!knowledgeList) return;
    if (!window.conhecimento.facts || window.conhecimento.facts.length === 0) {
      knowledgeList.innerHTML = '<p style="color: var(--text-muted); text-align: center; padding: 20px;">Nenhum conhecimento aprendido ainda. A assistente aprende automaticamente quando você ensinar algo novo!</p>';
      return;
    }
    knowledgeList.innerHTML = window.conhecimento.facts.map(f => `
      <div class="knowledge-item" data-id="${f.id}">
        <div class="knowledge-item-content" id="knowledge-content-${f.id}">
          <span class="knowledge-source">${f.source}</span>
          <p style="margin: 4px 0 0 0;">${f.content}</p>
          <small style="display: block; margin-top: 4px;">${new Date(f.addedAt).toLocaleDateString('pt-BR')}</small>
        </div>
        <div class="knowledge-actions" id="knowledge-actions-${f.id}" style="display: flex; gap: 4px; align-self: flex-start; margin-left: 8px;">
          <button class="knowledge-edit-btn" onclick="startEditKnowledge(${f.id})" title="Editar" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 2px 4px; font-size: 0.9rem; transition: color 0.2s;">✏️</button>
          <button class="knowledge-delete-btn" onclick="deleteKnowledge(${f.id})" title="Excluir">×</button>
        </div>
      </div>
    `).join('');
  };

  // Iniciar edição de item de conhecimento
  window.startEditKnowledge = (id) => {
    const fact = window.conhecimento.facts.find(f => f.id === id);
    if (!fact) return;

    const contentDiv = document.getElementById(`knowledge-content-${id}`);
    const actionsDiv = document.getElementById(`knowledge-actions-${id}`);
    if (!contentDiv) return;

    if (actionsDiv) actionsDiv.style.display = 'none';

    contentDiv.innerHTML = `
      <span class="knowledge-source">${fact.source}</span>
      <textarea id="edit-textarea-${id}" style="width: 100%; min-height: 70px; padding: 8px; border-radius: 6px; border: 1px solid var(--brand-green); background: var(--bg-primary); color: var(--text-primary); font-family: var(--font-sans); font-size: 0.9rem; resize: vertical; margin: 6px 0; outline: none; box-shadow: 0 0 4px var(--brand-glow);">${fact.content}</textarea>
      <div style="display: flex; gap: 8px; margin-top: 4px;">
        <button onclick="saveEditKnowledge(${id})" style="background: var(--brand-green); border: none; color: white; padding: 4px 10px; border-radius: 6px; font-size: 0.75rem; cursor: pointer; font-weight: 500; transition: opacity 0.2s;">Salvar</button>
        <button onclick="renderKnowledgeList()" style="background: var(--bg-tertiary); border: none; color: var(--text-primary); padding: 4px 10px; border-radius: 6px; font-size: 0.75rem; cursor: pointer; font-weight: 500; transition: opacity 0.2s;">Cancelar</button>
      </div>
    `;

    const textarea = document.getElementById(`edit-textarea-${id}`);
    if (textarea) {
      textarea.focus();
      textarea.setSelectionRange(textarea.value.length, textarea.value.length);
    }
  };

  // Salvar edição de item de conhecimento
  window.saveEditKnowledge = async (id) => {
    const textarea = document.getElementById(`edit-textarea-${id}`);
    if (!textarea) return;
    const newContent = textarea.value.trim();
    if (!newContent) {
      alert('O conteúdo do conhecimento não pode ser vazio.');
      return;
    }

    try {
      const res = await fetch(`/api/conhecimento/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content: newContent })
      });
      if (res.ok) {
        const fact = window.conhecimento.facts.find(f => f.id === id);
        if (fact) fact.content = newContent;
        renderKnowledgeList();
      } else {
        const err = await res.json();
        alert('Erro ao salvar conhecimento: ' + err.error);
      }
    } catch (e) {
      console.error('Erro ao atualizar conhecimento:', e);
      alert('Erro de conexão ao salvar conhecimento.');
    }
  };

  // Deletar item de conhecimento (função global para onclick)
  window.deleteKnowledge = async (id) => {
    if (!confirm('Deseja realmente remover este conhecimento aprendido?')) return;
    try {
      const res = await fetch(`/api/conhecimento/${id}`, { method: 'DELETE' });
      if (res.ok) {
        window.conhecimento.facts = window.conhecimento.facts.filter(f => f.id !== id);
        renderKnowledgeList();
      }
    } catch (e) {
      console.error('Erro ao deletar conhecimento:', e);
    }
  };

  // Adicionar conhecimento manualmente
  if (btnAddKnowledge) {
    btnAddKnowledge.addEventListener('click', async () => {
      const input = manualKnowledgeInput?.value.trim();
      if (!input) return;
      try {
        const res = await fetch('/api/conhecimento', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ fact: input, source: 'manual' })
        });
        if (res.ok) {
          const data = await res.json();
          if (data.added) {
            manualKnowledgeInput.value = '';
            await loadConhecimento();
          } else {
            alert('Esta informação já existe ou é similar a um conhecimento que a IA já possui.');
          }
        } else {
          alert('Erro ao salvar no servidor. Verifique sua conexão.');
        }
      } catch (e) {
        console.error('Erro ao adicionar conhecimento:', e);
        alert('Erro ao processar requisição.');
      }
    });
  }

  // Função para extrair knowledge tags da resposta da IA e enviar ao servidor
  window.extractAndSaveKnowledge = async (assistantMessage) => {
    if (!assistantMessage || !assistantMessage.includes('[KNOWLEDGE:')) return;
    try {
      await fetch('/api/conhecimento/extrair', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: assistantMessage })
      });
    } catch (e) {
      console.error('Erro ao extrair conhecimento:', e);
    }
  };

  // Variáveis temporárias para avatares (em base64 ou URLs novas)
  let newIaAvatarData = null;
  let newUserAvatarData = null;

  // Eventos do Modal
  if (btnSettings) {
    btnSettings.addEventListener('click', () => {
      newIaAvatarData = null;
      newUserAvatarData = null;
      if (settingAgentName) settingAgentName.value = window.agentConfig.agentName || 'PedagogIA';
      if (previewIaAvatar) previewIaAvatar.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
      if (previewUserAvatar) previewUserAvatar.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
      renderTemperatureOptions();
      loadConhecimento();
      settingsModal.style.display = 'flex';
    });
  }

  if (closeSettingsModal) {
    closeSettingsModal.addEventListener('click', () => {
      settingsModal.style.display = 'none';
    });
  }

  // Tab switching logic
  document.querySelectorAll('.settings-tab').forEach(tab => {
    tab.addEventListener('click', () => {
      document.querySelectorAll('.settings-tab').forEach(t => t.classList.remove('active'));
      document.querySelectorAll('.settings-tab-content').forEach(c => c.classList.remove('active'));
      tab.classList.add('active');
      const targetId = tab.dataset.tab;
      const targetContent = document.getElementById(targetId);
      if (targetContent) targetContent.classList.add('active');
    });
  });

  // Fechar clicando fora do modal-content
  if (settingsModal) {
    settingsModal.addEventListener('click', (e) => {
      if (e.target === settingsModal) {
        settingsModal.style.display = 'none';
      }
    });
  }

  // Previews de Imagem
  const handleAvatarFileSelect = (input, previewImg, callback) => {
    const file = input.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        previewImg.src = e.target.result;
        callback(e.target.result);
      };
      reader.readAsDataURL(file);
    }
  };

  if (uploadIaAvatar) {
    uploadIaAvatar.addEventListener('change', () => {
      handleAvatarFileSelect(uploadIaAvatar, previewIaAvatar, (base64) => {
        newIaAvatarData = base64;
      });
    });
  }

  if (uploadUserAvatar) {
    uploadUserAvatar.addEventListener('change', () => {
      handleAvatarFileSelect(uploadUserAvatar, previewUserAvatar, (base64) => {
        newUserAvatarData = base64;
      });
    });
  }

  // Salvar Configurações
  if (btnSaveSettings) {
    btnSaveSettings.addEventListener('click', async () => {
      btnSaveSettings.disabled = true;
      btnSaveSettings.innerText = 'Salvando...';

      try {
        let iaUrl = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
        let userUrl = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';

        // Se houver novas imagens, faz upload
        if (newIaAvatarData) {
          const res = await fetch('/api/upload-avatar', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ avatarType: 'ia', base64Data: newIaAvatarData })
          });
          if (res.ok) {
            const data = await res.json();
            iaUrl = data.url;
          }
        }

        if (newUserAvatarData) {
          const res = await fetch('/api/upload-avatar', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ avatarType: 'user', base64Data: newUserAvatarData })
          });
          if (res.ok) {
            const data = await res.json();
            userUrl = data.url;
          }
        }

        // Envia as configurações gerais
        const selectedTempPreset = temperatureOptions?.querySelector('input[name="temperature"]:checked')?.value || 'equilibrado';
        const resConfig = await fetch('/api/agent-config', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            agentName: settingAgentName.value,
            iaAvatarUrl: iaUrl,
            userAvatarUrl: userUrl,
            temperaturePreset: selectedTempPreset
          })
        });

        if (resConfig.ok) {
          const result = await resConfig.json();
          window.agentConfig = result.config;
          updateAgentIdentityUI();
          settingsModal.style.display = 'none';
        } else {
          alert('Erro ao salvar as configurações.');
        }
      } catch (err) {
        console.error(err);
        alert('Ocorreu um erro ao salvar.');
      } finally {
        btnSaveSettings.disabled = false;
        btnSaveSettings.innerText = 'Salvar Configurações';
      }
    });
  }

  // Executa o carregamento inicial das configurações
  loadAgentConfig();

  // Variáveis de Estado
  let chats = JSON.parse(localStorage.getItem('pedagog_chats') || localStorage.getItem('camila_chats')) || [];
  // Migração: adicionar campos tags e pinned a chats antigos
  chats = chats.map(c => ({ ...c, tags: c.tags || [], pinned: c.pinned || false }));
  let currentChatId = localStorage.getItem('pedagog_current_chat_id') || localStorage.getItem('camila_current_chat_id') || null;
  let isGenerating = false;
  let searchQuery = '';
  let activeTag = 'all';
  let currentUtterance = null; // para controlar TTS em andamento

  // Variáveis de Reconhecimento de Voz
  let recognition = null;
  let isListening = false;
  let lastInputWasVoice = false; // Rastrear se a última mensagem veio do microfone

  // ==========================================================================
  // THEME TOGGLE — Claro/Escuro
  // ==========================================================================
  const btnThemeToggle = document.getElementById('btnThemeToggle');
  const iconThemeSun = document.getElementById('iconThemeSun');
  const iconThemeMoon = document.getElementById('iconThemeMoon');

  const applyTheme = (theme) => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('pedagog_theme', theme);
    if (theme === 'light') {
      iconThemeSun.style.display = 'none';
      iconThemeMoon.style.display = 'block';
    } else {
      iconThemeSun.style.display = 'block';
      iconThemeMoon.style.display = 'none';
    }
  };

  // Init theme from localStorage or system preference
  const savedTheme = localStorage.getItem('pedagog_theme') || localStorage.getItem('camila_theme');
  if (savedTheme) {
    applyTheme(savedTheme);
  } else {
    // Default to dark
    applyTheme('dark');
  }

  btnThemeToggle.addEventListener('click', () => {
    const current = document.documentElement.getAttribute('data-theme') || 'dark';
    applyTheme(current === 'dark' ? 'light' : 'dark');
  });

  // ==========================================================================
  // BADGE DE MODELO DINÂMICO
  // ==========================================================================
  const modelBadgeText = document.getElementById('modelBadgeText');
  const updateModelBadge = async () => {
    try {
      const res = await fetch('/api/status');
      if (res.ok) {
        const data = await res.json();
        // Extrai nome abreviado do modelo (ex: "openai/gpt-4.1-nano" → "GPT-4.1 Nano")
        const modelName = data.model.split('/').pop();
        const formatted = modelName.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
        modelBadgeText.textContent = formatted;
      }
    } catch (e) {
      // Mantém texto padrão se falhar
    }
  };
  updateModelBadge();

  // ==========================================================================
  // MODAL DE TAGS & SIDEBAR TAGS
  // ==========================================================================
  const AVAILABLE_TAGS = [
    { id: 'relatorios', label: '📋 Relatórios' },
    { id: 'planejamento', label: '📝 Planejamento' },
    { id: 'mindlab', label: '🧠 Mind Lab' },
    { id: 'estudos', label: '📚 Estudos' },
    { id: 'htpc', label: '💻 HTPC' },
    { id: 'ata', label: '📝 ATA' },
    { id: 'sugestao', label: '💡 Sugestão' },
    { id: 'duvida', label: '❓ Dúvida' }
  ];
  const modalTagOverlay = document.getElementById('modalTagOverlay');
  const modalTagList = document.getElementById('modalTagList');
  const modalTagClose = document.getElementById('modalTagClose');
  const modalTagCancel = document.getElementById('modalTagCancel');
  const modalTagConfirm = document.getElementById('modalTagConfirm');
  let pendingTagAction = null; // { chatId, callback }
  let selectedTagsState = [];

  const openTagModal = (chatId, currentTags, callback) => {
    pendingTagAction = { chatId, callback };
    selectedTagsState = [...currentTags];
    renderTagModalList();
    modalTagOverlay.classList.add('active');
  };

  const closeTagModal = () => {
    modalTagOverlay.classList.remove('active');
    pendingTagAction = null;
  };

  const renderTagModalList = () => {
    modalTagList.innerHTML = AVAILABLE_TAGS.map(tag => `
      <div class="modal-tag-item ${selectedTagsState.includes(tag.id) ? 'selected' : ''}" data-tag="${tag.id}">
        <input type="checkbox" ${selectedTagsState.includes(tag.id) ? 'checked' : ''}>
        <span>${tag.label}</span>
      </div>
    `).join('');

    modalTagList.querySelectorAll('.modal-tag-item').forEach(item => {
      item.addEventListener('click', () => {
        const tag = item.dataset.tag;
        if (selectedTagsState.includes(tag)) {
          selectedTagsState = selectedTagsState.filter(t => t !== tag);
        } else {
          selectedTagsState.push(tag);
        }
        renderTagModalList();
      });
    });
  };

  const renderSidebarTags = () => {
    if (!sidebarTags) return;
    let tagsHtml = `<button class="tag-filter ${activeTag === 'all' ? 'active' : ''}" data-tag="all">Todas</button>`;
    tagsHtml += AVAILABLE_TAGS.map(tag => `
      <button class="tag-filter ${activeTag === tag.id ? 'active' : ''}" data-tag="${tag.id}">
        ${tag.label}
      </button>
    `).join('');
    sidebarTags.innerHTML = tagsHtml;
  };

  modalTagClose.addEventListener('click', closeTagModal);
  modalTagCancel.addEventListener('click', closeTagModal);
  modalTagOverlay.addEventListener('click', (e) => {
    if (e.target === modalTagOverlay) closeTagModal();
  });

  modalTagConfirm.addEventListener('click', () => {
    if (pendingTagAction) {
      pendingTagAction.callback(selectedTagsState);
    }
    closeTagModal();
  });

  // Expose globally for inline onclick handlers
  window.openTagModal = openTagModal;

  // ==========================================================================
  // CONTROLES DE INTERFACE & SIDEBAR
  // ==========================================================================

  const toggleSidebar = (open) => {
    if (open) {
      sidebar.classList.add('open');
    } else {
      sidebar.classList.remove('open');
    }
  };

  btnMenu.addEventListener('click', () => toggleSidebar(true));
  btnCloseSidebar.addEventListener('click', () => toggleSidebar(false));
  sidebarOverlay.addEventListener('click', () => toggleSidebar(false));

  // Redimensionamento automático do Input de Texto (textarea)
  userInput.addEventListener('input', () => {
    userInput.style.height = 'auto';
    userInput.style.height = (userInput.scrollHeight - 4) + 'px';
    
    // Habilitar ou desabilitar botão
    btnSend.disabled = userInput.value.trim() === '' || isGenerating;
  });

  // Prevenir comportamento padrão do Enter no textarea (enviar em vez de quebrar linha, Shift+Enter para nova linha)
  userInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      if (userInput.value.trim() !== '' && !isGenerating) {
        chatForm.requestSubmit();
      }
    }
  });

  // Busca no histórico
  searchInput.addEventListener('input', () => {
    searchQuery = searchInput.value;
    searchClear.style.display = searchQuery ? 'flex' : 'none';
    renderHistory();
  });

  searchClear.addEventListener('click', () => {
    searchInput.value = '';
    searchQuery = '';
    searchClear.style.display = 'none';
    renderHistory();
  });

  searchClearAll.addEventListener('click', () => {
    searchInput.value = '';
    searchQuery = '';
    searchClear.style.display = 'none';
    renderHistory();
  });

  // Alternar (expandir/recolher) as tags
  const btnToggleSidebarTags = document.getElementById('btnToggleSidebarTags');
  if (btnToggleSidebarTags && sidebarTags) {
    btnToggleSidebarTags.addEventListener('click', () => {
      if (sidebarTags.style.display === 'none') {
        sidebarTags.style.display = 'flex';
      } else {
        sidebarTags.style.display = 'none';
      }
    });
  }

  // Filtro por tags
  sidebarTags.addEventListener('click', (e) => {
    const tagBtn = e.target.closest('.tag-filter');
    if (!tagBtn) return;
    activeTag = tagBtn.dataset.tag;
    renderHistory();
  });

  // ==========================================================================
  // VOZ — WEB SPEECH API (ditado + conversa por voz)
  // ==========================================================================

  const initVoiceRecognition = () => {
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    if (!SpeechRecognition) {
      btnVoice.style.display = 'none';
      console.warn('SpeechRecognition não suportado neste navegador.');
      return;
    }

    recognition = new SpeechRecognition();
    recognition.lang = 'pt-BR';
    recognition.continuous = false;
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;

    recognition.onresult = (event) => {
      const transcript = event.results[0][0].transcript;
      userInput.value = transcript;
      userInput.dispatchEvent(new Event('input'));
      setVoiceState(false);

      // Marca que o input veio do microfone para auto-responder por voz
      lastInputWasVoice = true;

      // Envia automaticamente a mensagem ditada
      if (transcript.trim()) {
        setTimeout(() => {
          chatForm.dispatchEvent(new Event('submit', { cancelable: true }));
        }, 300);
      }
    };

    recognition.onerror = (event) => {
      console.warn('Voice error:', event.error);
      setVoiceState(false);
    };

    recognition.onend = () => {
      setVoiceState(false);
    };
  };

  const setVoiceState = (listening) => {
    isListening = listening;
    if (listening) {
      btnVoice.classList.add('listening');
      btnVoice.setAttribute('title', 'Clique para parar de ouvir');
    } else {
      btnVoice.classList.remove('listening');
      btnVoice.setAttribute('title', 'Conversar por voz');
    }
  };

  btnVoice.addEventListener('click', () => {
    if (!recognition) return;
    if (isListening) {
      recognition.stop();
    } else {
      recognition.start();
      setVoiceState(true);
    }
  });

  // ==========================================================================
  // TTS — Speech Synthesis nativa (voz do navegador)
  // ==========================================================================

  // Selecionar melhor voz pt-BR disponível no dispositivo de forma dinâmica
  const getBestVoice = () => {
    const voices = window.speechSynthesis.getVoices();
    const ptBR = voices.filter(v => v.lang === 'pt-BR' || v.lang === 'pt_BR');
    if (ptBR.length === 0) {
      const pt = voices.filter(v => v.lang.startsWith('pt'));
      return pt[0] || null;
    }

    // 1. Microsoft Neural (Edge): Thalita, Francisca, Giovanna
    const msNeural = ptBR.find(v => /thalita|francisca|giovanna|natural|neural/i.test(v.name));
    if (msNeural) return msNeural;

    // 2. Google (Chrome/Android): vozes naturais
    const google = ptBR.find(v => /google/i.test(v.name));
    if (google) return google;

    // 3. Apple (Safari/iOS): Luciana é excelente
    const apple = ptBR.find(v => /luciana|fernanda/i.test(v.name));
    if (apple) return apple;

    // 4. Qualquer feminina
    const female = ptBR.find(v => /female|femin|maria|raquel|camila/i.test(v.name));
    if (female) return female;

    // 5. Primeira disponível
    return ptBR[0];
  };

  const resetSpeakBtnState = (btn) => {
    if (btn) {
      btn.classList.remove('speaking');
      const span = btn.querySelector('span');
      if (span) span.textContent = 'Ouvir';
    }
  };

  let currentSpeakingBtn = null;
  let currentAudio = null;
  let ttsFallbackTimeout = null;

  // Função auxiliar para parar qualquer áudio em andamento (tanto nativo quanto do backend)
  const stopAllSpeech = () => {
    // Parar áudio do backend
    if (currentAudio) {
      currentAudio.pause();
      currentAudio = null;
    }
    // Parar SpeechSynthesis nativo
    window.speechSynthesis.cancel();
    
    // Limpar timeouts pendentes
    if (ttsFallbackTimeout) {
      clearTimeout(ttsFallbackTimeout);
      ttsFallbackTimeout = null;
    }

    // Resetar estado do botão ativo anterior
    if (currentSpeakingBtn) {
      resetSpeakBtnState(currentSpeakingBtn);
      currentSpeakingBtn = null;
    }
  };

  const speakTextLocalFallback = (cleanText, btn) => {
    console.log('[TTS] Acionando fallback local (voz nativa do navegador)...');
    
    // Configura SpeechSynthesis nativo
    const utterance = new SpeechSynthesisUtterance(cleanText);
    utterance.lang = 'pt-BR';
    utterance.rate = 1.15;
    utterance.pitch = 1.0;

    const voice = getBestVoice();
    if (voice) utterance.voice = voice;

    utterance.onstart = () => {
      if (btn) {
        btn.classList.add('speaking');
        const span = btn.querySelector('span');
        if (span) span.textContent = 'Parar';
      }
    };

    const handleStop = (event) => {
      console.log('TTS nativo finalizado ou com erro:', event.type);
      if (currentSpeakingBtn === btn) {
        resetSpeakBtnState(btn);
        currentSpeakingBtn = null;
      }
    };

    utterance.onend = handleStop;
    utterance.onerror = handleStop;

    window.speechSynthesis.speak(utterance);
  };

  // Falar texto com reprodução híbrida (prioriza Opção A: MsEdgeTTS com fallback local)
  const speakText = async (text, btn) => {
    if (!text) return;

    // Se clicar no botão que já está ativo, para tudo e retorna
    if (currentSpeakingBtn === btn) {
      stopAllSpeech();
      return;
    }

    // Para qualquer reprodução anterior
    stopAllSpeech();

    currentSpeakingBtn = btn;

    // Limpar markdown e emojis antes de falar
    const clean = text
      .replace(/\p{Extended_Pictographic}/gu, '') // Remove emojis pictográficos (ex: ✍️, 📝, 🧒)
      .replace(/[\u{1F300}-\u{1F9FF}]|[\u{2700}-\u{27BF}]|[\u{2600}-\u{26FF}]/gu, '') // Fallback para símbolos/dingbats comuns
      .replace(/```[\s\S]*?```/g, '')
      .replace(/`[^`]+`/g, '')
      .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
      .replace(/[*_#~\[\]>]/g, '')
      .replace(/\n+/g, '. ')
      .replace(/\s{2,}/g, ' ')
      .trim();

    if (!clean) {
      currentSpeakingBtn = null;
      return;
    }

    // Coloca o botão em estado de "carregando"
    if (btn) {
      btn.classList.add('speaking');
      const span = btn.querySelector('span');
      if (span) span.textContent = 'Carregando...';
    }

    let fallbackTriggered = false;

    // Configura o timeout de 15 segundos para o fallback nativo
    ttsFallbackTimeout = setTimeout(() => {
      if (currentSpeakingBtn === btn) {
        fallbackTriggered = true;
        if (currentAudio) {
          currentAudio.pause();
          currentAudio = null;
        }
        speakTextLocalFallback(clean, btn);
      }
    }, 15000);

    try {
      console.log('[TTS] Solicitando voz neural de alta qualidade ao backend...');
      const response = await fetch('/api/tts', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ text: clean })
      });

      if (!response.ok) {
        throw new Error(`Erro no servidor: ${response.status}`);
      }

      const blob = await response.blob();
      
      // Se o fallback já foi acionado durante a espera, ignora o retorno do áudio do backend
      if (fallbackTriggered) {
        return;
      }

      // Limpar o timeout de fallback já que o áudio respondeu a tempo
      if (ttsFallbackTimeout) {
        clearTimeout(ttsFallbackTimeout);
        ttsFallbackTimeout = null;
      }

      const audioUrl = URL.createObjectURL(blob);
      currentAudio = new Audio(audioUrl);

      currentAudio.onplay = () => {
        if (currentSpeakingBtn === btn) {
          const span = btn.querySelector('span');
          if (span) span.textContent = 'Parar';
        }
      };

      const handleAudioStop = () => {
        if (currentSpeakingBtn === btn) {
          resetSpeakBtnState(btn);
          currentSpeakingBtn = null;
          currentAudio = null;
        }
        URL.revokeObjectURL(audioUrl);
      };

      currentAudio.onended = handleAudioStop;
      currentAudio.onerror = (e) => {
        console.error('[TTS] Erro ao reproduzir áudio do backend:', e);
        if (currentSpeakingBtn === btn && !fallbackTriggered) {
          fallbackTriggered = true;
          speakTextLocalFallback(clean, btn);
        }
      };

      await currentAudio.play();

    } catch (err) {
      console.error('[TTS] Falha ao obter áudio do backend, acionando fallback local imediatamente:', err);
      // Limpa timeout e ativa fallback local imediatamente se der erro de rede
      if (ttsFallbackTimeout) {
        clearTimeout(ttsFallbackTimeout);
        ttsFallbackTimeout = null;
      }
      if (currentSpeakingBtn === btn && !fallbackTriggered) {
        fallbackTriggered = true;
        speakTextLocalFallback(clean, btn);
      }
    }
  };

  // ==========================================================================
  // ANEXOS — Upload de imagens e documentos
  // ==========================================================================

  const fileInput = document.getElementById('fileInput');
  const btnAttach = document.getElementById('btnAttach');
  let attachedFiles = [];

  // Criar preview container se não existir
  let attachPreview = document.querySelector('.attachments-preview');

  const ensureAttachPreview = () => {
    if (!attachPreview) {
      attachPreview = document.createElement('div');
      attachPreview.className = 'attachments-preview';
      document.getElementById('chatForm').appendChild(attachPreview);
    }
  };

  // Botão de anexar → abre seletor de arquivos
  btnAttach.addEventListener('click', () => {
    fileInput.click();
  });

  // Botão alternador de ferramentas (recursos) - FAB Tools
  const fabTools = document.getElementById('fabTools');
  const promptModesBar = document.querySelector('.prompt-modes-bar');

  if (fabTools && promptModesBar) {
    fabTools.addEventListener('click', () => {
      promptModesBar.classList.toggle('show');
      fabTools.classList.toggle('active');
    });
  }

  // Quando arquivos são selecionados
  fileInput.addEventListener('change', () => {
    const files = Array.from(fileInput.files);
    if (files.length === 0) return;

    files.forEach(file => {
      // Limite de 10MB por arquivo
      if (file.size > 10 * 1024 * 1024) {
        alert(`Arquivo "${file.name}" é muito grande. Máximo: 10MB.`);
        return;
      }
      attachedFiles.push(file);
    });

    renderAttachPreview();
    fileInput.value = ''; // reset para permitir selects again
  });

  // Arrastar e soltar na área do chat
  const chatArea = document.querySelector('.chat-area');
  if (chatArea) {
    chatArea.addEventListener('dragover', (e) => {
      e.preventDefault();
      chatArea.classList.add('drag-over');
    });
    chatArea.addEventListener('dragleave', () => {
      chatArea.classList.remove('drag-over');
    });
    chatArea.addEventListener('drop', (e) => {
      e.preventDefault();
      chatArea.classList.remove('drag-over');
      const files = Array.from(e.dataTransfer.files);
      files.forEach(file => {
        if (file.size <= 10 * 1024 * 1024) {
          attachedFiles.push(file);
        }
      });
      renderAttachPreview();
    });
  }

  // Renderizar preview dos anexos
  const renderAttachPreview = () => {
    ensureAttachPreview();
    attachPreview.innerHTML = '';

    if (attachedFiles.length === 0) {
      attachPreview.style.display = 'none';
      btnAttach.classList.remove('has-files');
      return;
    }

    btnAttach.classList.add('has-files');
    attachPreview.style.display = 'flex';

    attachedFiles.forEach((file, index) => {
      const item = document.createElement('div');
      item.className = 'attachment-item';

      const isImage = file.type.startsWith('image/');
      let previewHtml = '';

      if (isImage) {
        const url = URL.createObjectURL(file);
        previewHtml = `<img src="${url}" alt="${file.name}">`;
      } else {
        previewHtml = `<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path stroke-linecap="round" stroke-linejoin="round" d="m15.75 10.5 4.72-4.72a.75.75 0 0 1 1.28.53v11.38a.75.75 0 0 1-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25h-9A2.25 2.25 0 0 0 2.25 7.5v9a2.25 2.25 0 0 0 2.25 2.25Z" />
        </svg>`;
      }

      item.innerHTML = `
        ${previewHtml}
        <span class="file-name">${file.name}</span>
        <button type="button" class="remove-attachment" data-index="${index}">×</button>
      `;

      attachPreview.appendChild(item);
    });

    // Botões de remover
    attachPreview.querySelectorAll('.remove-attachment').forEach(btn => {
      btn.addEventListener('click', () => {
        const idx = parseInt(btn.dataset.index);
        attachedFiles.splice(idx, 1);
        renderAttachPreview();
      });
    });
  };

  // ==========================================================================
  // ATALHOS DE TECLADO
  // ==========================================================================

  document.addEventListener('keydown', (e) => {
    // Ctrl+N → novo chat
    if ((e.ctrlKey || e.metaKey) && e.key === 'n') {
      e.preventDefault();
      createNewChat();
    }
    // Ctrl+F ou Ctrl+K → focar busca
    if ((e.ctrlKey || e.metaKey) && (e.key === 'f' || e.key === 'k')) {
      e.preventDefault();
      toggleSidebar(true);
      setTimeout(() => searchInput.focus(), 50);
    }
    // Escape → fechar sidebar
    if (e.key === 'Escape') {
      toggleSidebar(false);
    }
  });

  // ==========================================================================
  // HISTÓRICO DE CHATS (LOCALSTORAGE) — VERSÃO COMPLETA COM PINNED, TAGS, BUSCA
  // ==========================================================================

  const saveChats = () => {
    localStorage.setItem('pedagog_chats', JSON.stringify(chats));
    if (currentChatId) {
      localStorage.setItem('pedagog_current_chat_id', currentChatId);
    } else {
      localStorage.removeItem('pedagog_current_chat_id');
    }
  };

  // Agrupamento por data
  const getDateGroup = (timestamp) => {
    const now = new Date();
    const date = new Date(timestamp);
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const yesterday = new Date(today);
    yesterday.setDate(yesterday.getDate() - 1);
    const weekAgo = new Date(today);
    weekAgo.setDate(weekAgo.getDate() - 7);
    const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);

    const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());

    if (dateOnly.getTime() === today.getTime()) return 'Hoje';
    if (dateOnly.getTime() === yesterday.getTime()) return 'Ontem';
    if (dateOnly >= weekAgo) return 'Esta Semana';
    if (dateOnly >= monthStart) return 'Este Mês';
    return 'Mais Antigas';
  };

  // Filtrar chats por tag
  const filterByTag = (chatList) => {
    if (activeTag === 'all') return chatList;
    return chatList.filter(chat => chat.tags && chat.tags.includes(activeTag));
  };

  // Filtrar chats por busca
  const filterBySearch = (chatList) => {
    if (!searchQuery.trim()) return chatList;
    const q = searchQuery.toLowerCase();
    return chatList.filter(chat => {
      if (chat.title.toLowerCase().includes(q)) return true;
      return chat.messages.some(msg => msg.content.toLowerCase().includes(q));
    });
  };

  // Renderizar um item de chat
  const createHistoryItem = (chat) => {
    const item = document.createElement('div');
    item.className = `history-item ${chat.id === currentChatId ? 'active' : ''} ${chat.pinned ? 'pinned' : ''}`;
    item.dataset.id = chat.id;

    const pinIcon = chat.pinned
      ? `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="pin-icon"><line x1="12" y1="17" x2="12" y2="22" stroke="currentColor" stroke-width="2" stroke-linecap="round"></line><path d="M5 17h14v-1.76a2 2 0 0 0-.44-1.24l-2.78-3.47A2 2 0 0 1 15 9.29V5a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4.29a2 2 0 0 1-.78 1.24L5.44 14a2 2 0 0 0-.44 1.24z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>`
      : '';

    const tagBadges = (chat.tags || []).map(tag =>
      `<span class="history-tag-badge">${getTagEmoji(tag)}</span>`
    ).join('');

    item.innerHTML = `
      <div class="history-item-content">
        ${pinIcon}
        <div class="history-item-title">${escapeHtml(chat.title)}</div>
        ${tagBadges ? `<div class="history-item-tags">${tagBadges}</div>` : ''}
      </div>
      <div class="history-item-actions">
        <button class="btn-history-action btn-pin-chat" title="${chat.pinned ? 'Desafixar' : 'Fixar'}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="${chat.pinned ? 'currentColor' : 'none'}" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <line x1="12" y1="17" x2="12" y2="22"></line>
            <path d="M5 17h14v-1.76a2 2 0 0 0-.44-1.24l-2.78-3.47A2 2 0 0 1 15 9.29V5a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4.29a2 2 0 0 1-.78 1.24L5.44 14a2 2 0 0 0-.44 1.24z"></path>
          </svg>
        </button>
        <button class="btn-history-action btn-tag-chat" title="Tags">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581a2.25 2.25 0 0 0 3.181 0l4.318-4.318a2.25 2.25 0 0 0 0-3.181l-9.58-9.581A2.25 2.25 0 0 0 9.568 3Z" />
            <path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
          </svg>
        </button>
        <button class="btn-history-action btn-rename-chat" title="Renomear">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
          </svg>
        </button>
        <button class="btn-history-action btn-delete-chat" title="Excluir">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
          </svg>
        </button>
      </div>
    `;

    return item;
  };

  // Emoji para cada tag
  const getTagEmoji = (tag) => {
    const emojis = { 
      relatorios: '📋', 
      planejamento: '📝', 
      mindlab: '🧠', 
      estudos: '📚',
      htpc: '💻',
      ata: '📝',
      sugestao: '💡',
      duvida: '❓'
    };
    return emojis[tag] || '🏷️';
  };

  // Renderizar histórico completo
  const renderHistory = () => {
    renderSidebarTags(); // Renderizar tags da sidebar de forma dinâmica e atualizada
    historyItems.innerHTML = '';

    if (chats.length === 0) {
      historyItems.innerHTML = '<div style="color: var(--text-muted); font-size: 12px; padding: 10px; text-align: center;">Nenhum chat salvo</div>';
      return;
    }

    // Aplicar filtros
    let filtered = [...chats];
    filtered = filterByTag(filtered);
    filtered = filterBySearch(filtered);

    // Se tem busca, mostrar resultados direto (sem grupo)
    if (searchQuery.trim()) {
      searchResultsHeader.style.display = 'block';
      searchResultsCount.textContent = `${filtered.length} resultado${filtered.length !== 1 ? 's' : ''}`;
      filtered.sort((a, b) => b.updatedAt - a.updatedAt);
      filtered.forEach(chat => {
        const item = createHistoryItem(chat);
        item.addEventListener('click', (e) => {
          if (e.target.closest('.btn-delete-chat')) { e.stopPropagation(); deleteChat(chat.id); return; }
          if (e.target.closest('.btn-pin-chat')) { e.stopPropagation(); togglePin(chat.id); return; }
          if (e.target.closest('.btn-rename-chat')) { e.stopPropagation(); renameChatInline(chat.id, item); return; }
          if (e.target.closest('.btn-tag-chat')) { e.stopPropagation(); editTags(chat.id); return; }
          selectChat(chat.id);
          toggleSidebar(false);
        });
        historyItems.appendChild(item);
      });
      return;
    }

    searchResultsHeader.style.display = 'none';

    // Separar pinned e não-pinned
    const pinned = filtered.filter(c => c.pinned).sort((a, b) => b.updatedAt - a.updatedAt);
    const unpinned = filtered.filter(c => !c.pinned).sort((a, b) => b.updatedAt - a.updatedAt);

    // Renderizar grupo se tiver items
    const renderGroup = (label, items) => {
      if (items.length === 0) return;
      const group = document.createElement('div');
      group.className = 'history-group';
      group.innerHTML = `<h3>${label}</h3>`;
      const container = document.createElement('div');
      container.className = 'history-items';
      items.forEach(chat => {
        const item = createHistoryItem(chat);
        item.addEventListener('click', (e) => {
          if (e.target.closest('.btn-delete-chat')) { e.stopPropagation(); deleteChat(chat.id); return; }
          if (e.target.closest('.btn-pin-chat')) { e.stopPropagation(); togglePin(chat.id); return; }
          if (e.target.closest('.btn-rename-chat')) { e.stopPropagation(); renameChatInline(chat.id, item); return; }
          if (e.target.closest('.btn-tag-chat')) { e.stopPropagation(); editTags(chat.id); return; }
          selectChat(chat.id);
          toggleSidebar(false);
        });
        container.appendChild(item);
      });
      group.appendChild(container);
      historyItems.appendChild(group);
    };

    // Pinned no topo
    if (pinned.length > 0) {
      renderGroup('📌 Fixadas', pinned);
    }

    // Agrupar por data os não-pinned
    const groups = {};
    unpinned.forEach(chat => {
      const group = getDateGroup(chat.updatedAt);
      if (!groups[group]) groups[group] = [];
      groups[group].push(chat);
    });

    ['Hoje', 'Ontem', 'Esta Semana', 'Este Mês', 'Mais Antigas'].forEach(g => {
      if (groups[g]) renderGroup(g, groups[g]);
    });
  };

  // Fixar/desfixar chat
  const togglePin = (id) => {
    const chat = chats.find(c => c.id === id);
    if (!chat) return;
    chat.pinned = !chat.pinned;
    saveChats();
    renderHistory();
  };

  // Renomear chat inline
  const renameChatInline = (id, itemElement) => {
    const chat = chats.find(c => c.id === id);
    if (!chat) return;

    const titleDiv = itemElement.querySelector('.history-item-title');
    if (!titleDiv) return;

    const originalTitle = chat.title;
    const input = document.createElement('input');
    input.type = 'text';
    input.className = 'rename-input';
    input.value = originalTitle;

    // Prevenir clique e propagação para o item
    input.addEventListener('click', (e) => e.stopPropagation());

    const finishRename = () => {
      const newTitle = input.value.trim();
      if (newTitle && newTitle !== originalTitle) {
        chat.title = newTitle;
        chat.updatedAt = Date.now();
        saveChats();
      }
      renderHistory();
    };

    input.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        finishRename();
      } else if (e.key === 'Escape') {
        e.preventDefault();
        renderHistory();
      }
    });

    input.addEventListener('blur', finishRename);

    titleDiv.replaceWith(input);
    input.focus();
    input.select();
  };

  // Gerenciar tags da conversa
  const editTags = (id) => {
    const chat = chats.find(c => c.id === id);
    if (!chat) return;
    const currentTags = chat.tags || [];
    openTagModal(id, currentTags, (newTags) => {
      chat.tags = newTags;
      chat.updatedAt = Date.now();
      saveChats();
      renderHistory();
    });
  };

  const selectChat = (id) => {
    currentChatId = id;
    const chat = chats.find(c => c.id === id);
    if (!chat) return;

    saveChats();
    renderHistory();
    
    // Ocultar welcome e renderizar as mensagens
    welcomeContainer.style.display = 'none';
    conversationList.innerHTML = '';

    chat.messages.forEach(msg => {
      appendMessageUI(msg.role, msg.content, msg.media);
    });

    scrollToBottom();
  };

  const createNewChat = () => {
    if (isGenerating) return;
    
    currentChatId = null;
    localStorage.removeItem('pedagog_current_chat_id');
    
    welcomeContainer.style.display = 'flex';
    conversationList.innerHTML = '';
    
    userInput.value = '';
    userInput.style.height = 'auto';
    btnSend.disabled = true;
    
    renderHistory();
  };

  const deleteChat = (id) => {
    chats = chats.filter(c => c.id !== id);
    if (currentChatId === id) {
      currentChatId = null;
      createNewChat();
    } else {
      saveChats();
      renderHistory();
    }
  };

  btnNewChat.addEventListener('click', createNewChat);
  btnNewChatMobile.addEventListener('click', createNewChat);

  // ==========================================================================
  // FLUXO DO CHAT & RENDERIZAÇÃO
  // ==========================================================================

  const appendMessageUI = (role, content, media = null) => {
    const isUser = role === 'user';
    const row = document.createElement('div');
    row.className = `message-row ${role}`;

    const avatarHtml = isUser
      ? `<div class="avatar user-avatar user-avatar-img-wrapper"><img src="${window.agentConfig?.userAvatarUrl || window.agentConfig?.camilaAvatarUrl || 'assets/pedagog_user.png'}" alt="Usuário" class="user-avatar-img"></div>`
      : `<div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.iaAvatarUrl || window.agentConfig?.kemilyAvatarUrl || 'assets/pedagog_ia.png'}" alt="${window.agentConfig?.agentName || 'PedagogIA'}" class="bot-avatar-img"></div>`;

    let contentHtml = '';
    if (isUser) {
      contentHtml = `<p>${escapeHtml(content).replace(/\n/g, '<br>')}</p>`;
    } else {
      if (media) {
        if (media.type === 'image') {
          contentHtml = `
            <div class="media-message-card">
              <div class="media-img-container">
                <img src="${media.url}" alt="Ilustração gerada" class="generated-image" onload="scrollToBottom()">
              </div>
              <p class="media-caption">✨ "${escapeHtml(media.originalPrompt)}"</p>
              <div class="media-actions-row">
                <a href="${media.url}" download="${getDownloadFileName('imagem', 'png')}" target="_blank" class="media-download-btn">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                  </svg>
                  <span>Salvar na Galeria</span>
                </a>
              </div>
            </div>
          `;
        } else if (media.type === 'audio') {
          const audioId = 'audio_' + Date.now() + '_' + Math.floor(Math.random() * 10000);
          contentHtml = `
            <div class="media-message-card">
              <div class="custom-audio-player">
                <audio src="${media.url}" id="${audioId}"></audio>
                <button class="audio-play-btn" onclick="toggleCustomAudio(this)" title="Ouvir música">
                  <svg class="play-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M8 5v14l11-7z"/>
                  </svg>
                  <svg class="pause-icon hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
                  </svg>
                </button>
                <div class="audio-timeline-container">
                  <div class="audio-timeline">
                    <div class="audio-progress"></div>
                  </div>
                </div>
                <span class="audio-time">0:00</span>
              </div>
              <p class="media-caption">🎵 "${escapeHtml(media.originalPrompt)}"</p>
              <div class="media-actions-row">
                <a href="${media.url}" download="${getDownloadFileName('musica', 'mp3')}" target="_blank" class="media-download-btn">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                  </svg>
                  <span>Baixar Música</span>
                </a>
              </div>
            </div>
          `;
        } else if (media.type === 'video') {
          contentHtml = `
            <div class="media-message-card">
              <div class="media-video-container">
                <video controls src="${media.url}" class="generated-video" preload="metadata"></video>
              </div>
              <p class="media-caption">🎥 "${escapeHtml(media.originalPrompt)}"</p>
              <div class="media-actions-row">
                <a href="${media.url}" download="${getDownloadFileName('video', 'mp4')}" target="_blank" class="media-download-btn">
                  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                  </svg>
                  <span>Salvar Vídeo</span>
                </a>
              </div>
            </div>
          `;
        }
      } else {
        if (content.trim().startsWith('<div class="media-message-card">')) {
          contentHtml = content;
        } else {
          contentHtml = marked.parse(content);
        }
      }
    }

    const actionsHtml = !isUser ? `
      <div class="message-actions">
        <button class="msg-action-btn btn-copy-msg" title="Copiar resposta" data-content="${media ? escapeHtml(content) : escapeHtml(content).replace(/"/g, '&quot;')}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75" />
          </svg>
          <span>Copiar</span>
        </button>
        <button class="msg-action-btn btn-regenerate" title="Regenerar resposta">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
          </svg>
          <span>Regenerar</span>
        </button>
        <button class="msg-action-btn btn-speak" title="Ouvir resposta" data-content="${media ? escapeHtml(content) : escapeHtml(content).replace(/"/g, '&quot;')}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" />
          </svg>
          <span>Ouvir</span>
        </button>
      </div>
    ` : `
      <div class="message-actions">
        <button class="msg-action-btn btn-edit" title="Editar e reenviar" data-content="${escapeHtml(content).replace(/"/g, '&quot;')}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
          </svg>
          <span>Editar</span>
        </button>
      </div>
    `;

    row.innerHTML = `
      <div class="message-icon">${avatarHtml}</div>
      <div class="message-content-wrapper">
        <div class="message-content">${contentHtml}</div>
        ${actionsHtml}
      </div>
    `;

    conversationList.appendChild(row);

    // Colorir blocos de código com Highlight.js
    row.querySelectorAll('pre code').forEach((block) => {
      hljs.highlightElement(block);
    });

    // Event listener para copiar mensagem
    const copyBtn = row.querySelector('.btn-copy-msg');
    if (copyBtn) {
      copyBtn.addEventListener('click', () => {
        const text = copyBtn.dataset.content;
        navigator.clipboard.writeText(text).then(() => {
          const span = copyBtn.querySelector('span');
          const original = span.textContent;
          span.textContent = 'Copiado!';
          setTimeout(() => span.textContent = original, 2000);
        });
      });
    }

    // Event listener para editar/reenviar mensagem
    const editBtn = row.querySelector('.btn-edit');
    if (editBtn) {
      editBtn.addEventListener('click', () => {
        const text = editBtn.dataset.content;
        const chat = chats.find(c => c.id === currentChatId);
        if (!chat) return;

        // Encontrar índice desta mensagem no chat
        const rows = conversationList.querySelectorAll('.message-row.user');
        let msgRow = null;
        for (const r of rows) {
          const btn = r.querySelector('.btn-edit');
          if (btn && btn.dataset.content === text) {
            msgRow = r;
            break;
          }
        }

        // Remover esta mensagem e todas as subsequentes (do user e do bot)
        if (msgRow) {
          const allRows = Array.from(conversationList.querySelectorAll('.message-row'));
          const idx = allRows.indexOf(msgRow);
          for (let i = allRows.length - 1; i >= idx; i--) {
            allRows[i].remove();
          }
          // Remover do estado também
          const msgIndex = chat.messages.findIndex(m => m.role === 'user' && m.content === text);
          if (msgIndex >= 0) {
            chat.messages = chat.messages.slice(0, msgIndex);
          }
          saveChats();
        }

        // Colocar texto no input e focar
        userInput.value = text;
        userInput.focus();
        userInput.dispatchEvent(new Event('input'));
        btnSend.disabled = false;
      });
    }

    // Event listener para ouvir resposta (TTS nativo)
    const speakBtn = row.querySelector('.btn-speak');
    if (speakBtn) {
      speakBtn.addEventListener('click', () => {
        const text = speakBtn.dataset.content;
        speakText(text, speakBtn);
      });
    }

    // Event listener para regenerar resposta
    const regenBtn = row.querySelector('.btn-regenerate');
    if (regenBtn) {
      regenBtn.addEventListener('click', () => {
        if (isGenerating) return;
        regenerateLastResponse();
      });
    }

    return row;
  };

  // Regenerar última resposta do bot
  const regenerateLastResponse = () => {
    const chat = chats.find(c => c.id === currentChatId);
    if (!chat || chat.messages.length === 0) return;

    // Encontrar última mensagem do bot
    let lastBotIdx = -1;
    for (let i = chat.messages.length - 1; i >= 0; i--) {
      if (chat.messages[i].role === 'assistant') {
        lastBotIdx = i;
        break;
      }
    }
    if (lastBotIdx === -1) return;

    // Remover última mensagem do bot e todas as mensagens depois da última mensagem do usuário
    let lastUserIdx = -1;
    for (let i = lastBotIdx - 1; i >= 0; i--) {
      if (chat.messages[i].role === 'user') {
        lastUserIdx = i;
        break;
      }
    }

    // Cortar mensagens até a última do usuário
    if (lastUserIdx >= 0) {
      chat.messages = chat.messages.slice(0, lastUserIdx + 1);
    } else {
      chat.messages = [];
    }

    // Remover da UI as mensagens depois do último user
    const rows = conversationList.querySelectorAll('.message-row');
    for (let i = rows.length - 1; i >= 0; i--) {
      const row = rows[i];
      const isBot = row.classList.contains('assistant');
      const isUser = row.classList.contains('user');
      if (isBot) {
        row.remove();
      } else if (isUser) {
        break;
      }
    }

    saveChats();
    scrollToBottom();

    // Reenviar última mensagem do usuário para gerar nova resposta
    const lastUserMsg = chat.messages[chat.messages.length - 1];
    if (lastUserMsg && lastUserMsg.role === 'user') {
      handleSendMessage(lastUserMsg.content, true);
    }
  };

  const scrollToBottom = () => {
    messagesContainer.scrollTop = messagesContainer.scrollHeight;
  };

  const getProgressSteps = (promptText) => {
    const promptLower = (promptText || '').toLowerCase();
    
    if (promptLower.includes('historia') || promptLower.includes('conto') || promptLower.includes('história') || promptLower.includes('escrever')) {
      return [
        { text: "Analisando a solicitação da professora...", progress: 15 },
        { text: "Esboçando o enredo e personagens infantis...", progress: 40 },
        { text: "Elaborando a história pedagógica...", progress: 70 },
        { text: "Fazendo sugestões para uso pedagógico...", progress: 90 }
      ];
    }
    
    if (promptLower.includes('relatorio') || promptLower.includes('relatório') || promptLower.includes('observa') || promptLower.includes('htpc')) {
      return [
        { text: "Analisando as observações pedagógicas...", progress: 15 },
        { text: "Sintetizando os avanços e interações...", progress: 40 },
        { text: "Estruturando os blocos do relatório individual...", progress: 65 },
        { text: "Refinando o texto e alinhando com a BNCC...", progress: 85 },
        { text: "Ajustando o tom formal-pedagógico...", progress: 95 }
      ];
    }
    
    if (promptLower.includes('planejamento') || promptLower.includes('aula') || promptLower.includes('atividade') || promptLower.includes('projeto') || promptLower.includes('brincar')) {
      return [
        { text: "Revisando os campos de experiência da BNCC...", progress: 20 },
        { text: "Estruturando os momentos da vivência lúdica...", progress: 45 },
        { text: "Definindo a intencionalidade educativa e mediação...", progress: 70 },
        { text: "Finalizando as comandas e recursos pedagógicos...", progress: 90 }
      ];
    }
    
    // Caso geral
    return [
      { text: "Analisando a solicitação...", progress: 20 },
      { text: "Processando as diretrizes pedagógicas...", progress: 45 },
      { text: "Elaborando a resposta...", progress: 75 },
      { text: "Refinando a formatação e estilo...", progress: 90 }
    ];
  };

  // Função principal de envio de mensagens
  const handleSendMessage = async (text, skipUserAppend = false, files = null, forcedIntent = null) => {
    if (!text && (!files || files.length === 0)) return;

    // Se não recebe files por parâmetro, usa os anexados globalmente
    const filesToSend = files || attachedFiles;
    let fullText = text || '';

    // Processar anexos: evitar base64 gigantesco em imagens e erro de leitura binária em PDF/DOCX
    if (filesToSend.length > 0) {
      for (const file of filesToSend) {
        if (file.type.startsWith('image/')) {
          // Apenas anexa uma referência textual limpa da imagem para a IA saber que ela existe
          fullText += `\n\n*[Imagem anexada: ${file.name} (${Math.round(file.size/1024)} KB)]*`;
        } else if (file.name.endsWith('.txt') || file.name.endsWith('.md') || file.name.endsWith('.json') || file.name.endsWith('.csv') || file.name.endsWith('.js') || file.name.endsWith('.css') || file.name.endsWith('.html')) {
          const reader = new FileReader();
          const content = await new Promise((resolve) => {
            reader.onload = (e) => resolve(e.target.result);
            reader.readAsText(file);
          });
          const truncated = content.length > 3000 ? content.substring(0, 3000) + '... [conteúdo truncado]' : content;
          fullText += `\n\n*[Conteúdo do arquivo "${file.name}":]*\n\`\`\`\n${truncated}\n\`\`\``;
        } else {
          // Para arquivos binários como PDF/DOCX que não podem ser lidos diretamente como texto cru no frontend
          fullText += `\n\n*[Arquivo anexado: ${file.name} (${Math.round(file.size/1024)} KB) - formato não textual]*`;
        }
      }
      // Limpar anexos após envio
      attachedFiles = [];
      if (attachPreview) {
        attachPreview.innerHTML = '';
        attachPreview.style.display = 'none';
        btnAttach.classList.remove('has-files');
      }
    }

    isGenerating = true;
    btnSend.disabled = true;
    userInput.disabled = true;
    userInput.value = '';
    userInput.style.height = 'auto';

    // Ocultar tela de boas-vindas se for a primeira mensagem
    if (welcomeContainer.style.display !== 'none') {
      welcomeContainer.style.display = 'none';
    }

    // Criar o chat se for novo
    if (!currentChatId) {
      const newId = 'chat_' + Date.now();
      const firstLine = fullText.split('\n')[0];
      const title = firstLine.length > 26 ? firstLine.substring(0, 26) + '...' : firstLine;
      
      chats.push({
        id: newId,
        title: title,
        tags: [],
        pinned: false,
        messages: [],
        createdAt: Date.now(),
        updatedAt: Date.now()
      });
      currentChatId = newId;
    }

    // Achar o chat atual no estado
    const chat = chats.find(c => c.id === currentChatId);
    if (!chat) return;

    // Adicionar mensagem do usuário no estado e na tela (pula se for regeneração)
    if (!skipUserAppend) {
      const userMsg = { role: 'user', content: fullText };
      chat.messages.push(userMsg);
      chat.updatedAt = Date.now();
      appendMessageUI('user', fullText);
      scrollToBottom();
      saveChats();
      renderHistory();
    }

    // Criar container para a resposta do bot (PedaGog) na tela
    const botRow = document.createElement('div');
    botRow.className = 'message-row assistant';
    
    botRow.innerHTML = `
      <div class="message-icon">
        <div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.iaAvatarUrl || window.agentConfig?.kemilyAvatarUrl || 'assets/pedagog_ia.png'}" alt="${window.agentConfig?.agentName || 'PedagogIA'}" class="bot-avatar-img"></div>
      </div>
      <div class="message-content-wrapper">
        <div class="message-content">
          <span class="typing-cursor"></span>
        </div>
      </div>
    `;
    conversationList.appendChild(botRow);
    scrollToBottom();

    const botContentDiv = botRow.querySelector('.message-content');
    let assistantContent = '';

    // Obter etapas de progresso personalizadas
    const progressSteps = getProgressSteps(fullText);
    let currentStepIdx = 0;
    
    // Renderizar barra de progresso inicial
    botContentDiv.innerHTML = `
      <div class="ia-progress-container" id="iaProgressContainer">
        <div class="ia-progress-header">
          <div class="ia-progress-icon"></div>
          <div class="ia-progress-step-text" id="iaProgressStepText">${progressSteps[0].text}</div>
        </div>
        <div class="ia-progress-bar">
          <div class="ia-progress-bar-fill" id="iaProgressBarFill" style="width: ${progressSteps[0].progress}%;"></div>
        </div>
      </div>
    `;
    scrollToBottom();

    // Fechar barra de prompt no mobile se estiver aberta para liberar espaço
    const mobilePromptBar = document.querySelector('.prompt-modes-bar');
    const mobileToggleBtn = document.getElementById('fabTools');
    if (mobilePromptBar && window.innerWidth <= 768) {
      mobilePromptBar.classList.remove('show');
      if (mobileToggleBtn) mobileToggleBtn.classList.remove('active');
    }

    // Iniciar timer para avançar as etapas
    let progressTimer = setInterval(() => {
      if (currentStepIdx < progressSteps.length - 1) {
        currentStepIdx++;
        const step = progressSteps[currentStepIdx];
        const stepTextEl = botContentDiv.querySelector('#iaProgressStepText');
        const barFillEl = botContentDiv.querySelector('#iaProgressBarFill');
        if (stepTextEl && barFillEl) {
          stepTextEl.textContent = step.text;
          barFillEl.style.width = `${step.progress}%`;
        }
      }
    }, 1500);

    try {
      // Filtrar mensagens para enviar apenas o histórico necessário ao OpenRouter, removendo dados base64 pesados de mídias
      const messagesPayload = chat.messages.map(m => {
        let cleanContent = m.content || '';
        if (cleanContent.includes('data:image/') || cleanContent.includes('data:audio/') || cleanContent.includes('data:video/')) {
          const typeLabel = cleanContent.includes('custom-audio-player') ? 'Áudio/Música' : (cleanContent.includes('media-video-container') ? 'Vídeo' : 'Imagem');
          cleanContent = `[Mídia gerada anteriormente: ${typeLabel}]`;
        }
        return { role: m.role, content: cleanContent };
      });

      // Fazer a chamada HTTP usando stream
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ messages: messagesPayload, forcedIntent: forcedIntent })
      });

      if (!response.ok) {
        throw new Error('Falha na resposta do servidor');
      }

      // Processar stream de dados (SSE)
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let buffer = '';
      let isMediaResponse = false;
      let mediaMsgData = null;

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        
        // Deixar a última parte inacabada no buffer
        buffer = lines.pop();

        for (const line of lines) {
          const cleanLine = line.trim();
          if (cleanLine.startsWith('data: ')) {
            const dataContent = cleanLine.slice(6);
            if (dataContent === '[DONE]') {
              continue;
            }
            try {
              const parsed = JSON.parse(dataContent);
              
              if (parsed.content) {
                assistantContent += parsed.content;
                // Mantemos o progresso visível sem renderizar o texto parcial
              } else if (parsed.type === 'media_status') {
                isMediaResponse = true;
                if (progressTimer) {
                  clearInterval(progressTimer);
                  progressTimer = null;
                }
                botContentDiv.innerHTML = `
                  <div class="media-loading">
                    <div class="media-spinner"></div>
                    <p class="media-loading-text">${escapeHtml(parsed.message)}</p>
                  </div>
                `;
                scrollToBottom();
              } else if (parsed.type === 'image') {
                isMediaResponse = true;
                if (progressTimer) {
                  clearInterval(progressTimer);
                  progressTimer = null;
                }
                mediaMsgData = { type: 'image', url: parsed.url, originalPrompt: parsed.originalPrompt };
                assistantContent = `
                  <div class="media-message-card">
                    <div class="media-img-container">
                      <img src="${parsed.url}" alt="Ilustração gerada" class="generated-image" onload="scrollToBottom()">
                    </div>
                    <p class="media-caption">✨ "${escapeHtml(parsed.originalPrompt)}"</p>
                    <div class="media-actions-row">
                      <a href="${parsed.url}" download="${getDownloadFileName('imagem', 'png')}" target="_blank" class="media-download-btn">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                          <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                        </svg>
                        <span>Salvar na Galeria</span>
                      </a>
                    </div>
                  </div>
                `;
                botContentDiv.innerHTML = assistantContent;
                scrollToBottom();
              } else if (parsed.type === 'error') {
                isMediaResponse = true;
                if (progressTimer) {
                  clearInterval(progressTimer);
                  progressTimer = null;
                }
                botContentDiv.innerHTML = `
                  <div class="message-row bot">
                    <div class="message-content">
                      <p style="color: red; font-weight: bold;">⚠️ Erro na geração: ${escapeHtml(parsed.message)}</p>
                    </div>
                  </div>
                `;
                scrollToBottom();
              } else if (parsed.type === 'audio') {
                isMediaResponse = true;
                if (progressTimer) {
                  clearInterval(progressTimer);
                  progressTimer = null;
                }
                mediaMsgData = { type: 'audio', url: parsed.url, originalPrompt: parsed.originalPrompt };
                const audioId = 'audio_' + Date.now();
                assistantContent = `
                  <div class="media-message-card">
                    <div class="custom-audio-player">
                      <audio src="${parsed.url}" id="${audioId}"></audio>
                      <button class="audio-play-btn" onclick="toggleCustomAudio(this)" title="Ouvir música">
                        <svg class="play-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M8 5v14l11-7z"/>
                        </svg>
                        <svg class="pause-icon hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
                          <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
                        </svg>
                      </button>
                      <div class="audio-timeline-container">
                        <div class="audio-timeline">
                          <div class="audio-progress"></div>
                        </div>
                      </div>
                      <span class="audio-time">0:00</span>
                    </div>
                    <p class="media-caption">🎵 "${escapeHtml(parsed.originalPrompt)}"</p>
                    <div class="media-actions-row">
                      <a href="${parsed.url}" download="${getDownloadFileName('musica', 'mp3')}" target="_blank" class="media-download-btn">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                          <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                        </svg>
                        <span>Baixar Música</span>
                      </a>
                    </div>
                  </div>
                `;
                botContentDiv.innerHTML = assistantContent;
                scrollToBottom();
              } else if (parsed.type === 'video') {
                isMediaResponse = true;
                if (progressTimer) {
                  clearInterval(progressTimer);
                  progressTimer = null;
                }
                mediaMsgData = { type: 'video', url: parsed.url, originalPrompt: parsed.originalPrompt };
                assistantContent = `
                  <div class="media-message-card">
                    <div class="media-video-container">
                      <video controls src="${parsed.url}" class="generated-video" preload="metadata"></video>
                    </div>
                    <p class="media-caption">🎥 "${escapeHtml(parsed.originalPrompt)}"</p>
                    <div class="media-actions-row">
                      <a href="${parsed.url}" download="${getDownloadFileName('video', 'mp4')}" target="_blank" class="media-download-btn">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
                          <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
                        </svg>
                        <span>Salvar Vídeo</span>
                      </a>
                    </div>
                  </div>
                `;
                botContentDiv.innerHTML = assistantContent;
                scrollToBottom();
              }
            } catch (err) {
              // Ignorar erros de JSON incompletos do buffer
            }
          }
        }
      }

      // Remover o cursor de digitação no final se não for mensagem de mídia
      const cursor = botContentDiv.querySelector('.typing-cursor');
      if (cursor) cursor.remove();

      if (progressTimer) {
        clearInterval(progressTimer);
        progressTimer = null;
      }

      // Remover blocos <think> nativos de modelos de reasoning antes de renderizar e extrair conhecimento
      assistantContent = assistantContent.replace(/<think>[\s\S]*?(?:<\/think>|$)/g, '').trim();

      // Parse final limpo do markdown (se for texto normal)
      if (!isMediaResponse) {
        const stepTextEl = botContentDiv.querySelector('#iaProgressStepText');
        const barFillEl = botContentDiv.querySelector('#iaProgressBarFill');
        if (stepTextEl && barFillEl) {
          stepTextEl.textContent = "Concluído com sucesso!";
          barFillEl.style.width = "100%";
        }
        // Aguardar um instante para o feedback visual de conclusão ser percebido
        await new Promise(resolve => setTimeout(resolve, 400));

        botContentDiv.innerHTML = marked.parse(assistantContent);
        botContentDiv.querySelectorAll('pre code').forEach((block) => {
          hljs.highlightElement(block);
        });
      }

      // Extrair e salvar conhecimento aprendido (tags [KNOWLEDGE: ...])
      window.extractAndSaveKnowledge(assistantContent);

      // Adicionar botões de ação (Copiar, Regenerar, Ouvir) após o streaming
      const escapedContent = escapeHtml(assistantContent).replace(/"/g, '&quot;');
      const actionsDiv = document.createElement('div');
      actionsDiv.className = 'message-actions';
      actionsDiv.innerHTML = `
        <button class="msg-action-btn btn-copy-msg" title="Copiar resposta" data-content="${escapedContent}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75" />
          </svg>
          <span>Copiar</span>
        </button>
        <button class="msg-action-btn btn-regenerate" title="Regenerar resposta">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
          </svg>
          <span>Regenerar</span>
        </button>
        <button class="msg-action-btn btn-speak" title="Ouvir resposta" data-content="${escapedContent}">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" />
          </svg>
          <span>Ouvir</span>
        </button>
      `;

      const wrapper = botRow.querySelector('.message-content-wrapper');
      wrapper.appendChild(actionsDiv);

      // Vincular listeners dos botões
      const copyBtn = actionsDiv.querySelector('.btn-copy-msg');
      copyBtn.addEventListener('click', () => {
        navigator.clipboard.writeText(assistantContent).then(() => {
          const span = copyBtn.querySelector('span');
          const original = span.textContent;
          span.textContent = 'Copiado!';
          setTimeout(() => span.textContent = original, 2000);
        });
      });

      const regenBtn = actionsDiv.querySelector('.btn-regenerate');
      regenBtn.addEventListener('click', () => {
        if (!isGenerating) regenerateLastResponse();
      });

      const speakBtn = actionsDiv.querySelector('.btn-speak');
      speakBtn.addEventListener('click', () => {
        speakText(assistantContent, speakBtn);
      });

      scrollToBottom();

      // AUTO-TTS: Se a mensagem veio do microfone, ler a resposta em voz alta automaticamente
      if (lastInputWasVoice && assistantContent && !isMediaResponse) {
        console.log('[VOZ] Mensagem veio do microfone — respondendo por voz automaticamente.');
        setTimeout(() => {
          speakText(assistantContent, speakBtn);
        }, 400);
      }
      lastInputWasVoice = false;

      // Salvar resposta no estado e localStorage
      const assistantMsg = { role: 'assistant', content: assistantContent };
      chat.messages.push(assistantMsg);
      chat.updatedAt = Date.now();
      saveChats();
      renderHistory();

    } catch (error) {
      console.error('Erro na resposta do chat:', error);
      if (progressTimer) {
        clearInterval(progressTimer);
        progressTimer = null;
      }
      const cursor = botContentDiv.querySelector('.typing-cursor');
      if (cursor) cursor.remove();
      
      botContentDiv.innerHTML = `
        <p style="color: var(--error); margin-top: 8px; font-size: 13.5px; display: flex; align-items: center; gap: 6px;">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" style="width: 16px; height: 16px;">
            <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
          </svg>
          Desculpe, ocorreu um erro ao obter resposta da PedaGog. Por favor, tente novamente.
        </p>
      `;
      scrollToBottom();
    } finally {
      isGenerating = false;
      btnSend.disabled = userInput.value.trim() === '';
      userInput.disabled = false;
      userInput.focus();
    }
  };

  // Envio pelo Formulário
  chatForm.addEventListener('submit', (e) => {
    e.preventDefault();
    const text = userInput.value.trim();
    handleSendMessage(text);
  });

  // Botões de Modos Rápidos de Prompt (Rodapé)
  document.querySelectorAll('.btn-prompt-mode').forEach(btn => {
    btn.addEventListener('click', () => {
      if (window.innerWidth <= 768) {
        if (promptModesBar) promptModesBar.classList.remove('show');
        if (fabTools) fabTools.classList.remove('active');
      }
      if (btn.dataset.prompt) {
        handleSendMessage(btn.dataset.prompt);
        return;
      }
      if (btn.dataset.fill) {
        userInput.value = btn.dataset.fill;
        userInput.focus();
        btnSend.disabled = false;
        return;
      }
      if (btn.id === 'barBtnEstudio') return; // Manipulado separadamente
      if (btn.id === 'barBtnComics') return; // Manipulado separadamente
      if (btn.id === 'barBtnMusica') return;
      if (btn.id === 'barBtnHistoria') return;
      if (btn.id === 'barBtnMindLab') return;
      
      const mode = btn.dataset.mode;
      const text = userInput.value.trim();
      
      let suggestion = "";
      let baseText = text;
      
      // Se o texto atual já for uma das sugestões padrão, limpamos para não duplicar
      const suggestionsList = [
        "Crie uma música pedagógica alegre e animada sobre ",
        "Crie um roteiro detalhado para um vídeo educativo sobre ",
        "Crie uma ilustração pedagógica com cores vibrantes mostrando ",
        "Escreva uma poesia infantil rimada e educativa sobre ",
        "Escreva uma história educativa infantil curta sobre "
      ];
      
      for (const sugg of suggestionsList) {
        if (baseText.startsWith(sugg)) {
          baseText = baseText.replace(sugg, "").trim();
          break;
        }
      }
      
      if (mode === 'AUDIO') {
        suggestion = "Crie uma música pedagógica alegre e animada sobre ";
      } else if (mode === 'VIDEO') {
        suggestion = "Crie um roteiro detalhado para um vídeo educativo sobre ";
      } else if (mode === 'IMAGE') {
        suggestion = "Crie uma ilustração pedagógica com cores vibrantes mostrando ";
      } else if (mode === 'POETRY') {
        suggestion = "Escreva uma poesia infantil rimada e educativa sobre ";
      } else if (mode === 'TEXT') {
        suggestion = "Escreva uma história educativa infantil curta sobre ";
      }
      
      userInput.value = suggestion + baseText;
      userInput.focus();
      
      // Mover cursor para o final do texto
      userInput.selectionStart = userInput.selectionEnd = userInput.value.length;
      
      // Ajustar altura do textarea para acomodar a sugestão
      userInput.style.height = 'auto';
      userInput.style.height = userInput.scrollHeight + 'px';
      if (btnSend) btnSend.disabled = false;
    });
  });

  // Sugestões de Prompt Rápidas
  suggestionCards.forEach(card => {
    card.addEventListener('click', () => {
      const prompt = card.dataset.prompt;
      if (prompt) {
        handleSendMessage(prompt);
      }
    });
  });

  // ==========================================================================
  // LOGOUT & INICIALIZAÇÃO
  // ==========================================================================

  btnLogout.addEventListener('click', async () => {
    try {
      const response = await fetch('/api/logout', {
        method: 'POST'
      });
      if (response.ok) {
        window.location.href = '/login';
      }
    } catch (error) {
      console.error('Erro ao fazer logout:', error);
    }
  });

  // Inicializar interface
  if (currentChatId) {
    // Tenta carregar o chat ativo
    const activeChat = chats.find(c => c.id === currentChatId);
    if (activeChat) {
      selectChat(currentChatId);
    } else {
      createNewChat();
    }
  } else {
    createNewChat();
  }

  // Inicializar reconhecimento de voz
  initVoiceRecognition();

  // ============================================================
  // SISTEMA DE OBSERVAÇÃO POR VOZ
  // ============================================================
  const recordModal = document.getElementById('recordModal');
  const fabRecord = document.getElementById('fabRecord');
  const btnExitRecord = document.getElementById('btnExitRecord');
  const btnStopRecord = document.getElementById('btnStopRecord');
  const recordStateRecording = document.getElementById('recordStateRecording');
  const recordStateProcessing = document.getElementById('recordStateProcessing');
  const recordStatePreview = document.getElementById('recordStatePreview');
  const recordTimer = document.getElementById('recordTimer');
  const reportContent = document.getElementById('reportContent');
  const previewDateTime = document.getElementById('previewDateTime');
  const btnDiscardReport = document.getElementById('btnDiscardReport');
  const btnSaveReport = document.getElementById('btnSaveReport');

  // Novos elementos de transcrição
  const recordStateTranscribed = document.getElementById('recordStateTranscribed');
  const transcriptionTextarea = document.getElementById('transcriptionTextarea');
  const btnDiscardTranscription = document.getElementById('btnDiscardTranscription');
  const btnAnalyzeTranscription = document.getElementById('btnAnalyzeTranscription');
  const recordProcessingText = document.getElementById('recordProcessingText');
  const recordProcessingSubtext = document.getElementById('recordProcessingSubtext');
// Variáveis de gravação
  let mediaRecorder = null;
  let audioChunks = [];
  let recordingStartTime = null;
  let timerInterval = null;
  let audioContext = null;
  let analyser = null;
  let frequencyData = null;
  let silenceFrames = 0;
  let totalFrames = 0;
  let vadCheckInterval = null;
  let generatedReport = null;
  let generatedCriancas = null;
  let generatedTurma = 'não informada';
  let generatedTags = [];

  // Fechar modal - colocada no topo para evitar problemas de inicialização
  function closeRecordModal() {
    if (mediaRecorder && mediaRecorder.state !== 'inactive') {
      try {
        mediaRecorder.stop();
      } catch (e) {}
      if (mediaRecorder.stream) {
        mediaRecorder.stream.getTracks().forEach(t => t.stop());
      }
    }
    clearInterval(timerInterval);
    clearInterval(vadCheckInterval);
    if (audioContext) { audioContext.close(); audioContext = null; }
    if (analyser) { analyser = null; frequencyData = null; }
    audioChunks = [];
    generatedReport = null;
    recordModal.style.display = 'none';
  }

  // Função para controlar a exibição dos estados
  function showRecordState(state) {
    recordStateRecording.style.display = 'none';
    recordStateProcessing.style.display = 'none';
    if (recordStateTranscribed) recordStateTranscribed.style.display = 'none';
    recordStatePreview.style.display = 'none';

    if (state === 'recording') {
      recordStateRecording.style.display = 'flex';
    } else if (state === 'processing') {
      recordStateProcessing.style.display = 'flex';
    } else if (state === 'transcribed') {
      if (recordStateTranscribed) recordStateTranscribed.style.display = 'flex';
    } else if (state === 'preview') {
      recordStatePreview.style.display = 'flex';
    }
  }

  // Abrir modal e iniciar gravação
  if (fabRecord) {
    fabRecord.addEventListener('click', async () => {
      audioChunks = [];
      generatedReport = null;

      // Mostra estado inicial (gravando)
      showRecordState('recording');
      recordModal.style.display = 'flex';

      // Inicia timer
      recordingStartTime = Date.now();
      timerInterval = setInterval(updateTimer, 1000);
      updateTimer();

      // Solicita permissão e inicia gravação
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
        let options = {};
        if (typeof MediaRecorder.isTypeSupported === 'function') {
          if (MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
            options = { mimeType: 'audio/webm;codecs=opus' };
          } else if (MediaRecorder.isTypeSupported('audio/webm')) {
            options = { mimeType: 'audio/webm' };
          } else if (MediaRecorder.isTypeSupported('audio/ogg')) {
            options = { mimeType: 'audio/ogg' };
          } else if (MediaRecorder.isTypeSupported('audio/mp4')) {
            options = { mimeType: 'audio/mp4' };
          }
        }
        // Configurar AudioContext para VAD
        audioContext = new AudioContext();
        const source = audioContext.createMediaStreamSource(stream);
        analyser = audioContext.createAnalyser();
        analyser.fftSize = 256;
        source.connect(analyser);
        frequencyData = new Uint8Array(analyser.frequencyBinCount);

        // Iniciar verificação de silêncio (VAD)
        silenceFrames = 0;
        totalFrames = 0;
        vadCheckInterval = setInterval(() => {
          if (!analyser) return;
          analyser.getByteFrequencyData(frequencyData);
          const avg = frequencyData.reduce((a, b) => a + b, 0) / frequencyData.length;
          totalFrames++;
          if (avg < 10) {
            silenceFrames++;
          } else {
            silenceFrames = Math.max(0, silenceFrames - 2); // recupera mais rápido
          }
          // Atualizar indicator visual
          const recordWaveform = document.getElementById('recordWaveform');
          if (recordWaveform && recordWaveform.children[0]) {
            const bars = recordWaveform.children;
            bars.forEach((bar) => {
              const h = Math.max(4, (avg / 255) * 50 + Math.random() * 10);
              bar.style.height = `${h}px`;
            });
          }
          // Se mais de 60% dos últimos 30 frames for silêncio, avisar
          if (totalFrames > 30 && (silenceFrames / 30) > 0.6) {
            const btnStopRecord = document.getElementById('btnStopRecord');
            if (btnStopRecord && !btnStopRecord.disabled) {
              btnStopRecord.style.borderColor = '#ff6b6b';
              btnStopRecord.title = 'Silêncio detectado - Clique se quiser parar';
            }
          } else {
            const btnStopRecord = document.getElementById('btnStopRecord');
            if (btnStopRecord) {
              btnStopRecord.style.borderColor = '';
              btnStopRecord.title = '';
            }
          }
        }, 100);

        mediaRecorder = new MediaRecorder(stream, options);

        mediaRecorder.ondataavailable = (e) => {
          if (e.data.size > 0) audioChunks.push(e.data);
        };

        mediaRecorder.start(100); // chunk a cada 100ms
      } catch (err) {
        console.error('Erro ao acessar microfone:', err);
        alert('Não foi possível acessar o microfone. Verifique as permissões.');
        closeRecordModal();
      }
    });
  }

  // Atualizar timer
  function updateTimer() {
    if (!recordingStartTime) return;
    const elapsed = Math.floor((Date.now() - recordingStartTime) / 1000);
    const mins = Math.floor(elapsed / 60).toString().padStart(2, '0');
    const secs = (elapsed % 60).toString().padStart(2, '0');
    recordTimer.textContent = `${mins}:${secs}`;
  }

  // Parar gravação e transcrever
  if (btnStopRecord) {
    btnStopRecord.addEventListener('click', async () => {
      if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        try {
          mediaRecorder.stop();
        } catch (e) {}
        if (mediaRecorder.stream) {
          mediaRecorder.stream.getTracks().forEach(t => t.stop());
        }
      }
      clearInterval(timerInterval);
      clearInterval(vadCheckInterval);
      if (audioContext) { audioContext.close(); audioContext = null; }
      if (analyser) { analyser = null; frequencyData = null; }

      // Mostra processando com texto de transcrição
      if (recordProcessingText) recordProcessingText.textContent = 'Transcrevendo áudio...';
      if (recordProcessingSubtext) recordProcessingSubtext.textContent = 'Aguarde a transcrição por Whisper';
      showRecordState('processing');

      // Envia áudio para servidor
      const blob = new Blob(audioChunks, { type: 'audio/webm' });
      const formData = new FormData();
      formData.append('audio', blob, 'recording.webm');

      try {
        const res = await fetch('/api/observacao/transcrever', {
          method: 'POST',
          body: formData
        });

        if (!res.ok) {
          const errData = await res.json();
          throw new Error(errData.error || 'Erro na transcrição');
        }

        const data = await res.json();
        
        // Exibe o texto transcrito na área de texto para edição
        if (transcriptionTextarea) {
          transcriptionTextarea.value = data.transcribedText || '';
        }
        
        showRecordState('transcribed');
      } catch (err) {
        console.error('Erro ao processar observação:', err);
        alert('Erro ao transcrever áudio: ' + err.message);
        closeRecordModal();
      }
    });
  }

  // Ação de analisar transcrição
  if (btnAnalyzeTranscription) {
    btnAnalyzeTranscription.addEventListener('click', async () => {
      const text = transcriptionTextarea ? transcriptionTextarea.value.trim() : '';
      if (!text || text.length < 5) {
        alert('Por favor, digite ou revise a transcrição (mínimo de 5 caracteres).');
        return;
      }

      // Mostra processando com texto de análise
      if (recordProcessingText) recordProcessingText.textContent = 'Analisando observação...';
      if (recordProcessingSubtext) recordProcessingSubtext.textContent = 'Gerando relatório pedagógico estruturado';
      showRecordState('processing');

      try {
        const turmaData = localStorage.getItem('pedagog_turma') || localStorage.getItem('camila_turma') || '[]';
        const res = await fetch('/api/observacao/analisar', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ transcribedText: text, turmaContext: JSON.parse(turmaData) })
        });

        if (!res.ok) {
          const errData = await res.json();
          throw new Error(errData.error || 'Erro na análise');
        }

        const data = await res.json();
        generatedReport = data.relatorio || data.report;
        generatedCriancas = data.criancas;
        generatedTurma = data.turma || 'não informada';
        generatedTags = data.tags || [];
        showReportPreview(data);
      } catch (err) {
        console.error('Erro ao analisar observação:', err);
        alert('Erro ao analisar observação: ' + err.message);
        showRecordState('transcribed');
      }
    });
  }

  // Ação de descartar transcrição
  if (btnDiscardTranscription) {
    btnDiscardTranscription.addEventListener('click', () => {
      closeRecordModal();
    });
  }

  // Mostrar prévia do relatório
  function showReportPreview(data) {
    showRecordState('preview');

    const now = new Date();
    previewDateTime.textContent = now.toLocaleString('pt-BR', {
      day: '2-digit', month: '2-digit', year: 'numeric',
      hour: '2-digit', minute: '2-digit'
    });

    // Monta HTML com metadados
    const criancasHtml = data.criancas && data.criancas.length
      ? `<div class="report-meta-item"><span class="meta-label">👧 Crianças:</span> ${data.criancas.join(', ')}</div>`
      : `<div class="report-meta-item"><span class="meta-label">👧 Crianças:</span> <em>não identificadas</em></div>`;
    const tagsHtml = data.tags && data.tags.length
      ? `<div class="report-meta-item"><span class="meta-label">🏷️ Tags:</span> ${data.tags.map(t => `<span class="tag-chip">${t}</span>`).join(' ')}</div>`
      : '';
    const turmaHtml = data.turma && data.turma !== 'não informada'
      ? `<div class="report-meta-item"><span class="meta-label">🏫 Turma:</span> ${data.turma}</div>`
      : '';

    reportContent.innerHTML = `
      <div class="report-meta">${criancasHtml}${turmaHtml}${tagsHtml}</div>
      <hr style="border-color: var(--border-light); margin: 12px 0;">
      ${marked.parse(generatedReport || 'Relatório não disponível.')}
    `;
    reportContent.querySelectorAll('pre code').forEach(b => hljs.highlightElement(b));
  }

  // Descartar relatório
  if (btnDiscardReport) {
    btnDiscardReport.addEventListener('click', () => {
      generatedReport = null;
      closeRecordModal();
    });
  }

  // Salvar relatório
  if (btnSaveReport) {
    btnSaveReport.addEventListener('click', async () => {
      if (!generatedReport) return;
      btnSaveReport.disabled = true;
      btnSaveReport.textContent = 'Salvando...';

      try {
        const res = await fetch('/api/observacao/salvar', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            report: generatedReport,
            criancas: generatedCriancas,
            turma: generatedTurma,
            tags: generatedTags
          })
        });
        const data = await res.json();
        if (data.success) {
          alert('Relatório salvo com sucesso!');
        } else {
          alert('Erro ao salvar: ' + (data.error || 'desconhecido'));
        }
      } catch (err) {
        console.error('Erro ao salvar:', err);
        alert('Erro ao salvar o relatório.');
      } finally {
        btnSaveReport.disabled = false;
        btnSaveReport.textContent = 'Salvar';
        closeRecordModal();
      }
    });
  }

  // Sair / descartar
  if (btnExitRecord) {
    btnExitRecord.addEventListener('click', closeRecordModal);
  }

  // Fechar clicando fora
  if (recordModal) {
    recordModal.addEventListener('click', (e) => {
      if (e.target === recordModal) closeRecordModal();
    });
  }

  // ============================================================
  // MODAL: MINHAS OBSERVAÇÕES
  // ============================================================
  const obsModal = document.getElementById('obsModal');
  const btnObservacoes = document.getElementById('btnObservacoes');
  const btnObsEspeciais = document.getElementById('btnObsEspeciais');
  const btnCloseObsModal = document.getElementById('btnCloseObsModal');
  const obsModalTitle = document.getElementById('obsModalTitle');
  const obsList = document.getElementById('obsList');
  const obsFilterMes = document.getElementById('obsFilterMes');
  const obsFilterTag = document.getElementById('obsFilterTag');
  const obsSearchCrianca = document.getElementById('obsSearchCrianca');

  let allObservations = [];
  let isSpecialObsMode = false;

  // Abrir modal de observações
  if (btnObservacoes) {
    btnObservacoes.addEventListener('click', async () => {
      isSpecialObsMode = false;
      if (obsModalTitle) obsModalTitle.textContent = '📒 Minhas Observações';
      obsModal.style.display = 'flex';
      obsList.innerHTML = '<div class="obs-empty">Carregando...</div>';

      try {
        const res = await fetch('/api/observacoes');
        const data = await res.json();
        allObservations = data.observations || [];
        populateMonthFilter();
        renderObsList();
      } catch (err) {
        console.error('Erro ao carregar observações:', err);
        obsList.innerHTML = '<div class="obs-empty">Erro ao carregar observações.</div>';
      }
    });
  }

  // Abrir modal de observações Especiais
  if (btnObsEspeciais) {
    btnObsEspeciais.addEventListener('click', async () => {
      isSpecialObsMode = true;
      if (obsModalTitle) obsModalTitle.textContent = '📒 Observações Educação Especial';
      obsModal.style.display = 'flex';
      obsList.innerHTML = '<div class="obs-empty">Carregando...</div>';

      try {
        const res = await fetch('/api/observacoes');
        const data = await res.json();
        allObservations = data.observations || [];
        populateMonthFilter();
        renderObsList();
      } catch (err) {
        console.error('Erro ao carregar observações:', err);
        obsList.innerHTML = '<div class="obs-empty">Erro ao carregar observações.</div>';
      }
    });
  }

  // Fechar modal
  if (btnCloseObsModal) {
    btnCloseObsModal.addEventListener('click', () => {
      obsModal.style.display = 'none';
    });
  }
  if (obsModal) {
    obsModal.addEventListener('click', (e) => {
      if (e.target === obsModal) obsModal.style.display = 'none';
    });
  }

  // Filtros
  if (obsFilterMes) obsFilterMes.addEventListener('change', renderObsList);
  if (obsFilterTag) obsFilterTag.addEventListener('change', renderObsList);
  if (obsSearchCrianca) obsSearchCrianca.addEventListener('input', renderObsList);

  // Preenche select de meses
  function populateMonthFilter() {
    if (!obsFilterMes) return;
    const months = [...new Set(allObservations.map(o => o.date?.slice(0, 7)))]
      .filter(Boolean).sort().reverse();
    obsFilterMes.innerHTML = '<option value="">Todos os meses</option>' +
      months.map(m => `<option value="${m}">${m.split('-')[1]}/${m.split('-')[0]}</option>`).join('');
  }

  // Renderiza lista filtrada
  function renderObsList() {
    if (!obsList) return;
    const mes = obsFilterMes?.value || '';
    const tag = obsFilterTag?.value || '';
    const search = obsSearchCrianca?.value.toLowerCase() || '';

    let especialKidsNames = [];
    if (isSpecialObsMode) {
      const turma = JSON.parse(localStorage.getItem('pedagog_turma') || localStorage.getItem('camila_turma') || '[]');
      especialKidsNames = turma.filter(c => c.especial).map(c => (c.nome || '').toLowerCase().trim()).filter(Boolean);
      if (especialKidsNames.length === 0) {
        obsList.innerHTML = '<div class="obs-empty">Nenhuma criança com "Educação Especial" cadastrada na Minha Turma.</div>';
        return;
      }
    }

    const filtered = allObservations.filter(o => {
      if (mes && !o.date?.startsWith(mes)) return false;
      if (tag && !o.tags?.includes(tag)) return false;
      
      const nomes = (o.criancas || []).join(' ').toLowerCase();
      
      if (isSpecialObsMode) {
        // Must contain at least one special kid's name
        const preview = (o.preview || '').toLowerCase();
        const isEspecial = especialKidsNames.some(ekn => nomes.includes(ekn) || preview.includes(ekn));
        if (!isEspecial) return false;
      }

      if (search) {
        if (!nomes.includes(search) && !(o.preview || '').toLowerCase().includes(search)) return false;
      }
      return true;
    });

    if (filtered.length === 0) {
      obsList.innerHTML = '<div class="obs-empty">Nenhuma observação encontrada.</div>';
      return;
    }

    obsList.innerHTML = filtered.map(o => {
      const tagsHtml = (o.tags || []).map(t => `<span class="obs-tag">${t}</span>`).join('');
      const criancasHtml = (o.criancas || []).map(c => `<span class="obs-crianca">${c}</span>`).join('');
      const dateFormatted = o.date ? o.date.split('-').reverse().join('/') : '';
      return `
        <div class="obs-item" data-filename="${o.filename}" data-yearmonth="${o.date?.slice(0, 7)}">
          <div class="obs-item-header">
            <strong>📋 ${dateFormatted}${o.time ? ' às ' + o.time : ''}</strong>
            ${o.turma && o.turma !== 'não informada' ? `<span class="obs-crianca">🏫 ${o.turma}</span>` : ''}
          </div>
          <div class="obs-item-preview">${o.preview || 'Sem prévia disponível.'}</div>
          <div class="obs-item-footer">${tagsHtml}${criancasHtml}</div>
        </div>
      `;
    }).join('');

    // Click para abrir observação
    obsList.querySelectorAll('.obs-item').forEach(item => {
      item.addEventListener('click', async () => {
        const ym = item.dataset.yearmonth;
        const fn = item.dataset.filename;
        if (!ym || !fn) return;
        try {
          const res = await fetch(`/api/observacoes/${ym}/${fn}`);
          const text = await res.text();
          showObsDetail(text);
        } catch (err) {
          console.error('Erro ao carregar observação:', err);
        }
      });
    });
  };

  // ============================================================
  // MODAL: MINHA TURMA (COM MÚLTIPLAS TURMAS E SUPABASE)
  // ============================================================
  const minhaTurmaModal = document.getElementById('minhaTurmaModal');
  const btnMinhaTurma = document.getElementById('btnMinhaTurma');
  const btnCloseMinhaTurmaModal = document.getElementById('btnCloseMinhaTurmaModal');
  
  // Turmas List & Form
  const turmasList = document.getElementById('turmasList');
  const btnCreateTurma = document.getElementById('btnCreateTurma');
  const btnCancelTurma = document.getElementById('btnCancelTurma');
  const btnSaveTurmaConfig = document.getElementById('btnSaveTurmaConfig');
  const configTurmaId = document.getElementById('configTurmaId');
  const configTurmaNome = document.getElementById('configTurmaNome');
  const configTurmaSala = document.getElementById('configTurmaSala');
  const configTurmaPeriodo = document.getElementById('configTurmaPeriodo');
  const configTurmaProfTitular = document.getElementById('configTurmaProfTitular');
  const configTurmaProfAux1 = document.getElementById('configTurmaProfAux1');
  const configTurmaProfAux2 = document.getElementById('configTurmaProfAux2');
  const configTurmaCuidadora = document.getElementById('configTurmaCuidadora');
  const turmaFormTitle = document.getElementById('turmaFormTitle');

  // Alunos List & Form
  const filterAlunosTurma = document.getElementById('filterAlunosTurma');
  const childrenList = document.getElementById('childrenList');
  const btnCreateChild = document.getElementById('btnCreateChild');
  const btnCancelChild = document.getElementById('btnCancelChild');
  const btnSaveChild = document.getElementById('btnSaveChild');
  const childFormTitle = document.getElementById('childFormTitle');
  const cFormId = document.getElementById('childFormId');
  const cFormTurma = document.getElementById('childFormTurma');
  const cFormNome = document.getElementById('childFormNome');
  const cFormApelido = document.getElementById('childFormApelido');
  const cFormDataNasc = document.getElementById('childFormDataNasc');
  const cFormEspecial = document.getElementById('childFormEspecial');
  const divEspecialDetalhes = document.getElementById('divEspecialDetalhes');
  const cFormEspecialDetalhes = document.getElementById('childFormEspecialDetalhes');
  const cFormPais = document.getElementById('childFormPais');
  const cFormAutorizados = document.getElementById('childFormAutorizados');

  // Tabs
  const tabTurmaConfig = document.getElementById('tabTurmaConfig');
  const tabTurmaAlunos = document.getElementById('tabTurmaAlunos');
  const turmaConfigSection = document.getElementById('turmaConfigSection');
  const turmaAlunosSection = document.getElementById('turmaAlunosSection');

  let currentTurmas = [];
  let currentAlunos = [];

  // API Calls
  const fetchTurmas = async () => {
    try {
      const res = await fetch('/api/turmas');
      currentTurmas = await res.json();
      populateTurmaSelects();
      return currentTurmas;
    } catch(e) { console.error(e); return []; }
  };

  const fetchAlunos = async () => {
    try {
      const res = await fetch('/api/alunos');
      currentAlunos = await res.json();
      localStorage.setItem('pedagog_turma', JSON.stringify(currentAlunos));
      return currentAlunos;
    } catch(e) { console.error(e); return []; }
  };

  const populateTurmaSelects = () => {
    const opts = '<option value="">Todas as Turmas</option>' + currentTurmas.map(t => `<option value="${t.id}">${t.nome}</option>`).join('');
    if(filterAlunosTurma) filterAlunosTurma.innerHTML = opts;
    const formOpts = '<option value="">Selecione uma turma...</option>' + currentTurmas.map(t => `<option value="${t.id}">${t.nome}</option>`).join('');
    if(cFormTurma) cFormTurma.innerHTML = formOpts;
    if(document.getElementById('emitirFilterTurma')) {
      document.getElementById('emitirFilterTurma').innerHTML = '<option value="">Todas as turmas</option>' + currentTurmas.map(t => `<option value="${t.id}">${t.nome}</option>`).join('');
    }
  };

  // Tabs Logic
  if (tabTurmaConfig) {
    tabTurmaConfig.addEventListener('click', () => {
      tabTurmaConfig.classList.add('active');
      tabTurmaConfig.style.borderBottomColor = 'var(--brand-green)';
      tabTurmaConfig.style.color = 'var(--brand-green)';
      tabTurmaAlunos.classList.remove('active');
      tabTurmaAlunos.style.borderBottomColor = 'transparent';
      tabTurmaAlunos.style.color = 'var(--text-secondary)';
      turmaConfigSection.style.display = 'flex';
      turmaAlunosSection.style.display = 'none';
    });
  }
  if (tabTurmaAlunos) {
    tabTurmaAlunos.addEventListener('click', () => {
      tabTurmaAlunos.classList.add('active');
      tabTurmaAlunos.style.borderBottomColor = 'var(--brand-green)';
      tabTurmaAlunos.style.color = 'var(--brand-green)';
      tabTurmaConfig.classList.remove('active');
      tabTurmaConfig.style.borderBottomColor = 'transparent';
      tabTurmaConfig.style.color = 'var(--text-secondary)';
      turmaAlunosSection.style.display = 'flex';
      turmaConfigSection.style.display = 'none';
    });
  }

  // Turmas Logic
  const clearTurmaForm = () => {
    configTurmaId.value = '';
    configTurmaNome.value = '';
    configTurmaSala.value = '';
    configTurmaPeriodo.value = 'Integral';
    configTurmaProfTitular.value = '';
    configTurmaProfAux1.value = '';
    configTurmaProfAux2.value = '';
    configTurmaCuidadora.value = '';
    turmaFormTitle.textContent = 'Cadastrar Turma';
  };

  const renderTurmasList = () => {
    if(!turmasList) return;
    if(currentTurmas.length === 0) {
      turmasList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Nenhuma turma cadastrada.</div>';
      return;
    }
    turmasList.innerHTML = currentTurmas.map(t => `
      <div style="background: var(--bg-secondary); border: 1px solid var(--border-light); padding: 12px; border-radius: 8px; display: flex; justify-content: space-between; align-items: center;">
        <div>
          <div style="font-weight: 600; color: var(--text-primary);">${escapeHtml(t.nome)}</div>
          <div style="font-size: 0.8rem; color: var(--text-secondary);">${t.periodo || ''} ${t.sala ? '- ' + t.sala : ''}</div>
        </div>
        <div style="display: flex; gap: 8px;">
          <button onclick="editTurma('${t.id}')" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px;" title="Editar">✏️</button>
          <button onclick="deleteTurma('${t.id}')" style="background: none; border: none; color: #ef4444; cursor: pointer; padding: 4px;" title="Excluir">🗑️</button>
        </div>
      </div>
    `).join('');
  };

  window.editTurma = (id) => {
    const t = currentTurmas.find(x => x.id === id);
    if(!t) return;
    configTurmaId.value = t.id;
    configTurmaNome.value = t.nome || '';
    configTurmaSala.value = t.sala || '';
    configTurmaPeriodo.value = t.periodo || 'Integral';
    configTurmaProfTitular.value = t.prof_titular || '';
    configTurmaProfAux1.value = t.prof_aux1 || '';
    configTurmaProfAux2.value = t.prof_aux2 || '';
    configTurmaCuidadora.value = t.cuidadora || '';
    turmaFormTitle.textContent = 'Editar Turma';
  };

  window.deleteTurma = async (id) => {
    const isOk = await showCustomConfirm('Excluir Turma', 'Deseja excluir esta turma? Todos os alunos associados a ela também serão excluídos.', true);
    if(isOk) {
      await fetch('/api/turmas/' + id, { method: 'DELETE' });
      await fetchTurmas();
      await fetchAlunos();
      renderTurmasList();
      renderAlunosList();
      clearTurmaForm();
    }
  };

  if(btnCreateTurma) btnCreateTurma.addEventListener('click', clearTurmaForm);
  if(btnCancelTurma) btnCancelTurma.addEventListener('click', clearTurmaForm);

  if (btnSaveTurmaConfig) {
    btnSaveTurmaConfig.addEventListener('click', async () => {
      const nome = configTurmaNome.value.trim();
      if(!nome) { showCustomAlert('Aviso', 'O Nome da Turma é obrigatório.'); return; }
      
      const body = {
        nome,
        sala: configTurmaSala.value,
        periodo: configTurmaPeriodo.value,
        profTitular: configTurmaProfTitular.value,
        profAux1: configTurmaProfAux1.value,
        profAux2: configTurmaProfAux2.value,
        cuidadora: configTurmaCuidadora.value
      };

      const id = configTurmaId.value;
      const url = id ? '/api/turmas/' + id : '/api/turmas';
      const method = id ? 'PUT' : 'POST';

      try {
        const res = await fetch(url, {
          method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body)
        });
        if(res.ok) {
          showCustomAlert('Sucesso', 'Turma salva com sucesso!');
          await fetchTurmas();
          renderTurmasList();
          clearTurmaForm();
        } else {
          showCustomAlert('Erro', 'Falha ao salvar turma.');
        }
      } catch(e) { console.error(e); }
    });
  }

  // Alunos Logic
  const clearChildForm = () => {
    cFormId.value = '';
    cFormTurma.value = filterAlunosTurma ? filterAlunosTurma.value : '';
    cFormNome.value = '';
    cFormApelido.value = '';
    cFormDataNasc.value = '';
    cFormEspecial.checked = false;
    cFormEspecialDetalhes.value = '';
    divEspecialDetalhes.style.display = 'none';
    cFormPais.value = '';
    cFormAutorizados.value = '';
    childFormTitle.textContent = 'Cadastrar Criança';
  };

  if (cFormEspecial) {
    cFormEspecial.addEventListener('change', () => {
      divEspecialDetalhes.style.display = cFormEspecial.checked ? 'flex' : 'none';
    });
  }

  const renderAlunosList = () => {
    if (!childrenList) return;
    const filterTurmaId = filterAlunosTurma ? filterAlunosTurma.value : '';
    let filtered = currentAlunos;
    if(filterTurmaId) {
      filtered = currentAlunos.filter(a => a.turma_id === filterTurmaId);
    }
    
    if (filtered.length === 0) {
      childrenList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Nenhuma criança encontrada.</div>';
      return;
    }
    
    filtered.sort((a, b) => (a.nome || '').localeCompare(b.nome || ''));

    childrenList.innerHTML = filtered.map(c => {
      const turmaObj = currentTurmas.find(t => t.id === c.turma_id);
      const turmaNome = turmaObj ? turmaObj.nome : 'Sem turma';
      return `
      <div style="background: var(--bg-secondary); border: 1px solid var(--border-light); padding: 12px; border-radius: 8px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px;">
        <div>
          <div style="font-weight: 600; color: var(--text-primary);">${escapeHtml(c.nome)} ${c.especial ? '⭐' : ''}</div>
          <div style="font-size: 0.8rem; color: var(--text-secondary);">${escapeHtml(turmaNome)} ${c.apelido ? '- ' + escapeHtml(c.apelido) : ''}</div>
        </div>
        <div style="display: flex; gap: 6px; align-items: center;">
          <button onclick="viewChildTimeline('${c.id}')" style="background: rgba(59,130,246,0.12); border: 1px solid rgba(59,130,246,0.3); color: #60a5fa; cursor: pointer; padding: 4px 8px; border-radius: 6px; font-size: 0.75rem; font-weight: 600;" title="Ver Linha do Tempo e Dossiê">🔍 Dossiê</button>
          <button onclick="editChild('${c.id}')" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px;" title="Editar">✏️</button>
          <button onclick="deleteChild('${c.id}')" style="background: none; border: none; color: #ef4444; cursor: pointer; padding: 4px;" title="Excluir">🗑️</button>
        </div>
      </div>
    `}).join('');
  };

  if(filterAlunosTurma) {
    filterAlunosTurma.addEventListener('change', () => {
      renderAlunosList();
      if(cFormTurma) cFormTurma.value = filterAlunosTurma.value;
    });
  }

  window.editChild = (id) => {
    const c = currentAlunos.find(x => x.id === id);
    if (!c) return;
    
    cFormId.value = c.id;
    cFormTurma.value = c.turma_id || '';
    cFormNome.value = c.nome || '';
    cFormApelido.value = c.apelido || '';
    if(c.data_nasc) {
      cFormDataNasc.value = c.data_nasc.split('T')[0];
    } else {
      cFormDataNasc.value = '';
    }
    cFormEspecial.checked = !!c.especial;
    cFormEspecialDetalhes.value = c.especial_detalhes || '';
    divEspecialDetalhes.style.display = c.especial ? 'flex' : 'none';
    cFormPais.value = c.pais || '';
    cFormAutorizados.value = c.autorizados || '';
    
    childFormTitle.textContent = 'Editar Criança';
  };

  window.deleteChild = async (id) => {
    const isOk = await showCustomConfirm('Excluir', 'Deseja excluir esta criança? Isso não removerá as observações já feitas.', true);
    if (isOk) {
      await fetch('/api/alunos/' + id, { method: 'DELETE' });
      await fetchAlunos();
      renderAlunosList();
      clearChildForm();
    }
  };

  if (btnMinhaTurma) {
    btnMinhaTurma.addEventListener('click', async () => {
      minhaTurmaModal.style.display = 'flex';
      await fetchTurmas();
      await fetchAlunos();
      renderTurmasList();
      renderAlunosList();
      clearTurmaForm();
      clearChildForm();
    });
  }

  if (btnCloseMinhaTurmaModal) btnCloseMinhaTurmaModal.addEventListener('click', () => minhaTurmaModal.style.display = 'none');
  if (minhaTurmaModal) {
    minhaTurmaModal.addEventListener('click', (e) => {
      if (e.target === minhaTurmaModal) minhaTurmaModal.style.display = 'none';
    });
  }

  if (btnCreateChild) btnCreateChild.addEventListener('click', clearChildForm);
  if (btnCancelChild) btnCancelChild.addEventListener('click', clearChildForm);

  if (btnSaveChild) {
    btnSaveChild.addEventListener('click', async () => {
      if (!cFormNome.value.trim() || !cFormTurma.value) {
        showCustomAlert('Aviso', 'O Nome da Criança e a Turma são obrigatórios.');
        return;
      }
      
      const id = cFormId.value;
      const body = {
        turma_id: cFormTurma.value,
        nome: cFormNome.value.trim(),
        apelido: cFormApelido.value.trim(),
        data_nasc: cFormDataNasc.value || null,
        especial: cFormEspecial.checked,
        especial_detalhes: cFormEspecialDetalhes.value.trim(),
        pais: cFormPais.value.trim(),
        autorizados: cFormAutorizados.value.trim()
      };

      const url = id ? '/api/alunos/' + id : '/api/alunos';
      const method = id ? 'PUT' : 'POST';

      try {
        const res = await fetch(url, {
          method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body)
        });
        if(res.ok) {
          await fetchAlunos();
          renderAlunosList();
          clearChildForm();
          showCustomAlert('Sucesso', 'Criança salva com sucesso!');
        } else {
          showCustomAlert('Erro', 'Falha ao salvar criança.');
        }
      } catch(e) { console.error(e); }
    });
  }

  // Preencher com Voz
  const btnVoiceRecordChild = document.getElementById('btnVoiceRecordChild');
  if (btnVoiceRecordChild && (window.SpeechRecognition || window.webkitSpeechRecognition)) {
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    const formRecognition = new SpeechRecognition();
    formRecognition.lang = 'pt-BR';
    formRecognition.continuous = false;
    formRecognition.interimResults = false;

    formRecognition.onstart = () => {
      btnVoiceRecordChild.innerHTML = '🛑 Gravando... (Clique para parar)';
      btnVoiceRecordChild.style.background = 'rgba(239, 68, 68, 0.1)';
      btnVoiceRecordChild.style.color = '#ef4444';
      btnVoiceRecordChild.style.borderColor = '#ef4444';
    };

    formRecognition.onresult = async (event) => {
      const transcript = event.results[0][0].transcript;
      btnVoiceRecordChild.innerHTML = '⏳ Processando com IA...';
      
      try {
        const response = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            messages: [{
              role: 'user', 
              content: `A professora ditou as seguintes informações para cadastrar uma criança na turma: "${transcript}". 
Por favor, extraia os dados e retorne APENAS um JSON válido com os seguintes campos:
"nome", "apelido", "data_nasc" (formato YYYY-MM-DD), "especial" (boolean), "especial_detalhes", "pais", "autorizados". 
Se algum dado não for mencionado, deixe a string vazia ou false para boolean.`
            }],
            temperature: 0.1
          })
        });
        
        if (response.ok) {
          const data = await response.json();
          const assistantReply = data.message;
          const match = assistantReply.match(/```json\n([\s\S]*?)\n```/) || assistantReply.match(/\{[\s\S]*\}/);
          if (match) {
            const parsed = JSON.parse(match[1] || match[0]);
            if (parsed.nome) cFormNome.value = parsed.nome;
            if (parsed.apelido) cFormApelido.value = parsed.apelido;
            if (parsed.data_nasc) cFormDataNasc.value = parsed.data_nasc;
            if (parsed.especial) cFormEspecial.checked = parsed.especial;
            divEspecialDetalhes.style.display = cFormEspecial.checked ? 'flex' : 'none';
            if (parsed.especial_detalhes) cFormEspecialDetalhes.value = parsed.especial_detalhes;
            if (parsed.pais) cFormPais.value = parsed.pais;
            if (parsed.autorizados) cFormAutorizados.value = parsed.autorizados;
          }
        }
      } catch (err) {
        console.error('Erro ao processar voz:', err);
        showCustomAlert('Erro', 'Não foi possível extrair os dados. Tente novamente ou preencha manualmente.');
      }
    };

    formRecognition.onend = () => {
      btnVoiceRecordChild.innerHTML = '🎤 Preencher com Voz';
      btnVoiceRecordChild.style.background = 'rgba(16, 163, 127, 0.1)';
      btnVoiceRecordChild.style.color = 'var(--brand-green)';
      btnVoiceRecordChild.style.borderColor = 'var(--brand-green)';
    };

    btnVoiceRecordChild.addEventListener('click', () => {
      if (btnVoiceRecordChild.innerHTML.includes('Gravando')) {
        formRecognition.stop();
      } else {
        formRecognition.start();
      }
    });
  }

  // Mostra detalhe da observação em modal
  const showObsDetail = (mdText) => {
    const modal = document.createElement('div');
    modal.className = 'settings-modal';
    modal.style.display = 'flex';
    modal.innerHTML = `
      <div class="settings-modal-content obs-modal-content" style="max-width: 680px;">
        <div class="settings-modal-header">
          <h3>📋 Observação</h3>
          <button class="btn-close-modal" onclick="this.closest('.settings-modal').remove()">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
              <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
        <div style="padding: 20px; overflow-y: auto; max-height: 70vh;">
          <div class="obs-detail-content" style="color: var(--text-primary); line-height: 1.6;">
            ${marked.parse(mdText.replace(/^---[\s\S]*?---\n/, ''))}
          </div>
          <div style="margin-top: 16px; display: flex; gap: 8px;">
            <button class="btn-save-report" onclick="navigator.clipboard.writeText(this.closest('.settings-modal').querySelector('.obs-detail-content').innerText).then(()=>alert('Copiado!'))">Copiar Texto</button>
            <button class="btn-discard" onclick="this.closest('.settings-modal').remove()">Fechar</button>
          </div>
        </div>
      </div>
    `;
    document.body.appendChild(modal);
    modal.addEventListener('click', (e) => {
      if (e.target === modal) modal.remove();
    });
  };

  // // ============================================================
  // CRUD DE MODELOS DE RELATÓRIO
  // ============================================================
  const modelosRelatorioModal = document.getElementById('modelosRelatorioModal');
  const btnModelosRelatorio = document.getElementById('btnModelosRelatorio');
  const btnCloseModelosModal = document.getElementById('btnCloseModelosModal');
  const templatesList = document.getElementById('templatesList');
  const btnCreateTemplate = document.getElementById('btnCreateTemplate');
  const btnCancelTemplate = document.getElementById('btnCancelTemplate');
  const btnSaveTemplate = document.getElementById('btnSaveTemplate');
  
  const templateFormId = document.getElementById('templateFormId');
  const templateFormNome = document.getElementById('templateFormNome');
  const templateFormFinalidade = document.getElementById('templateFormFinalidade');
  const templateFormPeriodicidade = document.getElementById('templateFormPeriodicidade');
  const templateFormEstrutura = document.getElementById('templateFormEstrutura');
  const templateFormTitle = document.getElementById('templateFormTitle');

  let allTemplates = [];

  // Abrir modal de modelos
  if (btnModelosRelatorio) {
    btnModelosRelatorio.addEventListener('click', async () => {
      modelosRelatorioModal.style.display = 'flex';
      clearTemplateForm();
      await fetchTemplates();
    });
  }

  // Fechar modal de modelos
  if (btnCloseModelosModal) {
    btnCloseModelosModal.addEventListener('click', () => {
      modelosRelatorioModal.style.display = 'none';
    });
  }
  if (modelosRelatorioModal) {
    modelosRelatorioModal.addEventListener('click', (e) => {
      if (e.target === modelosRelatorioModal) modelosRelatorioModal.style.display = 'none';
    });
  }

  // Buscar modelos do backend
  async function fetchTemplates() {
    templatesList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Carregando...</div>';
    try {
      const res = await fetch('/api/modelos');
      allTemplates = await res.json();
      renderTemplatesList();
    } catch (err) {
      console.error('Erro ao buscar modelos:', err);
      templatesList.innerHTML = '<div style="color: #ff6b6b; text-align: center; padding: 20px;">Erro ao carregar modelos.</div>';
    }
  }

  // Renderizar a lista de modelos na esquerda
  function renderTemplatesList() {
    if (allTemplates.length === 0) {
      templatesList.innerHTML = '<div style="color: var(--text-secondary); text-align: center; padding: 20px;">Nenhum modelo cadastrado.</div>';
      return;
    }
    templatesList.innerHTML = allTemplates.map(t => `
      <div class="obs-item" style="padding: 10px; margin: 0 0 8px 0; cursor: pointer; border-left: 3px solid var(--brand-green); display: flex; flex-direction: column; gap: 4px; background: var(--bg-secondary); border-radius: 8px;" data-id="${t.id}">
        <div style="font-weight: 600; color: var(--text-primary); font-size: 0.9rem;">${t.nome}</div>
        <div style="font-size: 0.75rem; color: var(--text-secondary);">${t.periodicidade} • ${t.finalidade || 'Sem finalidade'}</div>
        <div style="display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px;">
          <button class="template-duplicate-btn" data-id="${t.id}" style="background: none; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 2px 8px; border-radius: 4px; font-size: 0.72rem; cursor: pointer; transition: opacity 0.2s;">Duplicar</button>
          <button class="template-edit-btn" data-id="${t.id}" style="background: none; border: 1px solid var(--border-light); color: var(--brand-green); padding: 2px 8px; border-radius: 4px; font-size: 0.72rem; cursor: pointer;">Editar</button>
          <button class="template-delete-btn" data-id="${t.id}" style="background: none; border: 1px solid var(--border-light); color: #ff6b6b; padding: 2px 8px; border-radius: 4px; font-size: 0.72rem; cursor: pointer;">Excluir</button>
        </div>
      </div>
    `).join('');

    // Eventos de clique na lista para editar/deletar/duplicar
    templatesList.querySelectorAll('.obs-item').forEach(item => {
      item.addEventListener('click', (e) => {
        if (e.target.tagName === 'BUTTON') return;
        const id = item.dataset.id;
        const template = allTemplates.find(t => t.id == id);
        if (template) fillTemplateForm(template);
      });
    });

    templatesList.querySelectorAll('.template-duplicate-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const id = btn.dataset.id;
        const template = allTemplates.find(t => t.id == id);
        if (template) {
          fillTemplateForm(template);
          templateFormId.value = '';
          templateFormNome.value = template.nome + ' (Cópia)';
          templateFormTitle.textContent = 'Duplicar Modelo';
          if (templateFormNome) templateFormNome.focus();
        }
      });
    });

    templatesList.querySelectorAll('.template-edit-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const id = btn.dataset.id;
        const template = allTemplates.find(t => t.id == id);
        if (template) fillTemplateForm(template);
      });
    });

    templatesList.querySelectorAll('.template-delete-btn').forEach(btn => {
      btn.addEventListener('click', async (e) => {
        e.stopPropagation();
        const id = btn.dataset.id;
        const template = allTemplates.find(t => t.id == id);
        if (!template) return;
        if (confirm(`Tem certeza que deseja excluir o modelo "${template.nome}"?`)) {
          try {
            const res = await fetch(`/api/modelos/${id}`, { method: 'DELETE' });
            if (res.ok) {
              alert('Modelo excluído com sucesso!');
              clearTemplateForm();
              await fetchTemplates();
            } else {
              const err = await res.json();
              alert('Erro ao excluir: ' + err.error);
            }
          } catch (err) {
            console.error('Erro ao excluir modelo:', err);
          }
        }
      });
    });
  }

  // Preencher formulário de edição
  function fillTemplateForm(template) {
    templateFormId.value = template.id;
    templateFormNome.value = template.nome;
    templateFormFinalidade.value = template.finalidade || '';
    templateFormPeriodicidade.value = template.periodicidade || 'Semanal';
    templateFormEstrutura.value = template.estrutura || '';
    templateFormTitle.textContent = 'Editar Modelo';
  }

  // Limpar formulário
  function clearTemplateForm() {
    templateFormId.value = '';
    templateFormNome.value = '';
    templateFormFinalidade.value = '';
    templateFormPeriodicidade.value = 'Semanal';
    templateFormEstrutura.value = '';
    templateFormTitle.textContent = 'Novo Modelo';
  }

  // Botão "Novo Modelo"
  if (btnCreateTemplate) {
    btnCreateTemplate.addEventListener('click', clearTemplateForm);
  }

  // Botão "Cancelar"
  if (btnCancelTemplate) {
    btnCancelTemplate.addEventListener('click', () => {
      clearTemplateForm();
      if (modelosRelatorioModal) modelosRelatorioModal.style.display = 'none';
    });
  }

  // Botão "Salvar Modelo"
  if (btnSaveTemplate) {
    btnSaveTemplate.addEventListener('click', async () => {
      const id = templateFormId.value;
      const nome = templateFormNome.value.trim();
      const finalidade = templateFormFinalidade.value.trim();
      const periodicidade = templateFormPeriodicidade.value;
      const estrutura = templateFormEstrutura.value.trim();

      if (!nome || !estrutura) {
        alert('Nome e estrutura do modelo são obrigatórios.');
        return;
      }

      const body = { nome, finalidade, periodicidade, estrutura };
      const url = id ? `/api/modelos/${id}` : '/api/modelos';
      const method = id ? 'PUT' : 'POST';

      try {
        const res = await fetch(url, {
          method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(body)
        });
        if (res.ok) {
          alert('Modelo salvo com sucesso!');
          clearTemplateForm();
          await fetchTemplates();
        } else {
          const err = await res.json();
          alert('Erro ao salvar modelo: ' + err.error);
        }
      } catch (err) {
        console.error('Erro ao salvar modelo:', err);
      }
    });
  }

  // ============================================================
  // GERAÇÃO / EMISSÃO DE RELATÓRIO PEDAGÓGICO
  // ============================================================
  const emitirRelatorioModal = document.getElementById('emitirRelatorioModal');
  const btnEmitirRelatorio = document.getElementById('btnEmitirRelatorio');
  const btnCloseEmitirModal = document.getElementById('btnCloseEmitirModal');
  
  const emitirFilterAno = document.getElementById('emitirFilterAno');
  const emitirFilterTurma = document.getElementById('emitirFilterTurma');
  const emitirFilterCrianca = document.getElementById('emitirFilterCrianca');
  const emitirFilterDataInicio = document.getElementById('emitirFilterDataInicio');
  const emitirFilterDataFim = document.getElementById('emitirFilterDataFim');
  const emitirTagsContainer = document.getElementById('emitirTagsContainer');
  const emitirFilterTemplate = document.getElementById('emitirFilterTemplate');
  let emitirSelectedTags = [];
  
  const emitirObsCountInfo = document.getElementById('emitirObsCountInfo');
  const btnGenerateCompiledReport = document.getElementById('btnGenerateCompiledReport');
  const emitirReportPreviewArea = document.getElementById('emitirReportPreviewArea');
  
  const btnExportDocx = document.getElementById('btnExportDocx');
  const btnExportPdf = document.getElementById('btnExportPdf');

  let activeCompiledReport = null; // Guarda o texto do relatório compilado ativo

  // Abrir modal de emissão
  if (btnEmitirRelatorio) {
    btnEmitirRelatorio.addEventListener('click', async () => {
      emitirRelatorioModal.style.display = 'flex';
      activeCompiledReport = null;
      emitirReportPreviewArea.innerHTML = `
        <div style="color: var(--text-secondary); text-align: center; margin-top: 50px;">
          Escolha uma criança e um modelo de relatório para começar.
        </div>
      `;
      btnExportDocx.disabled = true;
      btnExportDocx.style.cursor = 'not-allowed';
      btnExportDocx.style.borderColor = 'var(--border-light)';
      btnExportDocx.style.color = 'var(--text-secondary)';
      
      btnExportPdf.disabled = true;
      btnExportPdf.style.cursor = 'not-allowed';
      btnExportPdf.style.borderColor = 'var(--border-light)';
      btnExportPdf.style.color = 'var(--text-secondary)';
      
      emitirFilterDataInicio.value = '';
      emitirFilterDataFim.value = '';
      
      emitirSelectedTags = [];
      if (emitirTagsContainer) {
        emitirTagsContainer.querySelectorAll('.tag-pill').forEach(p => p.classList.remove('active'));
      }
      
      await loadFiltersData();
    });
  }

  // Fechar modal de emissão
  if (btnCloseEmitirModal) {
    btnCloseEmitirModal.addEventListener('click', () => {
      emitirRelatorioModal.style.display = 'none';
    });
  }
  if (emitirRelatorioModal) {
    emitirRelatorioModal.addEventListener('click', (e) => {
      if (e.target === emitirRelatorioModal) emitirRelatorioModal.style.display = 'none';
    });
  }

  // Buscar crianças com base nos filtros de Ano e Turma selecionados
  async function loadChildrenList() {
    try {
      const activeAno = emitirFilterAno ? emitirFilterAno.value : '';
      const activeTurma = emitirFilterTurma ? emitirFilterTurma.value : '';
      const activeCrianca = emitirFilterCrianca ? emitirFilterCrianca.value : '';
      
      let url = '/api/observacoes/criancas';
      const params = [];
      if (activeAno) params.push(`ano=${activeAno}`);
      if (activeTurma) params.push(`turma=${encodeURIComponent(activeTurma)}`);
      if (params.length > 0) url += '?' + params.join('&');
      
      const res = await fetch(url);
      const criancas = await res.json();
      emitirFilterCrianca.innerHTML = '<option value="">Selecione a criança</option>' +
        `<option value="todas" ${activeCrianca === 'todas' ? 'selected' : ''}>Todas as crianças (Relatório Global)</option>` +
        (Array.isArray(criancas) ? criancas : []).map(c => `<option value="${c}" ${c === activeCrianca ? 'selected' : ''}>${c}</option>`).join('');
    } catch (err) {
      console.error('Erro ao carregar lista de crianças:', err);
    }
  }

  // Carregar dados de filtros (anos, turmas, crianças e templates)
  async function loadFiltersData() {
    try {
      const activeAno = emitirFilterAno ? emitirFilterAno.value : '';
      const activeTurma = emitirFilterTurma ? emitirFilterTurma.value : '';
      
      const res = await fetch('/api/observacoes/metadata');
      const meta = await res.json();
      
      if (emitirFilterAno) {
        emitirFilterAno.innerHTML = '<option value="">Todos os anos</option>' +
          (meta.anos || []).map(y => `<option value="${y}" ${y === activeAno ? 'selected' : ''}>${y}</option>`).join('');
      }
      if (emitirFilterTurma) {
        emitirFilterTurma.innerHTML = '<option value="">Todas as turmas</option>' +
          (meta.turmas || []).map(t => `<option value="${t}" ${t === activeTurma ? 'selected' : ''}>${t}</option>`).join('');
      }
    } catch (err) {
      console.error('Erro ao buscar metadados de filtros:', err);
    }

    await loadChildrenList();

    try {
      const activeTemplate = emitirFilterTemplate ? emitirFilterTemplate.value : '';
      const res = await fetch('/api/modelos');
      const modelos = await res.json();
      emitirFilterTemplate.innerHTML = '<option value="">Selecione o modelo</option>' +
        (Array.isArray(modelos) ? modelos : []).map(m => `<option value="${m.id}" ${m.id == activeTemplate ? 'selected' : ''}>${m.nome}</option>`).join('');
    } catch (err) {
      console.error('Erro ao buscar modelos para filtros:', err);
    }

    updateObservationsCount();
  }

  // Ouvintes para atualizar contagem e filtros de criança
  if (emitirFilterAno) {
    emitirFilterAno.addEventListener('change', async () => {
      await loadChildrenList();
      updateObservationsCount();
    });
  }
  if (emitirFilterTurma) {
    emitirFilterTurma.addEventListener('change', async () => {
      await loadChildrenList();
      updateObservationsCount();
    });
  }

  [emitirFilterCrianca, emitirFilterDataInicio, emitirFilterDataFim, emitirFilterTemplate].forEach(el => {
    if (el) el.addEventListener('change', updateObservationsCount);
  });
  if (emitirFilterCrianca) {
    emitirFilterCrianca.addEventListener('input', updateObservationsCount);
  }

  // Adicionar ouvintes para as pills de tags
  if (emitirTagsContainer) {
    emitirTagsContainer.querySelectorAll('.tag-pill').forEach(pill => {
      pill.addEventListener('click', () => {
        const tag = pill.getAttribute('data-tag');
        if (pill.classList.contains('active')) {
          pill.classList.remove('active');
          emitirSelectedTags = emitirSelectedTags.filter(t => t !== tag);
        } else {
          pill.classList.add('active');
          emitirSelectedTags.push(tag);
        }
        updateObservationsCount();
      });
    });
  }

  // Recalcular quantidade de observações elegíveis
  async function updateObservationsCount() {
    const crianca = emitirFilterCrianca ? emitirFilterCrianca.value : '';
    const dataInicio = emitirFilterDataInicio ? emitirFilterDataInicio.value : '';
    const dataFim = emitirFilterDataFim ? emitirFilterDataFim.value : '';
    const tag = emitirSelectedTags.join(',');
    const modeloId = emitirFilterTemplate ? emitirFilterTemplate.value : '';
    const ano = emitirFilterAno ? emitirFilterAno.value : '';
    const turma = emitirFilterTurma ? emitirFilterTurma.value : '';

    if (!crianca || !modeloId) {
      emitirObsCountInfo.textContent = 'Escolha uma criança (ou "Todas") e um modelo para prosseguir.';
      btnGenerateCompiledReport.disabled = true;
      btnGenerateCompiledReport.style.opacity = '0.6';
      btnGenerateCompiledReport.style.cursor = 'not-allowed';
      return;
    }

    try {
      let url = `/api/observacoes/contar?crianca=${encodeURIComponent(crianca)}`;
      if (dataInicio) url += `&dataInicio=${dataInicio}`;
      if (dataFim) url += `&dataFim=${dataFim}`;
      if (tag) url += `&tags=${encodeURIComponent(tag)}`;
      if (ano) url += `&ano=${ano}`;
      if (turma) url += `&turma=${encodeURIComponent(turma)}`;

      const res = await fetch(url);
      const data = await res.json();
      const count = data.count || 0;

      if (count === 0) {
        emitirObsCountInfo.innerHTML = `⚠️ <span style="color: #ff6b6b; font-weight: 600;">Nenhuma observação</span> encontrada para esses filtros.`;
        btnGenerateCompiledReport.disabled = true;
        btnGenerateCompiledReport.style.opacity = '0.6';
        btnGenerateCompiledReport.style.cursor = 'not-allowed';
      } else {
        emitirObsCountInfo.innerHTML = `✨ <strong>${count}</strong> observações selecionadas para compilação.`;
        btnGenerateCompiledReport.disabled = false;
        btnGenerateCompiledReport.style.opacity = '1';
        btnGenerateCompiledReport.style.cursor = 'pointer';
      }
    } catch (err) {
      console.error('Erro ao contar observações:', err);
    }
  }

  // Gerar relatório consolidado com IA
  if (btnGenerateCompiledReport) {
    btnGenerateCompiledReport.addEventListener('click', async () => {
      const crianca = emitirFilterCrianca.value;
      const dataInicio = emitirFilterDataInicio.value;
      const dataFim = emitirFilterDataFim.value;
      const tags = emitirSelectedTags;
      const modeloId = emitirFilterTemplate.value;
      const ano = emitirFilterAno ? emitirFilterAno.value : '';
      const turma = emitirFilterTurma ? emitirFilterTurma.value : '';

      if (!crianca || !modeloId) return;

      emitirReportPreviewArea.innerHTML = `
        <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: 12px; margin-top: 50px;">
          <div style="width: 32px; height: 32px; border: 3px solid var(--border-light); border-top-color: var(--brand-green); border-radius: 50%; animation: spin 1s linear infinite;"></div>
          <div style="color: var(--text-secondary); font-size: 0.9rem; font-weight: 500;">Analisando observações e gerando relatório pedagógico...</div>
        </div>
      `;
      btnGenerateCompiledReport.disabled = true;
      btnGenerateCompiledReport.style.opacity = '0.6';

      try {
        const res = await fetch('/api/modelos/gerar-relatorio', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            crianca,
            dataInicio,
            dataFim,
            tags: tags.length > 0 ? tags : undefined,
            modeloId,
            ano,
            turma
          })
        });

        if (!res.ok) {
          const errData = await res.json();
          throw new Error(errData.error || 'Erro desconhecido');
        }

        const data = await res.json();
        activeCompiledReport = data;

        // Renderizar prévia do relatório em markdown
        emitirReportPreviewArea.innerHTML = `
          <div style="background: var(--bg-primary); padding: 12px; border-radius: 8px; margin-bottom: 16px; border: 1px solid var(--border-light); font-size: 0.85rem;">
            <div><strong>Estudante:</strong> ${data.crianca}</div>
            <div><strong>Período:</strong> ${data.periodo}</div>
            <div><strong>Modelo Aplicado:</strong> ${data.templateNome}</div>
            <div><strong>Quantidade de Observações Consolidadas:</strong> ${data.totalObservacoes}</div>
          </div>
          <div class="report-content-body" style="color: var(--text-primary);">
            ${marked.parse(data.report)}
          </div>
        `;

        // Ativar botões de exportação
        btnExportDocx.disabled = false;
        btnExportDocx.style.cursor = 'pointer';
        btnExportDocx.style.borderColor = 'var(--brand-green)';
        btnExportDocx.style.color = 'var(--brand-green)';
        
        btnExportPdf.disabled = false;
        btnExportPdf.style.cursor = 'pointer';
        btnExportPdf.style.borderColor = 'var(--brand-green)';
        btnExportPdf.style.color = 'var(--brand-green)';

        // Rolar suavemente até o relatório no mobile
        if (window.innerWidth <= 768) {
          const modalBody = emitirRelatorioModal.querySelector('.settings-modal-body');
          if (modalBody) {
            setTimeout(() => {
              modalBody.scrollTo({
                top: modalBody.scrollHeight,
                behavior: 'smooth'
              });
            }, 150);
          }
        }

      } catch (err) {
        console.error('Erro ao gerar relatório compilado:', err);
        emitirReportPreviewArea.innerHTML = `
          <div style="color: #ff6b6b; text-align: center; margin-top: 50px; font-weight: 500;">
            Erro ao gerar relatório: ${err.message}
          </div>
        `;
      } finally {
        btnGenerateCompiledReport.disabled = false;
        btnGenerateCompiledReport.style.opacity = '1';
      }
    });
  }

  // Exportar para DOCX (Formato HTML-DOCX)
  if (btnExportDocx) {
    btnExportDocx.addEventListener('click', () => {
      if (!activeCompiledReport) return;

      const htmlContent = `
        <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:office:word" xmlns="http://www.w3.org/TR/REC-html40">
        <head>
          <meta charset="utf-8">
          <title>Relatório Pedagógico - ${activeCompiledReport.crianca}</title>
          <style>
            body { font-family: Arial, sans-serif; line-height: 1.5; color: #333; }
            h1, h2, h3 { color: #1f2937; }
            .header-info { background-color: #f3f4f6; padding: 12px; border-radius: 6px; margin-bottom: 20px; border: 1px solid #e5e7eb; }
            .header-info div { margin-bottom: 4px; font-size: 11pt; }
          </style>
        </head>
        <body>
          <div class="header-info">
            <div><b>Estudante:</b> ${activeCompiledReport.crianca}</div>
            <div><b>Período:</b> ${activeCompiledReport.periodo}</div>
            <div><b>Modelo:</b> ${activeCompiledReport.templateNome}</div>
            <div><b>Quantidade de observações consolidadas:</b> ${activeCompiledReport.totalObservacoes}</div>
          </div>
          <hr/>
          ${marked.parse(activeCompiledReport.report)}
        </body>
        </html>
      `;

      const blob = new Blob(['\ufeff' + htmlContent], { type: 'application/msword' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `relatorio_${activeCompiledReport.crianca.replace(/\s+/g, '_')}_${Date.now()}.doc`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    });
  }

  // Exportar para PDF (Abre janela de impressão do navegador)
  if (btnExportPdf) {
    btnExportPdf.addEventListener('click', () => {
      if (!activeCompiledReport) return;

      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>Relatório Pedagógico - ${activeCompiledReport.crianca}</title>
          <style>
            body { font-family: 'Outfit', 'Inter', -apple-system, sans-serif; padding: 40px; color: #333; line-height: 1.6; }
            h1, h2, h3 { color: #1e293b; margin-top: 24px; margin-bottom: 12px; }
            h1 { border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; font-size: 22px; }
            h2 { font-size: 18px; border-bottom: 1px solid #f1f5f9; padding-bottom: 6px; }
            .meta-box { background: #f8fafc; padding: 16px; border-radius: 8px; margin-bottom: 24px; font-size: 14px; border: 1px solid #e2e8f0; }
            .meta-item { margin-bottom: 6px; display: flex; }
            .meta-label { font-weight: bold; color: #475569; width: 220px; }
            p { margin-bottom: 14px; text-align: justify; }
            ul, ol { margin-bottom: 14px; padding-left: 20px; }
            li { margin-bottom: 6px; }
            @media print {
              body { padding: 0; }
              button { display: none; }
            }
          </style>
        </head>
        <body>
          <h1>Relatório Pedagógico de Desenvolvimento</h1>
          <div class="meta-box">
            <div class="meta-item"><span class="meta-label">Estudante:</span> <span>${activeCompiledReport.crianca}</span></div>
            <div class="meta-item"><span class="meta-label">Período:</span> <span>${activeCompiledReport.periodo}</span></div>
            <div class="meta-item"><span class="meta-label">Modelo Aplicado:</span> <span>${activeCompiledReport.templateNome}</span></div>
            <div class="meta-item"><span class="meta-label">Quantidade de Observações:</span> <span>${activeCompiledReport.totalObservacoes}</span></div>
          </div>
          <div>${marked.parse(activeCompiledReport.report)}</div>
          <script>
            window.onload = function() {
              window.print();
              setTimeout(() => { window.close(); }, 500);
            };
          </script>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // ============================================================
  // ESTÚDIO MUSICAL (Criação de música cantada com MiniMax)
  // ============================================================
  const estudioMusicalModal = document.getElementById('estudioMusicalModal');
  const btnCloseEstudioModal = document.getElementById('btnCloseEstudioModal');
  const sidebarBtnEstudio = document.getElementById('sidebarBtnEstudio');
  const barBtnEstudio = document.getElementById('barBtnEstudio');
  const welcomeCardEstudio = document.getElementById('welcomeCardEstudio');

  const btnGenerateStudioMusic = document.getElementById('btnGenerateStudioMusic');
  const musicTemaInput = document.getElementById('musicTemaInput');
  const musicGenerateLoader = document.getElementById('musicGenerateLoader');
  const musicLoaderText = document.getElementById('musicLoaderText');
  const musicResultArea = document.getElementById('musicResultArea');
  const musicStudioAudioPlayer = document.getElementById('musicStudioAudioPlayer');
  const musicStudioDownloadBtn = document.getElementById('musicStudioDownloadBtn');
  const musicStudioLyricsArea = document.getElementById('musicStudioLyricsArea');
  const btnCopyMusicLyrics = document.getElementById('btnCopyMusicLyrics');
  const btnDownloadMusicLyrics = document.getElementById('btnDownloadMusicLyrics');

  let selectedVoice = 'mulher';
  let selectedRhythm = 'roda';
  let selectedDuration = '30s';

  // Toggle classes active para botões de opções de voz do Estúdio Musical
  document.querySelectorAll('#estudioMusicalModal .music-option-grid .btn-music-option').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('#estudioMusicalModal .music-option-grid .btn-music-option').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedVoice = btn.dataset.voice;
    });
  });

  document.querySelectorAll('.btn-music-rhythm').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-music-rhythm').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedRhythm = btn.dataset.rhythm;
    });
  });

  document.querySelectorAll('.btn-music-duration').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-music-duration').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedDuration = btn.dataset.duration;
    });
  });

  // Abrir e fechar modal
  const openEstudioModal = () => {
    estudioMusicalModal.style.display = 'flex';
    musicTemaInput.value = '';
    musicResultArea.style.display = 'none';
    musicStudioAudioPlayer.src = '';
    musicStudioLyricsArea.textContent = '';
    if (musicGenerateLoader) musicGenerateLoader.style.display = 'none';
    btnGenerateStudioMusic.disabled = false;
  };

  if (sidebarBtnEstudio) {
    sidebarBtnEstudio.addEventListener('click', openEstudioModal);
  }

  if (barBtnEstudio) {
    barBtnEstudio.addEventListener('click', openEstudioModal);
  }

  if (welcomeCardEstudio) {
    welcomeCardEstudio.addEventListener('click', openEstudioModal);
  }

  if (btnCloseEstudioModal) {
    btnCloseEstudioModal.addEventListener('click', () => {
      estudioMusicalModal.style.display = 'none';
      musicStudioAudioPlayer.pause();
    });
  }

  // Fechar modal clicando fora
  window.addEventListener('click', (e) => {
    if (e.target === estudioMusicalModal) {
      estudioMusicalModal.style.display = 'none';
      musicStudioAudioPlayer.pause();
    }
  });

  // Ação de gerar música no estúdio
  if (btnGenerateStudioMusic) {
    btnGenerateStudioMusic.addEventListener('click', async () => {
      const tema = musicTemaInput.value.trim();
      if (!tema) {
        alert('Por favor, digite um tema para a música.');
        return;
      }

      btnGenerateStudioMusic.disabled = true;
      musicGenerateLoader.style.display = 'flex';
      musicResultArea.style.display = 'none';
      
      const statusInterval = setInterval(() => {
        const statusMessages = [
          'Compondo a letra pedagógica...',
          'Ajustando a métrica e as rimas...',
          'Gerando o arranjo musical...',
          'Adicionando os vocais cantados...',
          'Quase pronto, finalizando o áudio...'
        ];
        const randomMsg = statusMessages[Math.floor(Math.random() * statusMessages.length)];
        musicLoaderText.textContent = randomMsg;
      }, 5000);

      try {
        const response = await fetch('/api/music/generate', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            tema,
            voz: selectedVoice,
            ritmo: selectedRhythm,
            duracao: selectedDuration
          })
        });

        clearInterval(statusInterval);

        if (!response.ok) {
          const errData = await response.json();
          throw new Error(errData.error || 'Erro na geração de áudio');
        }

        const data = await response.json();
        
        // Exibir resultados
        musicStudioLyricsArea.textContent = data.lyrics;
        musicStudioAudioPlayer.src = data.audioUrl;
        musicStudioDownloadBtn.href = data.audioUrl;
        
        musicGenerateLoader.style.display = 'none';
        musicResultArea.style.display = 'flex';

      } catch (err) {
        clearInterval(statusInterval);
        console.error('Erro ao gerar música no estúdio:', err);
        alert('Erro ao gerar música: ' + err.message);
        musicGenerateLoader.style.display = 'none';
        btnGenerateStudioMusic.disabled = false;
      }
    });
  }

  // Copiar letra
  if (btnCopyMusicLyrics) {
    btnCopyMusicLyrics.addEventListener('click', () => {
      const lyrics = musicStudioLyricsArea.textContent;
      if (lyrics) {
        navigator.clipboard.writeText(lyrics)
          .then(() => {
            btnCopyMusicLyrics.textContent = '✅ Copiado!';
            setTimeout(() => {
              btnCopyMusicLyrics.textContent = '📋 Copiar Letra';
            }, 2000);
          })
          .catch(err => {
            console.error('Falha ao copiar:', err);
          });
      }
    });
  }

  // Baixar letra em arquivo de texto (TXT)
  if (btnDownloadMusicLyrics) {
    btnDownloadMusicLyrics.addEventListener('click', () => {
      const lyrics = musicStudioLyricsArea.textContent;
      const tema = musicTemaInput.value.trim() || 'cantiga';
      if (lyrics) {
        const blob = new Blob([lyrics], { type: 'text/plain;charset=utf-8' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `letra_${tema.replace(/\s+/g, '_').toLowerCase()}.txt`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      }
    });
  }

  // =====================================
  // HISTÓRICO DO ESTÚDIO MUSICAL
  // =====================================
  const btnOpenEstudioHistory = document.getElementById('btnOpenEstudioHistory');
  const estudioHistoryModal = document.getElementById('estudioHistoryModal');
  const btnCloseEstudioHistory = document.getElementById('btnCloseEstudioHistory');
  const estudioHistoryList = document.getElementById('estudioHistoryList');

  if (btnOpenEstudioHistory) {
    btnOpenEstudioHistory.addEventListener('click', async () => {
      estudioHistoryModal.style.display = 'flex';
      estudioHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Carregando histórico...</div>';
      try {
        const res = await fetch('/api/music/list');
        const data = await res.json();
        estudioHistoryList.innerHTML = '';
        if (data.length === 0) {
          estudioHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Nenhuma canção salva ainda no estúdio.</div>';
          return;
        }
        data.forEach(item => {
          const div = document.createElement('div');
          div.style.background = 'var(--bg-tertiary)';
          div.style.padding = '12px 15px';
          div.style.borderRadius = '8px';
          div.style.display = 'flex';
          div.style.justifyContent = 'space-between';
          div.style.alignItems = 'center';
          div.innerHTML = `
            <div style="flex: 1; margin-right: 15px;">
              <div style="font-weight: 600; font-size: 0.95rem; color: var(--text-primary);">🎵 ${item.tema || 'Música'}</div>
              <div style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 4px;">Voz: ${item.voz} | Ritmo: ${item.ritmo}</div>
              <div style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 4px;">${new Date(item.created_at).toLocaleString()}</div>
            </div>
            <div style="display: flex; gap: 8px;">
              <button class="btn-ver-estudio btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px;">Ver/Ouvir</button>
              <button class="btn-del-estudio btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px; color: #ef4444; border-color: rgba(239, 68, 68, 0.3);">🗑️</button>
            </div>
          `;
          estudioHistoryList.appendChild(div);
        });

        document.querySelectorAll('.btn-ver-estudio').forEach(btn => {
          btn.addEventListener('click', async (e) => {
            const id = e.currentTarget.dataset.id;
            try {
              const res = await fetch(`/api/music/${id}`);
              const itemData = await res.json();
              
              musicStudioLyricsArea.textContent = itemData.letra;
              musicStudioAudioPlayer.src = itemData.audio_url;
              musicStudioDownloadBtn.href = itemData.audio_url;
              musicResultArea.style.display = 'flex';
              
              estudioHistoryModal.style.display = 'none';
            } catch (err) { alert('Erro ao carregar música do estúdio.'); }
          });
        });

        document.querySelectorAll('.btn-del-estudio').forEach(btn => {
          btn.addEventListener('click', async (e) => {
            if(!confirm('Tem certeza que deseja apagar esta canção?')) return;
            const id = e.currentTarget.dataset.id;
            try {
              await fetch(`/api/music/${id}`, { method: 'DELETE' });
              e.currentTarget.closest('div[style*="var(--bg-tertiary)"]').remove();
            } catch (err) { alert('Erro ao deletar.'); }
          });
        });

      } catch (err) {
        estudioHistoryList.innerHTML = '<div style="color: #ef4444; padding: 20px;">Erro ao carregar histórico.</div>';
      }
    });
  }

  if (btnCloseEstudioHistory) {
    btnCloseEstudioHistory.addEventListener('click', () => {
      estudioHistoryModal.style.display = 'none';
    });
  }


  // ============================================================
  // FÁBRICA DE QUADRINHOS (Criação de histórias visuais pedagógicas)
  // ============================================================
  const fabricaQuadrinhosModal = document.getElementById('fabricaQuadrinhosModal');
  const btnCloseComicsModal = document.getElementById('btnCloseComicsModal');
  const barBtnComics = document.getElementById('barBtnComics');
  
  const btnGenerateComics = document.getElementById('btnGenerateComics');
  const comicsTemaInput = document.getElementById('comicsTemaInput');
  const comicsGenerateLoader = document.getElementById('comicsGenerateLoader');
  const comicsLoaderText = document.getElementById('comicsLoaderText');
  const comicsLoaderProgress = document.getElementById('comicsLoaderProgress');
  
  const comicsResultArea = document.getElementById('comicsResultArea');
  const comicsResultTitle = document.getElementById('comicsResultTitle');
  const comicsGridContainer = document.getElementById('comicsGridContainer');

  const comicsCenarioSelect = document.getElementById('comicsCenarioSelect');
  const comicsCenarioCustomInput = document.getElementById('comicsCenarioCustomInput');

  // Export PDF / Vídeo
  const btnExportComicsPDFPortrait = document.getElementById('btnExportComicsPDFPortrait');
  const btnExportComicsPDFLandscape = document.getElementById('btnExportComicsPDFLandscape');
  const btnCompileComicsVideo = document.getElementById('btnCompileComicsVideo');
  const comicsVideoMusic = document.getElementById('comicsVideoMusic');
  const comicsVideoDuration = document.getElementById('comicsVideoDuration');
  const comicsVideoLoader = document.getElementById('comicsVideoLoader');
  const comicsVideoResult = document.getElementById('comicsVideoResult');
  const comicsVideoPlayer = document.getElementById('comicsVideoPlayer');
  const comicsVideoDownloadBtn = document.getElementById('comicsVideoDownloadBtn');

  const comicsProjectSelect = document.getElementById('comicsProjectSelect');
  const btnNewComicsProject = document.getElementById('btnNewComicsProject');
  const btnDeleteComicsProject = document.getElementById('btnDeleteComicsProject');
  const comicsProjectTitleInput = document.getElementById('comicsProjectTitleInput');
  const btnSaveComicsProject = document.getElementById('btnSaveComicsProject');
  const btnSaveNewComicsProject = document.getElementById('btnSaveNewComicsProject');

  let currentComicsProjectId = null;
  let currentComicsCharDescEnglish = '';
  let selectedComicsQty = 5;
  let selectedComicsBubbles = true;
  let selectedComicsRatio = '16:9';
  let generatedPanelsData = [];

  // Toggle ativo quantidade de quadros
  document.querySelectorAll('.btn-comics-qty').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-comics-qty').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedComicsQty = parseInt(btn.dataset.qty);
    });
  });

  // Toggle ativo falas/diálogos
  document.querySelectorAll('.btn-comics-bubbles').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-comics-bubbles').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedComicsBubbles = btn.dataset.bubbles === 'true';
    });
  });

  // Toggle ativo proporção visual
  document.querySelectorAll('.btn-comics-ratio').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-comics-ratio').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedComicsRatio = btn.dataset.ratio;
    });
  });

  // Gerenciador dinâmico de personagens
  const comicsCharListContainer = document.getElementById('comicsCharListContainer');
  const btnAddHumanChar = document.getElementById('btnAddHumanChar');
  const btnAddAnimalChar = document.getElementById('btnAddAnimalChar');

  const addCharacterRow = (type = '', name = '', isAnimal = false) => {
    const row = document.createElement('div');
    row.className = 'comic-char-row';
    row.style.cssText = 'display: flex; gap: 8px; align-items: center; background: var(--bg-primary); padding: 8px; border-radius: 8px; border: 1px solid var(--border-light);';

    const emoji = document.createElement('span');
    emoji.style.fontSize = '1.1rem';
    emoji.textContent = isAnimal ? '🐾' : '🧒';
    row.appendChild(emoji);

    const typeInput = document.createElement('input');
    typeInput.type = 'text';
    typeInput.className = 'obs-input char-type-input';
    typeInput.placeholder = isAnimal ? 'Tipo (ex: Gatinho, Leão)' : 'Tipo (ex: Menino, Menina)';
    typeInput.value = type;
    typeInput.style.cssText = 'flex: 1; padding: 6px 10px; font-size: 0.85rem; margin: 0;';
    row.appendChild(typeInput);

    const nameInput = document.createElement('input');
    nameInput.type = 'text';
    nameInput.className = 'obs-input char-name-input';
    nameInput.placeholder = 'Nome';
    nameInput.value = name;
    nameInput.style.cssText = 'flex: 1; padding: 6px 10px; font-size: 0.85rem; margin: 0;';
    row.appendChild(nameInput);

    const deleteBtn = document.createElement('button');
    deleteBtn.type = 'button';
    deleteBtn.className = 'btn-delete-char';
    deleteBtn.innerHTML = '&times;';
    deleteBtn.style.cssText = 'background: none; border: none; color: #ef4444; font-size: 1.3rem; cursor: pointer; padding: 0 4px; line-height: 1;';
    deleteBtn.addEventListener('click', () => {
      row.remove();
    });
    row.appendChild(deleteBtn);

    comicsCharListContainer.appendChild(row);
  };

  const btnImportTurmaChars = document.getElementById('btnImportTurmaChars');

  if (btnAddHumanChar) {
    btnAddHumanChar.addEventListener('click', () => {
      addCharacterRow('', '', false);
    });
  }

  if (btnAddAnimalChar) {
    btnAddAnimalChar.addEventListener('click', () => {
      addCharacterRow('', '', true);
    });
  }

  if (btnImportTurmaChars) {
    btnImportTurmaChars.addEventListener('click', async () => {
      try {
        btnImportTurmaChars.disabled = true;
        btnImportTurmaChars.textContent = '⏳ Carregando...';
        const res = await fetch('/api/alunos');
        if (!res.ok) throw new Error('Falha ao obter lista de alunos');
        const alunos = await res.json();
        if (!alunos || alunos.length === 0) {
          await showCustomAlert('Nenhum Aluno', 'Cadastre alunos na seção "Minha Turma" para importá-los automaticamente.');
          return;
        }

        // Adiciona os alunos como personagens (até 4 para manter a história focada)
        const selecionados = alunos.slice(0, 4);
        comicsCharListContainer.innerHTML = '';
        selecionados.forEach(aluno => {
          const generoProvavel = aluno.nome.trim().endsWith('a') ? 'Menina' : 'Menino';
          addCharacterRow(generoProvavel, aluno.nome.trim(), false);
        });
        await showCustomAlert('Turma Importada!', `${selecionados.length} alunos foram adicionados como personagens da história.`);
      } catch (err) {
        console.error('Erro ao importar alunos:', err);
        await showCustomAlert('Erro', 'Não foi possível carregar a lista de alunos: ' + err.message);
      } finally {
        btnImportTurmaChars.disabled = false;
        btnImportTurmaChars.textContent = '+ 🏫 Importar da Turma';
      }
    });
  }

  // Exibir/ocultar cenário personalizado
  if (comicsCenarioSelect) {
    comicsCenarioSelect.addEventListener('change', () => {
      if (comicsCenarioSelect.value === 'custom') {
        comicsCenarioCustomInput.style.display = 'block';
      } else {
        comicsCenarioCustomInput.style.display = 'none';
      }
    });
  }

  // --- GERENCIADOR DE PROJETOS DE HQ ---
  const startNewComicsProject = () => {
    currentComicsProjectId = null;
    currentComicsCharDescEnglish = '';
    
    const modeContainer = document.getElementById('comicsGenerationModeContainer');
    if (modeContainer) modeContainer.style.display = 'none';
    const radioNew = document.querySelector('input[name="comicsGenMode"][value="new_story"]');
    if (radioNew) radioNew.checked = true;
    
    if (comicsProjectSelect) comicsProjectSelect.value = '';
    if (comicsProjectTitleInput) comicsProjectTitleInput.value = '';
    if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'none';
    if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'none';
    
    comicsTemaInput.value = '';
    comicsResultArea.style.display = 'none';
    comicsGenerateLoader.style.display = 'none';
    comicsVideoResult.style.display = 'none';
    comicsVideoLoader.style.display = 'none';
    btnGenerateComics.disabled = false;
    if (comicsLoaderProgress) comicsLoaderProgress.style.width = '0%';
    
    // Set active state for default quick options
    selectedComicsQty = 5;
    document.querySelectorAll('.btn-comics-qty').forEach(b => {
      if (b.dataset.qty === '5') b.classList.add('active');
      else b.classList.remove('active');
    });
    
    selectedComicsBubbles = true;
    document.querySelectorAll('.btn-comics-bubbles').forEach(b => {
      if (b.dataset.bubbles === 'true') b.classList.add('active');
      else b.classList.remove('active');
    });
    
    selectedComicsRatio = '16:9';
    document.querySelectorAll('.btn-comics-ratio').forEach(b => {
      if (b.dataset.ratio === '16:9') b.classList.add('active');
      else b.classList.remove('active');
    });

    if (comicsCenarioSelect) {
      comicsCenarioSelect.value = 'no parque de diversões colorido';
      if (comicsCenarioCustomInput) {
        comicsCenarioCustomInput.style.display = 'none';
        comicsCenarioCustomInput.value = '';
      }
    }

    // Inicializar lista de personagens com padrão se estiver vazia
    comicsCharListContainer.innerHTML = '';
    addCharacterRow("Menino", "Lucas", false);
    addCharacterRow("Menina", "Mariana", false);
    
    generatedPanelsData = [];
    comicsGridContainer.innerHTML = '';
  };

  const loadComicsProjectsList = async () => {
    if (!comicsProjectSelect) return;
    try {
      const resp = await fetch('/api/comics/projects');
      if (!resp.ok) {
        console.warn('Projetos de quadrinhos temporariamente indisponíveis:', resp.status);
        return;
      }
      const projects = await resp.json();
      if (!Array.isArray(projects)) return;
      
      comicsProjectSelect.innerHTML = '<option value="">-- Carregar projeto salvo... --</option>';
      projects.forEach(proj => {
        const opt = document.createElement('option');
        opt.value = proj.id;
        opt.textContent = `${proj.titulo} (${new Date(proj.updated_at).toLocaleDateString('pt-BR')})`;
        comicsProjectSelect.appendChild(opt);
      });
      
      if (currentComicsProjectId) {
        comicsProjectSelect.value = currentComicsProjectId;
      }
    } catch (err) {
      console.warn('Aviso ao listar projetos:', err.message);
    }
  };

  const loadComicsProject = async (id) => {
    if (!id) {
      startNewComicsProject();
      return;
    }
    try {
      const resp = await fetch(`/api/comics/projects/${id}`);
      if (!resp.ok) {
        const errMsg = await safeExtractError(resp, 'Falha ao carregar projeto');
        throw new Error(errMsg);
      }
      const { project, panels } = await resp.json();
      
      currentComicsProjectId = project.id;
      currentComicsCharDescEnglish = project.character_description_english || '';
      
      const modeContainer = document.getElementById('comicsGenerationModeContainer');
      if (modeContainer) modeContainer.style.display = 'flex';
      
      if (comicsProjectTitleInput) comicsProjectTitleInput.value = project.titulo || '';
      comicsTemaInput.value = project.tema || '';
      
      if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'block';
      if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'block';
      
      // Carregar proporção
      selectedComicsRatio = project.proporcao || '16:9';
      document.querySelectorAll('.btn-comics-ratio').forEach(b => {
        if (b.dataset.ratio === selectedComicsRatio) b.classList.add('active');
        else b.classList.remove('active');
      });
      
      // Carregar cenário
      if (comicsCenarioSelect) {
        const standardOptions = ['no parque de diversões colorido', 'na sala de aula da escola infantil', 'em uma floresta encantada cheia de flores', 'no zoológico interagindo com animais', 'num jardim ensolarado de uma casa'];
        if (standardOptions.includes(project.cenario)) {
          comicsCenarioSelect.value = project.cenario;
          if (comicsCenarioCustomInput) comicsCenarioCustomInput.style.display = 'none';
        } else {
          comicsCenarioSelect.value = 'custom';
          if (comicsCenarioCustomInput) {
            comicsCenarioCustomInput.style.display = 'block';
            comicsCenarioCustomInput.value = project.cenario || '';
          }
        }
      }
      
      // Carregar quantidade e balões baseados nos painéis retornados
      selectedComicsQty = panels.length || 5;
      document.querySelectorAll('.btn-comics-qty').forEach(b => {
        if (parseInt(b.dataset.qty) === selectedComicsQty) b.classList.add('active');
        else b.classList.remove('active');
      });
      
      const hasDialogue = panels.some(p => p.dialogue);
      selectedComicsBubbles = hasDialogue;
      document.querySelectorAll('.btn-comics-bubbles').forEach(b => {
        if ((b.dataset.bubbles === 'true') === selectedComicsBubbles) b.classList.add('active');
        else b.classList.remove('active');
      });
      
      // Carregar personagens
      comicsCharListContainer.innerHTML = '';
      if (project.character_description_global) {
        try {
          const chars = JSON.parse(project.character_description_global);
          if (Array.isArray(chars)) {
            chars.forEach(c => {
              addCharacterRow(c.type || '', c.name || '', c.isAnimal || false);
            });
          }
        } catch (e) {
          addCharacterRow("Menino", "Lucas", false);
          addCharacterRow("Menina", "Mariana", false);
        }
      } else {
        addCharacterRow("Menino", "Lucas", false);
        addCharacterRow("Menina", "Mariana", false);
      }
      
      // Carregar os painéis
      generatedPanelsData = panels.map(p => ({
        panel_number: p.panel_number,
        imageUrl: p.image_url,
        dialogue: p.dialogue || '',
        image_prompt: p.image_prompt || ''
      }));
      
      if (generatedPanelsData.length > 0) {
        comicsResultTitle.textContent = project.titulo || 'História em Quadrinhos';
        comicsGridContainer.innerHTML = '';
        
        generatedPanelsData.forEach((panel, index) => {
          const panelCard = document.createElement('div');
          panelCard.className = 'comic-panel-card';
          
          const imgContainer = document.createElement('div');
          imgContainer.className = `comic-panel-image-container ratio-${selectedComicsRatio.replace(':', '-')}`;
          
          const img = document.createElement('img');
          img.className = 'comic-panel-image';
          img.src = panel.imageUrl;
          img.alt = `Quadro ${panel.panel_number}`;
          imgContainer.appendChild(img);
          
          const badge = document.createElement('div');
          badge.className = 'comic-panel-number-badge';
          badge.textContent = panel.panel_number;
          imgContainer.appendChild(badge);
          
          panelCard.appendChild(imgContainer);
          
          const caption = document.createElement('div');
          caption.className = 'comic-caption-text';
          
          const textarea = document.createElement('textarea');
          textarea.className = 'comic-caption-input';
          textarea.value = panel.dialogue || '';
          textarea.placeholder = 'Digite a fala ou legenda do quadrinho...';
          textarea.addEventListener('input', (e) => {
            panel.dialogue = e.target.value;
          });
          
          caption.appendChild(textarea);
          panelCard.appendChild(caption);
          
          comicsGridContainer.appendChild(panelCard);
        });
        
        comicsResultArea.style.display = 'flex';
      }
      
      comicsVideoResult.style.display = 'none';
      comicsVideoLoader.style.display = 'none';
      btnGenerateComics.disabled = false;
      
    } catch (err) {
      console.error(err);
      await showCustomAlert('Erro', 'Erro ao carregar projeto: ' + err.message);
    }
  };

  const saveComicsProjectFlow = async (forceNew = false) => {
    let titulo = comicsProjectTitleInput ? comicsProjectTitleInput.value.trim() : '';
    if (!titulo) {
      titulo = comicsResultTitle ? comicsResultTitle.textContent.trim() : 'Minha História em Quadrinhos';
    }
    
    const characters = [];
    document.querySelectorAll('.comic-char-row').forEach(row => {
      const type = row.querySelector('.char-type-input').value.trim();
      const name = row.querySelector('.char-name-input').value.trim();
      const isAnimal = row.querySelector('.comic-char-animal-toggle').classList.contains('active');
      if (type && name) {
        characters.push({ type, name, isAnimal });
      }
    });
    
    let cenario = comicsCenarioSelect ? comicsCenarioSelect.value : 'no parque de diversões colorido';
    if (cenario === 'custom' && comicsCenarioCustomInput) {
      cenario = comicsCenarioCustomInput.value.trim();
    }
    
    const targetId = forceNew ? null : currentComicsProjectId;
    
    const body = {
      id: targetId,
      titulo,
      tema: comicsTemaInput.value.trim(),
      cenario,
      proporcao: selectedComicsRatio,
      character_description_global: JSON.stringify(characters),
      character_description_english: currentComicsCharDescEnglish || '',
      panels: generatedPanelsData.map(p => ({
        panel_number: p.panel_number,
        image_url: p.imageUrl || p.image_url || '',
        image_prompt: p.image_prompt || '',
        dialogue: p.dialogue || ''
      }))
    };
    
    try {
      const resp = await fetch('/api/comics/projects', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      });
      
      if (!resp.ok) {
        const errMsg = await safeExtractError(resp, 'Erro ao salvar projeto');
        throw new Error(errMsg);
      }
      
      const data = await resp.json();
      currentComicsProjectId = data.id;
      await showCustomAlert('Sucesso', 'Projeto salvo com sucesso!');
      
      if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'block';
      if (btnSaveComicsProject) btnSaveComicsProject.style.display = 'block';
      await loadComicsProjectsList();
    } catch (err) {
      console.error(err);
      await showCustomAlert('Erro', 'Erro ao salvar projeto: ' + err.message);
    }
  };

  const saveComicsProject = () => saveComicsProjectFlow(false);
  const saveNewComicsProject = () => saveComicsProjectFlow(true);

  const deleteComicsProject = async () => {
    if (!currentComicsProjectId) return;
    const confirmed = await showCustomConfirm(
      'Confirmar Exclusão',
      'Tem certeza de que deseja excluir este projeto permanentemente?',
      true
    );
    if (!confirmed) return;
    
    try {
      const resp = await fetch(`/api/comics/projects/${currentComicsProjectId}`, {
        method: 'DELETE'
      });
      
      if (!resp.ok) {
        const errMsg = await safeExtractError(resp, 'Falha ao excluir projeto');
        throw new Error(errMsg);
      }
      
      await showCustomAlert('Excluído', 'Projeto excluído com sucesso!');
      startNewComicsProject();
      await loadComicsProjectsList();
    } catch (err) {
      console.error(err);
      await showCustomAlert('Erro', 'Erro ao excluir projeto: ' + err.message);
    }
  };

  // Abrir e fechar modal Fábrica de Quadrinhos
  const openComicsModal = () => {
    fabricaQuadrinhosModal.style.display = 'flex';
    startNewComicsProject();
    loadComicsProjectsList();
  };

  // Listeners do Gerenciador de Projetos
  if (comicsProjectSelect) {
    comicsProjectSelect.addEventListener('change', (e) => {
      loadComicsProject(e.target.value);
    });
  }

  if (btnNewComicsProject) {
    btnNewComicsProject.addEventListener('click', async () => {
      const confirmed = await showCustomConfirm(
        'Novo Projeto',
        'Deseja iniciar um novo projeto? Alterações não salvas serão perdidas.'
      );
      if (confirmed) {
        startNewComicsProject();
      }
    });
  }

  if (btnSaveComicsProject) {
    btnSaveComicsProject.addEventListener('click', saveComicsProject);
  }

  if (btnSaveNewComicsProject) {
    btnSaveNewComicsProject.addEventListener('click', saveNewComicsProject);
  }

  if (btnDeleteComicsProject) {
    btnDeleteComicsProject.addEventListener('click', deleteComicsProject);
  }

  if (barBtnComics) {
    barBtnComics.addEventListener('click', openComicsModal);
  }

  if (btnCloseComicsModal) {
    btnCloseComicsModal.addEventListener('click', () => {
      fabricaQuadrinhosModal.style.display = 'none';
      if (comicsVideoPlayer) comicsVideoPlayer.pause();
    });
  }

  // Fechar modal clicando fora
  window.addEventListener('click', (e) => {
    if (e.target === fabricaQuadrinhosModal) {
      fabricaQuadrinhosModal.style.display = 'none';
      if (comicsVideoPlayer) comicsVideoPlayer.pause();
    }
  });

  // Helper para converter URL de imagem local em base64
  const getBase64Image = async (imgUrl) => {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'Anonymous';
      img.onload = () => {
        const canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
        resolve(canvas.toDataURL('image/jpeg'));
      };
      img.onerror = (e) => reject(new Error('Falha ao carregar imagem para o PDF: ' + imgUrl));
      img.src = imgUrl;
    });
  };

  // Helper para execução concorrente controlada
  const mapConcurrent = async (items, limit, fn) => {
    const results = new Array(items.length);
    let currentIdx = 0;
    const worker = async () => {
      while (currentIdx < items.length) {
        const i = currentIdx++;
        results[i] = await fn(items[i], i);
      }
    };
    const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());
    await Promise.all(workers);
    return results;
  };

  // Ação de geração da história e imagens
  if (btnGenerateComics) {
    btnGenerateComics.addEventListener('click', async () => {
      const tema = comicsTemaInput.value.trim();
      if (!tema) {
        await showCustomAlert('Campo Requerido', 'Por favor, digite um tema para a história.');
        return;
      }

      // Reunir personagens dinamicamente
      const personagens = [];
      document.querySelectorAll('.comic-char-row').forEach(row => {
        const type = row.querySelector('.char-type-input').value.trim();
        const name = row.querySelector('.char-name-input').value.trim();
        if (type && name) {
          personagens.push(`${type} chamado(a) ${name}`);
        }
      });

      if (personagens.length === 0) {
        await showCustomAlert('Personagens Faltando', 'Adicione e preencha pelo menos um personagem principal.');
        return;
      }

      // Definir cenário
      let cenario = comicsCenarioSelect.value;
      if (cenario === 'custom') {
        cenario = comicsCenarioCustomInput.value.trim() || 'em um local bonito';
      }

      btnGenerateComics.disabled = true;
      comicsGenerateLoader.style.display = 'flex';
      comicsResultArea.style.display = 'none';
      comicsVideoResult.style.display = 'none';
      comicsLoaderProgress.style.width = '5%';
      comicsLoaderText.textContent = 'Escrevendo o roteiro e diálogos dos quadrinhos...';

      try {
        // 1. Gerar Roteiro
        const genMode = currentComicsProjectId ? (document.querySelector('input[name="comicsGenMode"]:checked')?.value || 'new_story') : 'new_story';
        
        const requestBody = {
          tema,
          quantidade: selectedComicsQty,
          baloes: selectedComicsBubbles,
          proporcao: selectedComicsRatio,
          personagens,
          cenario
        };

        if (currentComicsProjectId) {
          requestBody.continuationType = genMode;
          requestBody.character_description = currentComicsCharDescEnglish;
          requestBody.existingPanels = generatedPanelsData.map(p => ({
            panel_number: p.panel_number,
            image_url: p.imageUrl || p.image_url || '',
            image_prompt: p.image_prompt || '',
            dialogue: p.dialogue || ''
          }));
        }

        const scriptResp = await fetch('/api/comics/generate-script', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(requestBody)
        });

        if (!scriptResp.ok) {
          const errMsg = await safeExtractError(scriptResp, 'Erro ao planejar roteiro');
          throw new Error(errMsg);
        }

        const scriptData = await scriptResp.json();
        comicsLoaderProgress.style.width = '20%';

        if (scriptData.character_description) {
          currentComicsCharDescEnglish = scriptData.character_description;
        }

        // 2. Gerar quadrinhos com concorrência balanceada (2 por vez) e tracking em tempo real
        if (genMode !== 'extend') {
          generatedPanelsData = [];
        }
        const totalPanels = scriptData.panels.length;
        let completedCount = 0;

        const generateSinglePanel = async (panel) => {
          const fullPrompt = `${panel.image_prompt}, high resolution children book illustration, cute Pixar style, ${selectedComicsRatio === '16:9' ? '16:9 aspect ratio' : '4:3 aspect ratio'}`;

          let frameResp;
          try {
            frameResp = await fetch('/api/comics/generate-frame', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ prompt: fullPrompt, proporcao: selectedComicsRatio })
            });
          } catch (netErr) {
            throw new Error(`Falha de conexão no quadro ${panel.panel_number}: ${netErr.message}`);
          }

          if (!frameResp.ok) {
            const errMsg = await safeExtractError(frameResp, 'Erro ao ilustrar quadro');
            throw new Error(`Erro no quadrinho ${panel.panel_number}: ${errMsg}`);
          }

          const frameData = await frameResp.json();
          completedCount++;
          const progressPercent = 20 + Math.floor((completedCount / totalPanels) * 75);
          if (comicsLoaderProgress) comicsLoaderProgress.style.width = `${progressPercent}%`;
          if (comicsLoaderText) comicsLoaderText.textContent = `🎨 Ilustrando quadrinhos: ${completedCount}/${totalPanels} quadros concluídos...`;

          return {
            panel_number: panel.panel_number,
            imageUrl: frameData.imageUrl,
            dialogue: panel.dialogue || '',
            image_prompt: panel.image_prompt || ''
          };
        };

        // Executa com no máximo 2 quadros em paralelo para estabilidade máxima e resposta fluida
        const newPanels = await mapConcurrent(scriptData.panels, 2, generateSinglePanel);
        
        // Ordena por panel_number para garantir a sequência correta
        newPanels.sort((a, b) => a.panel_number - b.panel_number);
        
        if (genMode === 'extend') {
          generatedPanelsData = generatedPanelsData.concat(newPanels);
        } else {
          generatedPanelsData = newPanels;
        }

        // Atualizar cabeçalho e metadados
        comicsResultTitle.textContent = scriptData.title || comicsResultTitle.textContent || 'Fábrica de Quadrinhos Pedagog';

        // Renderizar Storyboard Interativo
        renderComicsStoryboard();

        // Se for uma nova história derivada de um projeto antigo, limpamos o ID para virar um novo projeto independente ao salvar
        if (genMode === 'new_story' && currentComicsProjectId) {
          currentComicsProjectId = null;
          if (comicsProjectSelect) comicsProjectSelect.value = '';
          const modeContainer = document.getElementById('comicsGenerationModeContainer');
          if (modeContainer) modeContainer.style.display = 'none';
          if (comicsProjectTitleInput) {
            comicsProjectTitleInput.value = scriptData.title || (comicsProjectTitleInput.value + ' (Derivado)');
          }
          if (btnDeleteComicsProject) btnDeleteComicsProject.style.display = 'none';
        }

        comicsGenerateLoader.style.display = 'none';
        comicsResultArea.style.display = 'flex';
        btnGenerateComics.disabled = false;

      } catch (err) {
        console.error('Erro ao fabricar quadrinhos:', err);
        await showCustomAlert('Erro', 'Erro ao fabricar quadrinhos: ' + err.message);
        comicsGenerateLoader.style.display = 'none';
        btnGenerateComics.disabled = false;
      }
    });
  }

  // --- RENDERIZADOR DO STORYBOARD PROFISSIONAL DOS QUADRINHOS ---
  const renderComicsStoryboard = () => {
    if (!comicsGridContainer) return;
    comicsGridContainer.innerHTML = '';

    generatedPanelsData.forEach((panel, index) => {
      const panelCard = document.createElement('div');
      panelCard.className = 'comic-panel-card';
      panelCard.dataset.index = index;

      const imgContainer = document.createElement('div');
      imgContainer.className = `comic-panel-image-container ratio-${selectedComicsRatio.replace(':', '-')}`;

      const img = document.createElement('img');
      img.className = 'comic-panel-image';
      img.src = panel.imageUrl || panel.image_url;
      img.alt = `Quadro ${panel.panel_number}`;
      img.loading = 'lazy';
      imgContainer.appendChild(img);

      // Selo de número do quadrinho
      const badge = document.createElement('div');
      badge.className = 'comic-panel-number-badge';
      badge.textContent = panel.panel_number;
      imgContainer.appendChild(badge);

      // Barra de Ações Rápidas por Quadro (Mobile & Desktop)
      const actionsOverlay = document.createElement('div');
      actionsOverlay.className = 'comic-panel-overlay-actions';

      // Botão 🔍 Zoom
      const btnZoom = document.createElement('button');
      btnZoom.type = 'button';
      btnZoom.className = 'btn-comic-action';
      btnZoom.title = 'Ampliar imagem';
      btnZoom.innerHTML = '🔍';
      btnZoom.addEventListener('click', (e) => {
        e.stopPropagation();
        openComicsPresentation(index);
      });
      actionsOverlay.appendChild(btnZoom);

      // Botão 🔄 Regenerar Imagem deste Quadro
      const btnRegen = document.createElement('button');
      btnRegen.type = 'button';
      btnRegen.className = 'btn-comic-action';
      btnRegen.title = 'Regenerar apenas este quadrinho';
      btnRegen.innerHTML = '🔄';
      btnRegen.addEventListener('click', async (e) => {
        e.stopPropagation();
        await regenerateSinglePanel(index, panelCard, img, btnRegen);
      });
      actionsOverlay.appendChild(btnRegen);

      // Botão ✏️ Ver/Editar Prompt
      const btnPromptToggle = document.createElement('button');
      btnPromptToggle.type = 'button';
      btnPromptToggle.className = 'btn-comic-action';
      btnPromptToggle.title = 'Editar prompt visual';
      btnPromptToggle.innerHTML = '✏️';
      actionsOverlay.appendChild(btnPromptToggle);

      // Botão 💾 Baixar Imagem Individual
      const btnDownloadImg = document.createElement('button');
      btnDownloadImg.type = 'button';
      btnDownloadImg.className = 'btn-comic-action';
      btnDownloadImg.title = 'Baixar esta imagem PNG';
      btnDownloadImg.innerHTML = '💾';
      btnDownloadImg.addEventListener('click', (e) => {
        e.stopPropagation();
        const a = document.createElement('a');
        a.href = panel.imageUrl || panel.image_url;
        a.download = `quadrinho_${panel.panel_number}.png`;
        document.body.appendChild(a);
        a.click();
        a.remove();
      });
      actionsOverlay.appendChild(btnDownloadImg);

      imgContainer.appendChild(actionsOverlay);
      panelCard.appendChild(imgContainer);

      // Área de Legenda / Diálogo
      const caption = document.createElement('div');
      caption.className = 'comic-caption-text';

      const textarea = document.createElement('textarea');
      textarea.className = 'comic-caption-input';
      textarea.value = panel.dialogue || '';
      textarea.placeholder = 'Digite a fala ou legenda do quadrinho...';
      textarea.style.cssText = 'width: 100%; border: 1px solid var(--border-light); background: var(--bg-secondary); color: var(--text-primary); border-radius: 6px; padding: 8px; font-family: inherit; font-size: 0.85rem; resize: vertical; box-sizing: border-box; min-height: 48px;';

      textarea.addEventListener('input', (e) => {
        panel.dialogue = e.target.value;
        if (generatedPanelsData[index]) {
          generatedPanelsData[index].dialogue = e.target.value;
        }
      });
      caption.appendChild(textarea);

      // Mini-Editor de Prompt Visual (Oculto por padrão, ativado no botão ✏️)
      const promptBox = document.createElement('div');
      promptBox.className = 'comic-prompt-details';
      const promptInput = document.createElement('textarea');
      promptInput.style.cssText = 'width: 100%; font-size: 0.72rem; padding: 4px; background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--border-light); border-radius: 4px; resize: vertical; min-height: 40px; box-sizing: border-box;';
      promptInput.value = panel.image_prompt || '';
      promptInput.addEventListener('input', (e) => {
        panel.image_prompt = e.target.value;
      });
      promptBox.appendChild(document.createTextNode('Prompt Visual: '));
      promptBox.appendChild(promptInput);
      caption.appendChild(promptBox);

      btnPromptToggle.addEventListener('click', (e) => {
        e.stopPropagation();
        promptBox.style.display = promptBox.style.display === 'block' ? 'none' : 'block';
      });

      panelCard.appendChild(caption);
      comicsGridContainer.appendChild(panelCard);
    });
  };

  // Regenerar um único painel
  const regenerateSinglePanel = async (index, panelCard, imgElement, btnRegen) => {
    const panel = generatedPanelsData[index];
    if (!panel) return;

    try {
      btnRegen.disabled = true;
      btnRegen.textContent = '⏳';
      imgElement.style.opacity = '0.4';

      const promptToUse = panel.image_prompt || 'cute children illustration';
      const fullPrompt = `${promptToUse}, high resolution children book illustration, cute Pixar style, ${selectedComicsRatio === '16:9' ? '16:9 aspect ratio' : '4:3 aspect ratio'}`;

      const resp = await fetch('/api/comics/generate-frame', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ prompt: fullPrompt })
      });

      if (!resp.ok) {
        const errMsg = await safeExtractError(resp, 'Erro na regeneração');
        throw new Error(errMsg);
      }

      const data = await resp.json();
      panel.imageUrl = data.imageUrl;
      imgElement.src = data.imageUrl + '?v=' + Date.now();
      imgElement.style.opacity = '1';
    } catch (err) {
      console.error('Erro ao regenerar painel:', err);
      await showCustomAlert('Erro', 'Não foi possível regenerar o quadrinho: ' + err.message);
      imgElement.style.opacity = '1';
    } finally {
      btnRegen.disabled = false;
      btnRegen.innerHTML = '🔄';
    }
  };

  // --- EXPORTAR TODAS AS IMAGENS EM ZIP ---
  const btnExportComicsZIP = document.getElementById('btnExportComicsZIP');
  if (btnExportComicsZIP) {
    btnExportComicsZIP.addEventListener('click', async () => {
      if (!generatedPanelsData || generatedPanelsData.length === 0) {
        await showCustomAlert('Aviso', 'Nenhum quadrinho gerado para exportar.');
        return;
      }

      try {
        btnExportComicsZIP.disabled = true;
        btnExportComicsZIP.textContent = '⏳ Criando ZIP...';

        if (typeof JSZip === 'undefined') {
          throw new Error('Biblioteca JSZip não carregada.');
        }

        const zip = new JSZip();
        const folder = zip.folder('quadrinhos');
        const title = (comicsResultTitle?.textContent || 'Historia_Quadrinhos').replace(/[^a-zA-Z0-9_-]/g, '_');

        let roteiroTxt = `HISTÓRIA EM QUADRINHOS: ${comicsResultTitle?.textContent || 'Fábrica de Quadrinhos'}\n`;
        roteiroTxt += `Criado com PedagogIA em ${new Date().toLocaleDateString('pt-BR')}\n\n`;

        for (let i = 0; i < generatedPanelsData.length; i++) {
          const panel = generatedPanelsData[i];
          const imgUrl = panel.imageUrl || panel.image_url;
          roteiroTxt += `[QUADRO ${panel.panel_number}]\nFala/Legenda: ${panel.dialogue || '(Sem fala)'}\nPrompt Visual: ${panel.image_prompt || ''}\n\n`;

          try {
            const resp = await fetch(imgUrl);
            const blob = await resp.blob();
            folder.file(`quadrinho_${panel.panel_number}.jpg`, blob);
          } catch (fetchErr) {
            console.warn(`Erro ao incluir imagem ${panel.panel_number} no ZIP:`, fetchErr);
          }
        }

        folder.file('roteiro.txt', roteiroTxt);

        const content = await zip.generateAsync({ type: 'blob' });
        const downloadUrl = URL.createObjectURL(content);
        const a = document.createElement('a');
        a.href = downloadUrl;
        a.download = `${title}_pedagog.zip`;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(downloadUrl);

      } catch (err) {
        console.error('Erro ao gerar ZIP:', err);
        await showCustomAlert('Erro', 'Não foi possível gerar o ZIP: ' + err.message);
      } finally {
        btnExportComicsZIP.disabled = false;
        btnExportComicsZIP.innerHTML = '<span>📦 Baixar Todas as Imagens (ZIP)</span>';
      }
    });
  }

  // --- MODO APRESENTAÇÃO EM TELA CHEIA (LEITURA INFANTIL / MOBILE) ---
  const comicsPresModal = document.getElementById('comicsPresentationModal');
  const comicsPresTitle = document.getElementById('comicsPresTitle');
  const comicsPresImage = document.getElementById('comicsPresImage');
  const comicsPresCaption = document.getElementById('comicsPresCaption');
  const comicsPresCounter = document.getElementById('comicsPresCounter');
  const btnPresPrev = document.getElementById('btnPresPrev');
  const btnPresNext = document.getElementById('btnPresNext');
  const btnCloseComicsPresModal = document.getElementById('btnCloseComicsPresModal');
  const btnComicsPresentationMode = document.getElementById('btnComicsPresentationMode');

  let presCurrentIndex = 0;

  const openComicsPresentation = (index = 0) => {
    if (!generatedPanelsData || generatedPanelsData.length === 0) return;
    presCurrentIndex = Math.max(0, Math.min(index, generatedPanelsData.length - 1));
    if (comicsPresModal) comicsPresModal.style.display = 'flex';
    updateComicsPresentationView();
  };

  const closeComicsPresentation = () => {
    if (comicsPresModal) comicsPresModal.style.display = 'none';
  };

  const updateComicsPresentationView = () => {
    if (!generatedPanelsData || generatedPanelsData.length === 0) return;
    const panel = generatedPanelsData[presCurrentIndex];
    if (!panel) return;

    if (comicsPresTitle) comicsPresTitle.textContent = comicsResultTitle?.textContent || 'Fábrica de Quadrinhos';
    if (comicsPresCounter) comicsPresCounter.textContent = `${presCurrentIndex + 1} / ${generatedPanelsData.length}`;
    if (comicsPresImage) comicsPresImage.src = panel.imageUrl || panel.image_url;
    if (comicsPresCaption) comicsPresCaption.textContent = panel.dialogue || '(História silenciosa)';

    if (btnPresPrev) btnPresPrev.disabled = presCurrentIndex === 0;
    if (btnPresNext) btnPresNext.disabled = presCurrentIndex === generatedPanelsData.length - 1;
  };

  if (btnComicsPresentationMode) {
    btnComicsPresentationMode.addEventListener('click', () => {
      openComicsPresentation(0);
    });
  }

  if (btnPresPrev) {
    btnPresPrev.addEventListener('click', () => {
      if (presCurrentIndex > 0) {
        presCurrentIndex--;
        updateComicsPresentationView();
      }
    });
  }

  if (btnPresNext) {
    btnPresNext.addEventListener('click', () => {
      if (presCurrentIndex < generatedPanelsData.length - 1) {
        presCurrentIndex++;
        updateComicsPresentationView();
      }
    });
  }

  if (btnCloseComicsPresModal) {
    btnCloseComicsPresModal.addEventListener('click', closeComicsPresentation);
  }

  // Teclado (setas) para o modo apresentação
  window.addEventListener('keydown', (e) => {
    if (comicsPresModal && comicsPresModal.style.display === 'flex') {
      if (e.key === 'ArrowRight' || e.key === 'Space') {
        if (presCurrentIndex < generatedPanelsData.length - 1) {
          presCurrentIndex++;
          updateComicsPresentationView();
        }
      } else if (e.key === 'ArrowLeft') {
        if (presCurrentIndex > 0) {
          presCurrentIndex--;
          updateComicsPresentationView();
        }
      } else if (e.key === 'Escape') {
        closeComicsPresentation();
      }
    }
  });

  // Touch Swipe para smartphones no modo apresentação
  let touchStartX = 0;
  if (comicsPresModal) {
    comicsPresModal.addEventListener('touchstart', (e) => {
      touchStartX = e.changedTouches[0].screenX;
    }, { passive: true });

    comicsPresModal.addEventListener('touchend', (e) => {
      const touchEndX = e.changedTouches[0].screenX;
      const diff = touchEndX - touchStartX;
      if (Math.abs(diff) > 50) {
        if (diff < 0 && presCurrentIndex < generatedPanelsData.length - 1) {
          // Swipe para a esquerda -> Próximo
          presCurrentIndex++;
          updateComicsPresentationView();
        } else if (diff > 0 && presCurrentIndex > 0) {
          // Swipe para a direita -> Anterior
          presCurrentIndex--;
          updateComicsPresentationView();
        }
      }
    }, { passive: true });
  }

  // Exportar PDF Retrato (1 por página)
  if (btnExportComicsPDFPortrait) {
    btnExportComicsPDFPortrait.addEventListener('click', async () => {
      if (generatedPanelsData.length === 0) return;
      btnExportComicsPDFPortrait.disabled = true;
      btnExportComicsPDFPortrait.textContent = '⏳ Montando PDF...';

      try {
        const { jsPDF } = window.jspdf;
        const doc = new jsPDF('p', 'pt', 'a4');
        const title = comicsResultTitle.textContent || 'História em Quadrinhos';

        for (let i = 0; i < generatedPanelsData.length; i++) {
          const panel = generatedPanelsData[i];
          if (i > 0) doc.addPage();

          // Título centralizado
          doc.setFont('helvetica', 'bold');
          doc.setFontSize(18);
          doc.setTextColor(30, 41, 59);
          doc.text(title, 297, 50, { align: 'center' });

          // Imagem
          const base64Img = await getBase64Image(panel.imageUrl);
          const imgWidth = 515;
          const imgHeight = selectedComicsRatio === '16:9' ? 290 : 386;
          doc.addImage(base64Img, 'JPEG', 40, 80, imgWidth, imgHeight);

          // Altura esticada para a caixa de diálogo (160pt de altura - aprox dobro)
          const textHeight = 160;
          const textY = 80 + imgHeight;

          // Caixa de diálogo com fundo cinza claro e borda integrada
          doc.setFillColor(248, 250, 252);
          doc.rect(40, textY, imgWidth, textHeight, 'F');

          // Moldura unificada ao redor de toda a imagem + texto
          doc.setDrawColor(30, 41, 59);
          doc.setLineWidth(2);
          doc.rect(40, 80, imgWidth, imgHeight + textHeight, 'D');

          // Linha divisória entre a imagem e a caixa de texto
          doc.line(40, textY, 555, textY);

          // Texto maior e mais legível (dobro do tamanho relativo - 15pt)
          if (panel.dialogue) {
            doc.setFont('helvetica', 'normal');
            doc.setFontSize(15);
            doc.setTextColor(15, 23, 42);
            
            const splitText = doc.splitTextToSize(panel.dialogue, imgWidth - 40);
            doc.text(splitText, 60, textY + 35);
          }

          // Círculo discreto com o número do quadrinho no canto superior esquerdo da imagem
          doc.setFillColor(254, 240, 138);
          doc.circle(65, 105, 12, 'F');
          doc.setDrawColor(30, 41, 59);
          doc.setLineWidth(1.5);
          doc.circle(65, 105, 12, 'D');
          
          doc.setFont('helvetica', 'bold');
          doc.setFontSize(10);
          doc.setTextColor(30, 41, 59);
          doc.text(String(panel.panel_number), 65, 109, { align: 'center' });

          // Rodapé
          doc.setFont('helvetica', 'italic');
          doc.setFontSize(9);
          doc.setTextColor(148, 163, 184);
          doc.text(`Criado com PedaGog - Quadro ${panel.panel_number} de ${generatedPanelsData.length}`, 297, 815, { align: 'center' });
        }

        doc.save(`quadrinhos_${title.replace(/\s+/g, '_').toLowerCase()}.pdf`);
      } catch (error) {
        console.error('Erro ao gerar PDF Retrato:', error);
        alert('Erro ao gerar PDF: ' + error.message);
      } finally {
        btnExportComicsPDFPortrait.disabled = false;
        btnExportComicsPDFPortrait.textContent = '📄 PDF (1 por página - Retrato)';
      }
    });
  }

  // Exportar PDF Paisagem (2 por página)
  if (btnExportComicsPDFLandscape) {
    btnExportComicsPDFLandscape.addEventListener('click', async () => {
      if (generatedPanelsData.length === 0) return;
      btnExportComicsPDFLandscape.disabled = true;
      btnExportComicsPDFLandscape.textContent = '⏳ Montando PDF...';

      try {
        const { jsPDF } = window.jspdf;
        const doc = new jsPDF('l', 'pt', 'a4');
        const title = comicsResultTitle.textContent || 'História em Quadrinhos';

        const totalPanels = generatedPanelsData.length;
        const totalPages = Math.ceil(totalPanels / 2);

        for (let page = 0; page < totalPages; page++) {
          if (page > 0) doc.addPage();

          // Título centralizado no topo da página paisagem
          doc.setFont('helvetica', 'bold');
          doc.setFontSize(18);
          doc.setTextColor(30, 41, 59);
          doc.text(`${title} - Página ${page + 1} de ${totalPages}`, 421, 45, { align: 'center' });

          // Renderizar até dois quadrinhos lado a lado
          for (let col = 0; col < 2; col++) {
            const index = page * 2 + col;
            if (index >= totalPanels) break;

            const panel = generatedPanelsData[index];
            const startX = col === 0 ? 40 : 426;
            const cardWidth = 376;
            
            // Proporções exatas mantidas
            const imgHeight = selectedComicsRatio === '16:9' ? 211 : 282;
            const textHeight = 140; // Dobro de tamanho (antes era 65)

            // Imagem do quadrinho
            const base64Img = await getBase64Image(panel.imageUrl);
            doc.addImage(base64Img, 'JPEG', startX, 70, cardWidth, imgHeight);

            // Fundo da caixa de texto
            const textY = 70 + imgHeight;
            doc.setFillColor(248, 250, 252);
            doc.rect(startX, textY, cardWidth, textHeight, 'F');

            // Moldura unificada ao redor do quadro (imagem + texto)
            doc.setDrawColor(30, 41, 59);
            doc.setLineWidth(2);
            doc.rect(startX, 70, cardWidth, imgHeight + textHeight, 'D');

            // Linha separando a imagem da caixa de texto
            doc.line(startX, textY, startX + cardWidth, textY);

            // Legenda formatada em tamanho maior (13pt)
            if (panel.dialogue) {
              doc.setFont('helvetica', 'normal');
              doc.setFontSize(13);
              doc.setTextColor(15, 23, 42);
              
              const splitText = doc.splitTextToSize(panel.dialogue, cardWidth - 30);
              doc.text(splitText, startX + 15, textY + 30);
            }

            // Círculo discreto com o numeral do quadro no canto superior esquerdo da imagem
            doc.setFillColor(254, 240, 138);
            doc.circle(startX + 20, 90, 11, 'F');
            doc.setDrawColor(30, 41, 59);
            doc.setLineWidth(1.5);
            doc.circle(startX + 20, 90, 11, 'D');
            
            doc.setFont('helvetica', 'bold');
            doc.setFontSize(9);
            doc.setTextColor(30, 41, 59);
            doc.text(String(panel.panel_number), startX + 20, 93, { align: 'center' });
          }
        }

        doc.save(`quadrinhos_${title.replace(/\s+/g, '_').toLowerCase()}_paisagem.pdf`);
      } catch (error) {
        console.error('Erro ao gerar PDF Paisagem:', error);
        alert('Erro ao gerar PDF: ' + error.message);
      } finally {
        btnExportComicsPDFLandscape.disabled = false;
        btnExportComicsPDFLandscape.textContent = '📄 PDF (2 por página - Paisagem)';
      }
    });
  }

  // Compilar Vídeo de Apresentação (FFmpeg)
  if (btnCompileComicsVideo) {
    btnCompileComicsVideo.addEventListener('click', async () => {
      if (generatedPanelsData.length === 0) return;

      btnCompileComicsVideo.disabled = true;
      comicsVideoLoader.style.display = 'flex';
      comicsVideoResult.style.display = 'none';

      try {
        const response = await fetch('/api/comics/generate-video', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            frames: generatedPanelsData,
            musicSelection: comicsVideoMusic.value,
            frameDuration: comicsVideoDuration.value
          })
        });

        if (!response.ok) {
          const err = await response.json();
          throw new Error(err.error || 'Erro na compilação do vídeo');
        }

        const data = await response.json();
        
        comicsVideoPlayer.src = data.videoUrl;
        comicsVideoDownloadBtn.href = data.videoUrl;
        
        comicsVideoResult.style.display = 'flex';
        comicsVideoLoader.style.display = 'none';
        btnCompileComicsVideo.disabled = false;

      } catch (err) {
        console.error('Erro ao gerar vídeo dos quadrinhos:', err);
        alert('Erro ao compilar o vídeo: ' + err.message);
        comicsVideoLoader.style.display = 'none';
        btnCompileComicsVideo.disabled = false;
      }
    });
  }

  // ============================================================
  // VIDEOMIND (TRANSCRIÇÃO E ANÁLISE DE VÍDEO PEDAGÓGICO)
  // ============================================================
  const videoMindModal = document.getElementById('videoMindModal');
  const btnCloseVideoMindModal = document.getElementById('btnCloseVideoMindModal');
  const barBtnVideoMind = document.getElementById('barBtnVideoMind');
  
  const btnGenerateVideoMind = document.getElementById('btnGenerateVideoMind');
  const videoMindUrlInput = document.getElementById('videoMindUrlInput');
  const videoMindLoader = document.getElementById('videoMindLoader');
  const videoMindLoaderText = document.getElementById('videoMindLoaderText');
  const videoMindResultArea = document.getElementById('videoMindResultArea');
  
  const videoMindThumbnail = document.getElementById('videoMindThumbnail');
  const videoMindTitle = document.getElementById('videoMindTitle');
  const videoMindAuthor = document.getElementById('videoMindAuthor');
  const videoMindReportArea = document.getElementById('videoMindReportArea');
  
  const btnCopyVideoMindReport = document.getElementById('btnCopyVideoMindReport');
  const btnDownloadVideoMindReport = document.getElementById('btnDownloadVideoMindReport');
  const btnPdfVideoMindReport = document.getElementById('btnPdfVideoMindReport');

  let selectedVideoMindLines = 20;
  let activeVideoMindReport = null;

  // Listener para selecionar o tamanho do resumo
  document.querySelectorAll('#videoMindModal .music-option-grid .btn-videomind-lines').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('#videoMindModal .music-option-grid .btn-videomind-lines').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      selectedVideoMindLines = parseInt(btn.dataset.lines) || 20;
    });
  });

  // Abrir modal do VideoMind
  if (barBtnVideoMind) {
    barBtnVideoMind.addEventListener('click', () => {
      videoMindModal.style.display = 'flex';
      videoMindUrlInput.value = '';
      videoMindResultArea.style.display = 'none';
      videoMindReportArea.innerHTML = '';
      if (videoMindLoader) videoMindLoader.style.display = 'none';
      btnGenerateVideoMind.disabled = false;
      activeVideoMindReport = null;
    });
  }

  // Fechar modal
  if (btnCloseVideoMindModal) {
    btnCloseVideoMindModal.addEventListener('click', () => {
      videoMindModal.style.display = 'none';
    });
  }

  window.addEventListener('click', (e) => {
    if (e.target === videoMindModal) {
      videoMindModal.style.display = 'none';
    }
  });

  // Ação de analisar vídeo
  if (btnGenerateVideoMind) {
    btnGenerateVideoMind.addEventListener('click', async () => {
      const url = videoMindUrlInput.value.trim();
      const pastedTranscriptInput = document.getElementById('videoMindPastedTranscriptInput');
      const pastedTranscript = pastedTranscriptInput ? pastedTranscriptInput.value.trim() : '';

      if (!url) {
        alert('Por favor, insira o link de um vídeo do YouTube.');
        return;
      }

      btnGenerateVideoMind.disabled = true;
      videoMindLoader.style.display = 'flex';
      videoMindResultArea.style.display = 'none';
      videoMindLoaderText.textContent = 'Buscando metadados do vídeo...';

      let statusMsgIdx = 0;
      const statusMessages = [
        'Buscando legenda automática do vídeo...',
        'Carregando a transcrição completa...',
        'Enviando transcrição para a IA...',
        'Pedagoga IA analisando o conteúdo...',
        'Alinhando temas do vídeo com a BNCC...',
        'Gerando resumo de ' + selectedVideoMindLines + ' linhas...',
        'Criando propostas de atividades pedagógicas...',
        'Finalizando o parecer pedagógico...'
      ];

      const statusInterval = setInterval(() => {
        if (statusMsgIdx < statusMessages.length) {
          videoMindLoaderText.textContent = statusMessages[statusMsgIdx];
          statusMsgIdx++;
        } else {
          videoMindLoaderText.textContent = 'Ajustando formatação da análise...';
        }
      }, 4000);

      try {
        const response = await fetch('/api/videomind/analyze', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            url,
            lines: selectedVideoMindLines,
            pastedTranscript
          })
        });

        clearInterval(statusInterval);

        if (!response.ok) {
          const errData = await response.json();
          throw new Error(errData.error || 'Erro desconhecido');
        }

        const data = await response.json();
        activeVideoMindReport = data;

        // Preencher informações do vídeo
        videoMindTitle.textContent = data.metadata.title;
        videoMindAuthor.textContent = 'Canal: ' + data.metadata.author;
        videoMindThumbnail.src = data.metadata.thumbnail;

        // Renderizar Markdown
        if (window.marked) {
          videoMindReportArea.innerHTML = marked.parse(data.report);
        } else {
          videoMindReportArea.textContent = data.report;
        }

        videoMindLoader.style.display = 'none';
        videoMindResultArea.style.display = 'flex';

      } catch (err) {
        clearInterval(statusInterval);
        console.error('Erro no VideoMind:', err);
        alert('Erro ao analisar vídeo: ' + err.message);
        videoMindLoader.style.display = 'none';
        btnGenerateVideoMind.disabled = false;
      }
    });
  }

  // Copiar Parecer
  if (btnCopyVideoMindReport) {
    btnCopyVideoMindReport.addEventListener('click', () => {
      if (activeVideoMindReport && activeVideoMindReport.report) {
        navigator.clipboard.writeText(activeVideoMindReport.report)
          .then(() => {
            btnCopyVideoMindReport.textContent = '✅ Copiado!';
            setTimeout(() => {
              btnCopyVideoMindReport.textContent = '📋 Copiar Parecer';
            }, 2000);
          })
          .catch(err => {
            console.error('Falha ao copiar:', err);
          });
      }
    });
  }

  // Baixar relatório TXT
  if (btnDownloadVideoMindReport) {
    btnDownloadVideoMindReport.addEventListener('click', () => {
      if (activeVideoMindReport && activeVideoMindReport.report) {
        const title = activeVideoMindReport.metadata.title || 'analise_video';
        const blob = new Blob([activeVideoMindReport.report], { type: 'text/plain;charset=utf-8' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `VideoMind_${title.replace(/\s+/g, '_').toLowerCase()}.txt`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      }
    });
  }

  // Baixar relatório PDF
  if (btnPdfVideoMindReport) {
    btnPdfVideoMindReport.addEventListener('click', () => {
      if (!activeVideoMindReport) return;

      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>VideoMind - Parecer Pedagógico</title>
          <style>
            body { font-family: 'Outfit', 'Inter', -apple-system, sans-serif; padding: 40px; color: #333; line-height: 1.6; }
            h1, h2, h3 { color: #0891b2; margin-top: 24px; margin-bottom: 12px; }
            h1 { border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; font-size: 22px; }
            h2 { font-size: 18px; border-bottom: 1px solid #f1f5f9; padding-bottom: 6px; }
            .meta-box { background: #f8fafc; padding: 16px; border-radius: 8px; margin-bottom: 24px; font-size: 14px; border: 1px solid #e2e8f0; display: flex; gap: 16px; align-items: center; }
            .meta-info { display: flex; flex-direction: column; gap: 4px; }
            .meta-label { font-weight: bold; color: #475569; }
            p { margin-bottom: 14px; text-align: justify; }
            ul, ol { margin-bottom: 14px; padding-left: 20px; }
            li { margin-bottom: 6px; }
            @media print {
              body { padding: 0; }
              button { display: none; }
            }
          </style>
        </head>
        <body>
          <h1>🎬 VideoMind - Análise & Parecer Pedagógico</h1>
          <div class="meta-box">
            <img src="${activeVideoMindReport.metadata.thumbnail}" style="width: 100px; aspect-ratio: 16/9; object-fit: cover; border-radius: 6px;">
            <div class="meta-info">
              <div><span class="meta-label">Vídeo:</span> <span>${activeVideoMindReport.metadata.title}</span></div>
              <div><span class="meta-label">Canal:</span> <span>${activeVideoMindReport.metadata.author}</span></div>
              <div><span class="meta-label">Resumo Escolhido:</span> <span>${selectedVideoMindLines} Linhas</span></div>
            </div>
          </div>
          <div>${window.marked ? marked.parse(activeVideoMindReport.report) : activeVideoMindReport.report}</div>
          <script>
            window.onload = function() {
              window.print();
              setTimeout(() => { window.close(); }, 500);
            };
          </script>
        </body>
        </html>
      `);
    });
  }

  // ============================================================
  // GARATUJAS (ANALISADOR DE TRAÇADO INFANTIL)
  // ============================================================
  const garatujasModal = document.getElementById('garatujasModal');
  const btnCloseGaratujasModal = document.getElementById('btnCloseGaratujasModal');
  const barBtnGaratujas = document.getElementById('barBtnGaratujas');
  
  const tabGaratujasNova = document.getElementById('tabGaratujasNova');
  const tabGaratujasHistorico = document.getElementById('tabGaratujasHistorico');
  const contentGaratujasNova = document.getElementById('contentGaratujasNova');
  const contentGaratujasHistorico = document.getElementById('contentGaratujasHistorico');
  
  const garatujasAlunoInput = document.getElementById('garatujasAlunoInput');
  const garatujasIdadeInput = document.getElementById('garatujasIdadeInput');
  const garatujaFileInput = document.getElementById('garatujaFileInput');
  const btnUploadGaratuja = document.getElementById('btnUploadGaratuja');
  const garatujaFileStatus = document.getElementById('garatujaFileStatus');
  const garatujaPreviewContainer = document.getElementById('garatujaPreviewContainer');
  const garatujaImgPreview = document.getElementById('garatujaImgPreview');
  
  const btnGenerateGaratuja = document.getElementById('btnGenerateGaratuja');
  const garatujaLoader = document.getElementById('garatujaLoader');
  const garatujaLoaderText = document.getElementById('garatujaLoaderText');
  const garatujaResultArea = document.getElementById('garatujaResultArea');
  const garatujaReportArea = document.getElementById('garatujaReportArea');
  
  const btnCopyGaratujaReport = document.getElementById('btnCopyGaratujaReport');
  const btnPdfGaratujaReport = document.getElementById('btnPdfGaratujaReport');
  const garatujasListContainer = document.getElementById('garatujasListContainer');
  const garatujasNoData = document.getElementById('garatujasNoData');
  
  let activeGaratujaReport = null;

  // Abas do Garatujas
  if (tabGaratujasNova) {
    tabGaratujasNova.addEventListener('click', () => {
      tabGaratujasNova.classList.add('active');
      tabGaratujasHistorico.classList.remove('active');
      contentGaratujasNova.style.display = 'block';
      contentGaratujasHistorico.style.display = 'none';
    });
  }

  if (tabGaratujasHistorico) {
    tabGaratujasHistorico.addEventListener('click', () => {
      tabGaratujasHistorico.classList.add('active');
      tabGaratujasNova.classList.remove('active');
      contentGaratujasNova.style.display = 'none';
      contentGaratujasHistorico.style.display = 'block';
      loadGaratujasHistory();
    });
  }

  // Abrir Modal
  if (barBtnGaratujas) {
    barBtnGaratujas.addEventListener('click', () => {
      garatujasModal.style.display = 'flex';
      garatujasAlunoInput.value = '';
      garatujaFileInput.value = '';
      garatujaFileStatus.textContent = 'Nenhum arquivo selecionado';
      garatujaPreviewContainer.style.display = 'none';
      garatujaResultArea.style.display = 'none';
      garatujaLoader.style.display = 'none';
      btnGenerateGaratuja.disabled = false;
      activeGaratujaReport = null;
      if (tabGaratujasNova) tabGaratujasNova.click();
    });
  }

  // Fechar Modal
  if (btnCloseGaratujasModal) {
    btnCloseGaratujasModal.addEventListener('click', () => {
      garatujasModal.style.display = 'none';
    });
  }

  window.addEventListener('click', (e) => {
    if (e.target === garatujasModal) {
      garatujasModal.style.display = 'none';
    }
  });

  // Upload trigger
  if (btnUploadGaratuja) {
    btnUploadGaratuja.addEventListener('click', () => {
      garatujaFileInput.click();
    });
  }

  if (garatujaFileInput) {
    garatujaFileInput.addEventListener('change', () => {
      const file = garatujaFileInput.files[0];
      if (file) {
        garatujaFileStatus.textContent = file.name;
        const reader = new FileReader();
        reader.onload = (e) => {
          garatujaImgPreview.src = e.target.result;
          garatujaPreviewContainer.style.display = 'block';
        };
        reader.readAsDataURL(file);
      } else {
        garatujaFileStatus.textContent = 'Nenhum arquivo selecionado';
        garatujaPreviewContainer.style.display = 'none';
      }
    });
  }

  // Gerar Análise
  if (btnGenerateGaratuja) {
    btnGenerateGaratuja.addEventListener('click', async () => {
      const alunoName = garatujasAlunoInput.value.trim();
      const alunoIdade = garatujasIdadeInput ? garatujasIdadeInput.value.trim() : '';
      const file = garatujaFileInput.files[0];

      if (!alunoName) {
        alert('Por favor, informe o nome do aluno.');
        return;
      }
      if (!file) {
        alert('Por favor, selecione a foto do desenho.');
        return;
      }

      btnGenerateGaratuja.disabled = true;
      garatujaLoader.style.display = 'flex';
      garatujaResultArea.style.display = 'none';
      garatujaLoaderText.textContent = 'Enviando imagem pedagógica...';

      const formData = new FormData();
      formData.append('alunoName', alunoName);
      if (alunoIdade) formData.append('alunoIdade', alunoIdade);
      formData.append('image', file);

      let statusMsgIdx = 0;
      const statusMessages = [
        'Carregando desenho infantil...',
        'IA escaneando os traços e formas...',
        'Analisando simetria e coordenação motora...',
        'Definindo estágio evolutivo do desenho...',
        'Criando sugestões de atividades formativas...',
        'Finalizando laudo psicopedagógico...'
      ];

      const statusInterval = setInterval(() => {
        if (statusMsgIdx < statusMessages.length) {
          garatujaLoaderText.textContent = statusMessages[statusMsgIdx];
          statusMsgIdx++;
        } else {
          garatujaLoaderText.textContent = 'Formatando parecer...';
        }
      }, 4500);

      try {
        const response = await fetch('/api/garatujas/analyze', {
          method: 'POST',
          body: formData
        });

        clearInterval(statusInterval);

        if (!response.ok) {
          const errData = await response.json();
          throw new Error(errData.error || 'Erro desconhecido');
        }

        const data = await response.json();
        activeGaratujaReport = data;

        if (window.marked) {
          garatujaReportArea.innerHTML = marked.parse(data.analise);
        } else {
          garatujaReportArea.textContent = data.analise;
        }

        garatujaLoader.style.display = 'none';
        garatujaResultArea.style.display = 'flex';
        btnGenerateGaratuja.disabled = false;

      } catch (err) {
        clearInterval(statusInterval);
        console.error(err);
        alert('Erro na análise: ' + err.message);
        garatujaLoader.style.display = 'none';
        btnGenerateGaratuja.disabled = false;
      }
    });
  }

  // Copiar Parecer Garatujas
  if (btnCopyGaratujaReport) {
    btnCopyGaratujaReport.addEventListener('click', () => {
      if (activeGaratujaReport && activeGaratujaReport.analise) {
        navigator.clipboard.writeText(activeGaratujaReport.analise)
          .then(() => {
            btnCopyGaratujaReport.textContent = '✅ Copiado!';
            setTimeout(() => { btnCopyGaratujaReport.textContent = '📋 Copiar'; }, 2000);
          });
      }
    });
  }

  // Baixar PDF Garatujas
  if (btnPdfGaratujaReport) {
    btnPdfGaratujaReport.addEventListener('click', () => {
      if (!activeGaratujaReport) return;
      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>Garatujas - Laudo do Desenho</title>
          <style>
            body { font-family: 'Outfit', 'Inter', sans-serif; padding: 40px; color: #333; line-height: 1.6; }
            h1, h2, h3 { color: #ea580c; margin-top: 24px; margin-bottom: 12px; }
            h1 { border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; font-size: 22px; }
            .meta-box { background: #f8fafc; padding: 16px; border-radius: 8px; margin-bottom: 24px; border: 1px solid #e2e8f0; display: flex; gap: 16px; align-items: center; }
            .meta-label { font-weight: bold; color: #475569; }
            img { border-radius: 6px; border: 1px solid #ddd; max-height: 120px; }
            @media print {
              body { padding: 0; }
              button { display: none; }
            }
          </style>
        </head>
        <body>
          <h1>🎨 Garatujas - Parecer de Traçado Infantil</h1>
          <div class="meta-box">
            <img src="${activeGaratujaReport.imageUrl}">
            <div>
              <div><span class="meta-label">Aluno(a):</span> <span>${activeGaratujaReport.alunoName}</span></div>
              <div><span class="meta-label">Data de Análise:</span> <span>${new Date(activeGaratujaReport.createdAt).toLocaleDateString('pt-BR')}</span></div>
            </div>
          </div>
          <div>${window.marked ? marked.parse(activeGaratujaReport.analise) : activeGaratujaReport.analise}</div>
          <script>
            window.onload = function() {
              window.print();
              setTimeout(() => { window.close(); }, 500);
            };
          <\/script>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // Carregar Histórico Garatujas
  async function loadGaratujasHistory() {
    try {
      const response = await fetch('/api/garatujas/list');
      if (!response.ok) throw new Error('Erro ao carregar histórico');
      const list = await response.json();

      garatujasListContainer.innerHTML = '';
      if (list.length === 0) {
        garatujasNoData.style.display = 'block';
        return;
      }
      garatujasNoData.style.display = 'none';

      list.forEach(item => {
        const div = document.createElement('div');
        div.className = 'quick-note-card';
        div.style.cursor = 'pointer';
        div.style.display = 'flex';
        div.style.flexDirection = 'column';
        div.style.gap = '8px';
        div.style.padding = '12px';
        
        div.innerHTML = `
          <div style="position: relative; width: 100%; aspect-ratio: 4/3; overflow: hidden; border-radius: 6px; background: rgba(0,0,0,0.2);">
            <img src="${item.imageUrl}" style="width: 100%; height: 100%; object-fit: cover;">
            <button class="delete-btn" data-id="${item.id}" style="position: absolute; top: 6px; right: 6px; background: rgba(0,0,0,0.5); border: none; width: 26px; height: 26px; border-radius: 50%; color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 0.8rem; transition: background 0.2s, transform 0.2s; z-index: 10;" title="Deletar análise" onmouseover="this.style.background='rgba(220,53,69,0.95)'; this.style.transform='scale(1.1)';" onmouseout="this.style.background='rgba(0,0,0,0.5)'; this.style.transform='scale(1)';">
              🗑️
            </button>
          </div>
          <div style="font-weight: 600; color: var(--text-primary); font-size: 0.9rem;">${escapeHtml(item.alunoName)}</div>
          <div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div>
        `;
        
        const deleteBtn = div.querySelector('.delete-btn');
        deleteBtn.addEventListener('click', async (e) => {
          e.stopPropagation();
          if (confirm(`Deseja realmente excluir a análise de desenho do aluno "${item.alunoName}"?`)) {
            try {
              const delResp = await fetch(`/api/garatujas/${item.id}`, { method: 'DELETE' });
              if (!delResp.ok) throw new Error('Falha ao deletar');
              alert('Análise deletada com sucesso.');
              loadGaratujasHistory();
              if (activeGaratujaReport && activeGaratujaReport.id === item.id) {
                activeGaratujaReport = null;
                garatujasAlunoInput.value = '';
                garatujaImgPreview.src = '';
                garatujaPreviewContainer.style.display = 'none';
                garatujaReportArea.innerHTML = '';
                garatujaResultArea.style.display = 'none';
              }
            } catch (err) {
              alert('Erro ao excluir análise: ' + err.message);
            }
          }
        });
        
        div.addEventListener('click', async () => {
          try {
            const detailResp = await fetch(`/api/garatujas/${item.id}`);
            if (!detailResp.ok) throw new Error('Erro ao obter detalhes');
            const detail = await detailResp.json();
            
            activeGaratujaReport = detail;
            garatujasAlunoInput.value = detail.alunoName;
            garatujaImgPreview.src = detail.imageUrl;
            garatujaPreviewContainer.style.display = 'block';
            garatujaReportArea.innerHTML = window.marked ? marked.parse(detail.analise) : detail.analise;
            
            garatujaResultArea.style.display = 'flex';
            if (tabGaratujasNova) tabGaratujasNova.click();
          } catch (e) {
            alert('Falha ao abrir desenho.');
          }
        });
        
        garatujasListContainer.appendChild(div);
      });
    } catch (err) {
      console.error(err);
    }
  }

  // ============================================================
  // ESTÚDIO DE POESIA
  // ============================================================
  // ESTÚDIO DE POESIAS (ESTÚDIO PROFISSIONAL)
  // ============================================================
  const poesiaModal = document.getElementById('poesiaModal');
  const btnClosePoesiaModal = document.getElementById('btnClosePoesiaModal');
  const barBtnPoesia = document.getElementById('barBtnPoesia');
  const btnOpenPoesiaHistory = document.getElementById('btnOpenPoesiaHistory');
  const poesiaHistoryModal = document.getElementById('poesiaHistoryModal');
  const btnClosePoesiaHistory = document.getElementById('btnClosePoesiaHistory');

  const poesiaTemplateSelect = document.getElementById('poesiaTemplateSelect');
  const poesiaTemaInput = document.getElementById('poesiaTemaInput');
  const poesiaTurmaSelect = document.getElementById('poesiaTurmaSelect');
  const poesiaFaixaEtaria = document.getElementById('poesiaFaixaEtaria');
  const poesiaEstruturaSelect = document.getElementById('poesiaEstruturaSelect');
  const poesiaEstiloSelect = document.getElementById('poesiaEstiloSelect');
  const poesiaVozSelect = document.getElementById('poesiaVozSelect');
  const btnGeneratePoesia = document.getElementById('btnGeneratePoesia');
  const poesiaGenerateLoader = document.getElementById('poesiaGenerateLoader');

  // Elementos do Painel Direito
  const poesiaBnccBadge = document.getElementById('poesiaBnccBadge');
  const poesiaMetricsBox = document.getElementById('poesiaMetricsBox');
  const poesiaEsquemaBadge = document.getElementById('poesiaEsquemaBadge');
  const poesiaMetricRimaVal = document.getElementById('poesiaMetricRimaVal');
  const poesiaMetricRimaBar = document.getElementById('poesiaMetricRimaBar');
  const poesiaMetricRitmoVal = document.getElementById('poesiaMetricRitmoVal');
  const poesiaMetricRitmoBar = document.getElementById('poesiaMetricRitmoBar');
  const poesiaMetricAliteracaoVal = document.getElementById('poesiaMetricAliteracaoVal');
  const poesiaMetricAliteracaoBar = document.getElementById('poesiaMetricAliteracaoBar');
  const poesiaMetricMusicalidadeVal = document.getElementById('poesiaMetricMusicalidadeVal');
  const poesiaMetricMusicalidadeBar = document.getElementById('poesiaMetricMusicalidadeBar');
  const poesiaMetricaDesc = document.getElementById('poesiaMetricaDesc');

  const poesiaAudioPlayerBox = document.getElementById('poesiaAudioPlayerBox');
  const poesiaAudioPlayer = document.getElementById('poesiaAudioPlayer');
  const poesiaPlayerTitle = document.getElementById('poesiaPlayerTitle');
  const btnDownloadPoesiaAudio = document.getElementById('btnDownloadPoesiaAudio');

  const poesiaContentTabs = document.getElementById('poesiaContentTabs');
  const btnTabPoesiaOriginal = document.getElementById('btnTabPoesiaOriginal');
  const btnTabPoesiaFonetica = document.getElementById('btnTabPoesiaFonetica');
  const btnTabPoesiaPedagogica = document.getElementById('btnTabPoesiaPedagogica');

  const poesiaPlaceholderText = document.getElementById('poesiaPlaceholderText');
  const poesiaActiveBox = document.getElementById('poesiaActiveBox');
  const poesiaActiveTitle = document.getElementById('poesiaActiveTitle');
  const poesiaActiveSubtitle = document.getElementById('poesiaActiveSubtitle');
  const poesiaActiveContent = document.getElementById('poesiaActiveContent');
  const poesiaPedagogicalTipBox = document.getElementById('poesiaPedagogicalTipBox');
  const poesiaPedagogicalTipText = document.getElementById('poesiaPedagogicalTipText');

  const btnCopyActivePoesia = document.getElementById('btnCopyActivePoesia');
  const btnDownloadActivePoesiaTxt = document.getElementById('btnDownloadActivePoesiaTxt');
  const btnSendPoesiaToMusic = document.getElementById('btnSendPoesiaToMusic');
  const btnExportActivePoesiaPdf = document.getElementById('btnExportActivePoesiaPdf');

  let selectedPoesiaEstrofes = 3;
  let activePoesiaTab = 'original';

  // TEMPLATES TEMÁTICOS DO ESTÚDIO DE POESIAS
  const POESIA_TEMPLATES = {
    horta: {
      tema: "Plantar sementinhas na horta da escola, regar a terra com carinho, ver os brotinhos crescerem e colher vegetais coloridos e saudáveis.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      estrutura: "Quadras (Rimas A-B-A-B)",
      estilo: "Lúdico-cantado e sonoro",
      voz: "mulher",
      estrofes: 3
    },
    animais: {
      tema: "Os bichinhos da fazenda, o canto do galo pela manhã, a vaquinha mimosa, o cachorrinho amigo e as onomatopeias dos sons dos animais.",
      faixa: "Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)",
      estrutura: "Quadras (Rimas A-B-A-B)",
      estilo: "Lúdico-cantado e sonoro",
      voz: "mulher",
      estrofes: 3
    },
    familia: {
      tema: "O abraço quentinho da família, o carinho ao chegar em casa, os beijinhos de boa noite e o afeto entre pais, avós e irmãos.",
      faixa: "Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)",
      estrutura: "Redondilhas (7 sílabas poéticas)",
      estilo: "Sensorial, suave e afetivo",
      voz: "mulher",
      estrofes: 3
    },
    higiene: {
      tema: "Bolhas de sabão lavando as mãozinhas, a escova de dentes dançando na boca e o cheirinho gostoso de banho tomado.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      estrutura: "Quadras (Rimas A-B-A-B)",
      estilo: "Lúdico-cantado e sonoro",
      voz: "crianca",
      estrofes: 3
    },
    chuva: {
      tema: "As gotinhas de chuva batendo ploc-ploc no telhado, o cheiro de terra molhada e a dança com guarda-chuva colorido.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      estrutura: "Redondilhas (7 sílabas poéticas)",
      estilo: "Sensorial, suave e afetivo",
      voz: "mulher",
      estrofes: 3
    },
    alfabeto: {
      tema: "As letrinhas encantadas brincando no papel, as rimas das vogais e a mágica de escrever o primeiro nome.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      estrutura: "Quadras (Rimas A-B-A-B)",
      estilo: "Narrativo-infantil com história",
      voz: "mulher",
      estrofes: 4
    },
    cores: {
      tema: "O azul do céu infinito, o amarelo do sol brilhante, o verde das folhinhas e a aquarela das cores na pintura com os dedinhos.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      estrutura: "Haiku Infantil (5-7-5 sílabas)",
      estilo: "Sensorial, suave e afetivo",
      voz: "mulher",
      estrofes: 3
    }
  };

  // Estado da poesia ativa
  let activePoesiaData = {
    titulo: '',
    poesia: '',
    versaoFonetica: '',
    esquemaRima: '',
    analiseLiteraria: { rima: 80, ritmo: 80, aliteracao: 60, musicalidade: 85, explicacaoMetrica: '' },
    bnccCampos: '',
    dicas: '',
    audioUrl: '',
    tema: '',
    estrutura: '',
    estilo: '',
    faixaEtaria: ''
  };

  // Botões de contagem de estrofes
  document.querySelectorAll('.btn-poesia-estrofes').forEach(btn => {
    btn.addEventListener('click', (e) => {
      document.querySelectorAll('.btn-poesia-estrofes').forEach(b => b.classList.remove('active'));
      e.target.classList.add('active');
      selectedPoesiaEstrofes = parseInt(e.target.dataset.estrofes);
    });
  });

  // Carregar turmas no seletor do estúdio de poesia
  const loadTurmasForPoesia = async () => {
    if (!poesiaTurmaSelect) return;
    try {
      const res = await fetch('/api/turmas');
      if (res.ok) {
        const turmas = await res.json();
        poesiaTurmaSelect.innerHTML = '<option value="">-- Selecionar Turma --</option>';
        turmas.forEach(t => {
          const opt = document.createElement('option');
          opt.value = t.id;
          opt.textContent = `${t.nome} (${t.ano || '2026'})`;
          poesiaTurmaSelect.appendChild(opt);
        });
      }
    } catch (err) {
      console.warn('Erro ao carregar turmas para poesia:', err);
    }
  };

  // Abrir Modal
  if (barBtnPoesia) {
    barBtnPoesia.addEventListener('click', () => {
      poesiaModal.style.display = 'flex';
      loadTurmasForPoesia();
      if (!poesiaTemaInput.value) {
        applyPoesiaTemplate('horta');
      }
    });
  }

  if (btnClosePoesiaModal) {
    btnClosePoesiaModal.addEventListener('click', () => {
      poesiaModal.style.display = 'none';
      if (poesiaAudioPlayer) poesiaAudioPlayer.pause();
    });
  }

  poesiaModal.addEventListener('click', (e) => {
    if (e.target === poesiaModal) {
      poesiaModal.style.display = 'none';
      if (poesiaAudioPlayer) poesiaAudioPlayer.pause();
    }
  });

  // Aplicar Template
  const applyPoesiaTemplate = (key) => {
    const tmpl = POESIA_TEMPLATES[key];
    if (!tmpl) return;

    if (poesiaTemaInput) poesiaTemaInput.value = tmpl.tema;
    if (poesiaFaixaEtaria) poesiaFaixaEtaria.value = tmpl.faixa;
    if (poesiaEstruturaSelect) poesiaEstruturaSelect.value = tmpl.estrutura;
    if (poesiaEstiloSelect) poesiaEstiloSelect.value = tmpl.estilo;
    if (poesiaVozSelect) poesiaVozSelect.value = tmpl.voz;

    // Atualizar botões de estrofes
    document.querySelectorAll('.btn-poesia-estrofes').forEach(b => {
      const isMatch = parseInt(b.dataset.estrofes) === tmpl.estrofes;
      b.classList.toggle('active', isMatch);
      if (isMatch) selectedPoesiaEstrofes = tmpl.estrofes;
    });
  };

  if (poesiaTemplateSelect) {
    poesiaTemplateSelect.addEventListener('change', (e) => {
      if (e.target.value) {
        applyPoesiaTemplate(e.target.value);
      }
    });
  }

  // Alternar Abas no Painel Direito
  const switchPoesiaTab = (tab) => {
    activePoesiaTab = tab;
    [btnTabPoesiaOriginal, btnTabPoesiaFonetica, btnTabPoesiaPedagogica].forEach(b => {
      if (b) {
        b.classList.remove('active');
        b.style.background = 'transparent';
        b.style.color = 'var(--text-secondary)';
      }
    });

    let currentContent = '';
    let subtitleText = `${activePoesiaData.estrutura || 'Quadras'} • ${activePoesiaData.esquemaRima || 'A-B-A-B'}`;

    if (tab === 'original') {
      if (btnTabPoesiaOriginal) {
        btnTabPoesiaOriginal.classList.add('active');
        btnTabPoesiaOriginal.style.background = 'rgba(234,179,8,0.15)';
        btnTabPoesiaOriginal.style.color = '#fbbf24';
      }
      currentContent = activePoesiaData.poesia;
    } else if (tab === 'fonetica') {
      if (btnTabPoesiaFonetica) {
        btnTabPoesiaFonetica.classList.add('active');
        btnTabPoesiaFonetica.style.background = 'rgba(234,179,8,0.15)';
        btnTabPoesiaFonetica.style.color = '#fbbf24';
      }
      currentContent = activePoesiaData.versaoFonetica || activePoesiaData.poesia;
      subtitleText = '🗣️ Guia Fonético com Sílabas Tônicas e Pausas Rítmicas';
    } else if (tab === 'pedagogica') {
      if (btnTabPoesiaPedagogica) {
        btnTabPoesiaPedagogica.classList.add('active');
        btnTabPoesiaPedagogica.style.background = 'rgba(234,179,8,0.15)';
        btnTabPoesiaPedagogica.style.color = '#fbbf24';
      }
      currentContent = `📚 Campo de Experiência BNCC:\n${activePoesiaData.bnccCampos}\n\n💡 Vivência em Sala de Aula:\n${activePoesiaData.dicas || 'Recite o poema em roda incentivando as crianças a acompanharem o ritmo com palmas.'}`;
      subtitleText = '💡 Vivência Pedagógica & Alinhamento BNCC';
    }

    if (poesiaActiveSubtitle) poesiaActiveSubtitle.textContent = subtitleText;
    if (poesiaActiveContent) {
      if (tab === 'fonetica') {
        // Converte **palavra** em negrito no HTML
        const formatted = currentContent.replace(/\*\*(.*?)\*\*/g, '<strong style="color: #fbbf24; text-decoration: underline;">$1</strong>');
        poesiaActiveContent.innerHTML = formatted;
      } else {
        poesiaActiveContent.textContent = currentContent;
      }
    }
  };

  if (btnTabPoesiaOriginal) btnTabPoesiaOriginal.addEventListener('click', () => switchPoesiaTab('original'));
  if (btnTabPoesiaFonetica) btnTabPoesiaFonetica.addEventListener('click', () => switchPoesiaTab('fonetica'));
  if (btnTabPoesiaPedagogica) btnTabPoesiaPedagogica.addEventListener('click', () => switchPoesiaTab('pedagogica'));

  // Equalizer visualizer quando o áudio recitado toca
  if (poesiaAudioPlayer) {
    poesiaAudioPlayer.addEventListener('play', () => {
      const bars = document.querySelectorAll('#poesiaWaveformVisualizer .wave-bar');
      bars.forEach(b => b.classList.add('wave-active'));
    });
    poesiaAudioPlayer.addEventListener('pause', () => {
      const bars = document.querySelectorAll('#poesiaWaveformVisualizer .wave-bar');
      bars.forEach(b => b.classList.remove('wave-active'));
    });
  }

  // --- GERAR POESIA (ANÁLISE LITERÁRIA + ÁUDIO RECITADO) ---
  if (btnGeneratePoesia) {
    btnGeneratePoesia.addEventListener('click', async () => {
      const tema = (poesiaTemaInput?.value || '').trim();
      if (!tema) {
        await showCustomAlert('Aviso', 'Por favor, informe a ideia ou tema da poesia.');
        return;
      }

      btnGeneratePoesia.disabled = true;
      if (poesiaGenerateLoader) poesiaGenerateLoader.style.display = 'flex';

      try {
        const res = await fetch('/api/poesias/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            tema,
            faixaEtaria: poesiaFaixaEtaria?.value,
            estrofes: selectedPoesiaEstrofes,
            estrutura: poesiaEstruturaSelect?.value || 'Quadras (Rimas A-B-A-B)',
            estilo: poesiaEstiloSelect?.value || 'Lúdico-cantado e sonoro',
            voz: poesiaVozSelect?.value || 'mulher',
            turmaId: poesiaTurmaSelect?.value || null,
            gerarAudio: true
          })
        });

        const data = await res.json();

        if (res.ok && data.success) {
          activePoesiaData = {
            titulo: data.titulo || `Poema: ${tema}`,
            poesia: data.poesia,
            versaoFonetica: data.versaoFonetica,
            esquemaRima: data.esquemaRima || 'A-B-A-B',
            analiseLiteraria: data.analiseLiteraria || { rima: 85, ritmo: 80, aliteracao: 65, musicalidade: 90 },
            bnccCampos: data.bnccCampos || 'EI02EF01 / EI03EF02 • Escuta, Fala, Pensamento e Imaginação',
            dicas: data.dicasPedagogicas || '',
            audioUrl: data.audioUrl,
            tema: tema,
            estrutura: data.estrutura || poesiaEstruturaSelect?.value,
            estilo: data.estilo || poesiaEstiloSelect?.value,
            faixaEtaria: data.faixaEtaria || poesiaFaixaEtaria?.value
          };

          // Atualizar Interface
          if (poesiaPlaceholderText) poesiaPlaceholderText.style.display = 'none';
          if (poesiaMetricsBox) poesiaMetricsBox.style.display = 'flex';
          if (poesiaContentTabs) poesiaContentTabs.style.display = 'flex';
          if (poesiaActiveBox) poesiaActiveBox.style.display = 'flex';

          if (poesiaActiveTitle) poesiaActiveTitle.textContent = activePoesiaData.titulo;
          if (poesiaBnccBadge) {
            poesiaBnccBadge.textContent = `BNCC: ${activePoesiaData.bnccCampos.split('•')[0].trim()}`;
            poesiaBnccBadge.style.display = 'inline-block';
          }
          if (poesiaEsquemaBadge) {
            poesiaEsquemaBadge.textContent = `Esquema: ${activePoesiaData.esquemaRima}`;
          }

          // Atualizar Barras de Métricas Literárias
          const metrics = activePoesiaData.analiseLiteraria;
          if (poesiaMetricRimaVal) poesiaMetricRimaVal.textContent = `${metrics.rima || 85}%`;
          if (poesiaMetricRimaBar) poesiaMetricRimaBar.style.width = `${metrics.rima || 85}%`;

          if (poesiaMetricRitmoVal) poesiaMetricRitmoVal.textContent = `${metrics.ritmo || 80}%`;
          if (poesiaMetricRitmoBar) poesiaMetricRitmoBar.style.width = `${metrics.ritmo || 80}%`;

          if (poesiaMetricAliteracaoVal) poesiaMetricAliteracaoVal.textContent = `${metrics.aliteracao || 65}%`;
          if (poesiaMetricAliteracaoBar) poesiaMetricAliteracaoBar.style.width = `${metrics.aliteracao || 65}%`;

          if (poesiaMetricMusicalidadeVal) poesiaMetricMusicalidadeVal.textContent = `${metrics.musicalidade || 90}%`;
          if (poesiaMetricMusicalidadeBar) poesiaMetricMusicalidadeBar.style.width = `${metrics.musicalidade || 90}%`;

          if (poesiaMetricaDesc && metrics.explicacaoMetrica) {
            poesiaMetricaDesc.textContent = metrics.explicacaoMetrica;
          }

          if (poesiaPedagogicalTipText && activePoesiaData.dicas) {
            poesiaPedagogicalTipText.textContent = activePoesiaData.dicas;
            poesiaPedagogicalTipBox.style.display = 'block';
          }

          // Áudio Recitado
          if (data.audioUrl) {
            poesiaAudioPlayer.src = data.audioUrl;
            if (poesiaPlayerTitle) poesiaPlayerTitle.textContent = activePoesiaData.titulo;
            if (btnDownloadPoesiaAudio) btnDownloadPoesiaAudio.href = data.audioUrl;
            if (poesiaAudioPlayerBox) poesiaAudioPlayerBox.style.display = 'flex';
          } else {
            if (poesiaAudioPlayerBox) poesiaAudioPlayerBox.style.display = 'none';
          }

          switchPoesiaTab('original');
          showToast('Poesia pedagógica e métricas geradas com sucesso!', 'success');

        } else {
          await showCustomAlert('Erro', data.error || 'Erro ao gerar poesia.');
        }

      } catch (err) {
        console.error('Erro ao compor poesia:', err);
        await showCustomAlert('Erro', 'Não foi possível conectar ao servidor: ' + err.message);
      } finally {
        btnGeneratePoesia.disabled = false;
        if (poesiaGenerateLoader) poesiaGenerateLoader.style.display = 'none';
      }
    });
  }

  // Copiar Poema Ativo
  if (btnCopyActivePoesia) {
    btnCopyActivePoesia.addEventListener('click', () => {
      const text = activePoesiaData.poesia || '';
      if (text) {
        navigator.clipboard.writeText(`${activePoesiaData.titulo}\n\n${text}`);
        showToast('Poema copiado para a área de transferência!', 'success');
      }
    });
  }

  // Baixar Poema TXT
  if (btnDownloadActivePoesiaTxt) {
    btnDownloadActivePoesiaTxt.addEventListener('click', () => {
      const text = activePoesiaData.poesia || '';
      if (!text) return;
      const content = `POESIA PEDAGÓGICA - PEDAGOGIA\n========================================\nTítulo: ${activePoesiaData.titulo}\nFaixa Etária: ${activePoesiaData.faixaEtaria}\nEstrutura: ${activePoesiaData.estrutura}\nEsquema de Rima: ${activePoesiaData.esquemaRima}\nBNCC: ${activePoesiaData.bnccCampos}\n========================================\n\n${text}\n\n----------------------------------------\nGuia de Leitura / Fonética:\n${activePoesiaData.versaoFonetica}\n\n----------------------------------------\nVivência Pedagógica:\n${activePoesiaData.dicas}\n`;
      const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = `poema_${(activePoesiaData.titulo || 'poesia').replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase()}.txt`;
      document.body.appendChild(link);
      link.click();
      link.remove();
    });
  }

  // Enviar Poema ao Musicando Ideias
  if (btnSendPoesiaToMusic) {
    btnSendPoesiaToMusic.addEventListener('click', () => {
      poesiaModal.style.display = 'none';
      const barBtnMusica = document.getElementById('barBtnMusica');
      const musicaModal = document.getElementById('musicaModal');
      const musicaTemaInput = document.getElementById('musicaTemaInput');
      if (musicaModal && musicaTemaInput) {
        musicaModal.style.display = 'flex';
        musicaTemaInput.value = `Musicar a poesia "${activePoesiaData.titulo}": ${activePoesiaData.poesia.substring(0, 200)}...`;
        showToast('Poema transferido para o Estúdio de Música!', 'success');
      }
    });
  }

  // Exportar PDF Ilustrado Formatado
  if (btnExportActivePoesiaPdf) {
    btnExportActivePoesiaPdf.addEventListener('click', () => {
      const text = activePoesiaData.poesia || '';
      if (!text) return;

      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>${activePoesiaData.titulo} - PedaGog</title>
          <link rel="preconnect" href="https://fonts.googleapis.com">
          <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
          <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
          <style>
            body { font-family: 'Fredoka', 'Outfit', sans-serif; padding: 40px; color: #1e293b; background: #fffdf8; line-height: 1.8; }
            .header-box { border-bottom: 3px dashed #eab308; padding-bottom: 16px; margin-bottom: 24px; }
            h1 { color: #ca8a04; margin: 0 0 8px 0; font-size: 2rem; }
            .meta-tags { display: flex; gap: 12px; font-size: 0.9rem; color: #64748b; font-weight: 600; margin-bottom: 8px; flex-wrap: wrap; }
            .meta-tag { background: #fef9c3; color: #a16207; padding: 4px 10px; border-radius: 6px; }
            .poetry-box { font-size: 1.25rem; background: #ffffff; padding: 28px; border-radius: 12px; border: 1px solid #fef08a; white-space: pre-wrap; margin-bottom: 24px; box-shadow: 0 4px 6px rgba(0,0,0,0.02); }
            .metrics-box { background: #f8fafc; border: 1px solid #e2e8f0; padding: 14px 18px; border-radius: 8px; font-size: 0.85rem; color: #475569; margin-bottom: 20px; }
            .tip-box { background: #fefce8; border: 1px solid #fde047; color: #854d0e; padding: 14px 18px; border-radius: 8px; font-size: 0.92rem; }
            @media print { body { padding: 20px; } button { display: none; } }
          </style>
        </head>
        <body>
          <div style="max-width: 750px; margin: 0 auto;">
            <div class="header-box">
              <div style="display: flex; justify-content: space-between; align-items: flex-start;">
                <div>
                  <h1>📜 ${activePoesiaData.titulo}</h1>
                  <div class="meta-tags">
                    <span class="meta-tag">👶 ${activePoesiaData.faixaEtaria}</span>
                    <span class="meta-tag">📐 ${activePoesiaData.estrutura}</span>
                    <span class="meta-tag">📚 ${activePoesiaData.bnccCampos.split('•')[0]}</span>
                  </div>
                </div>
                <button onclick="window.print()" style="background: #eab308; color: #1e293b; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-weight: bold; font-family: sans-serif;">🖨️ Imprimir / Salvar PDF</button>
              </div>
            </div>
            
            <div class="poetry-box">${text}</div>

            <div class="metrics-box">
              <strong>📊 Análise Métrica:</strong> Rima: ${activePoesiaData.analiseLiteraria.rima}% | Ritmo: ${activePoesiaData.analiseLiteraria.ritmo}% | Musicalidade: ${activePoesiaData.analiseLiteraria.musicalidade}% (Esquema: ${activePoesiaData.esquemaRima})
            </div>

            ${activePoesiaData.dicas ? `
            <div class="tip-box">
              💡 <strong>Vivência Pedagógica / Roda de Leitura:</strong><br>
              ${activePoesiaData.dicas}
            </div>` : ''}
            
            <div style="margin-top: 30px; text-align: center; font-size: 0.8rem; color: #94a3b8; border-top: 1px solid #e2e8f0; padding-top: 10px;">
              Estúdio de Poesias • PedagogIA • Assistente Pedagógica da Professora Camila
            </div>
          </div>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // --- HISTÓRICO DE POESIAS ---
  if (btnOpenPoesiaHistory) {
    btnOpenPoesiaHistory.addEventListener('click', () => {
      poesiaHistoryModal.style.display = 'flex';
      loadPoesiaHistory();
    });
  }

  if (btnClosePoesiaHistory) {
    btnClosePoesiaHistory.addEventListener('click', () => {
      poesiaHistoryModal.style.display = 'none';
    });
  }

  poesiaHistoryModal.addEventListener('click', (e) => {
    if (e.target === poesiaHistoryModal) {
      poesiaHistoryModal.style.display = 'none';
    }
  });

  async function loadPoesiaHistory() {
    const listContainer = document.getElementById('poesiaHistoryList');
    if (!listContainer) return;
    listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando histórico...</p>';
    
    try {
      const response = await fetch('/api/poesias/list');
      const data = await response.json();
      if (data && data.length > 0) {
        listContainer.innerHTML = '';
        data.forEach(item => {
          const date = new Date(item.created_at).toLocaleString('pt-BR');
          const div = document.createElement('div');
          div.className = 'history-item-card';
          div.style.cssText = 'background: rgba(255,255,255,0.03); padding: 14px; border-radius: 10px; border: 1px solid var(--border-light); display: flex; flex-direction: column; gap: 8px; cursor: pointer; position: relative; transition: all 0.2s;';
          div.innerHTML = `
            <div style="display: flex; justify-content: space-between; align-items: flex-start; padding-right: 30px;">
              <strong style="color: #fbbf24; font-size: 0.95rem;">${item.faixa_etaria} (${item.estrofes} Estrofes)</strong>
              <span style="font-size: 0.72rem; color: var(--text-secondary);">${date}</span>
            </div>
            <p style="margin: 0; font-size: 0.85rem; color: var(--text-primary); opacity: 0.9;"><strong>Tema:</strong> ${item.tema}</p>
            ${item.audio_url ? `
              <div style="display: flex; align-items: center; gap: 8px; margin-top: 4px;">
                <span style="font-size: 0.75rem; color: #10b981; font-weight: 600;">🎙️ Áudio Recitado Disponível</span>
              </div>
            ` : ''}
            <button class="btn-delete-poesia" data-id="${item.id}" style="position: absolute; top: 12px; right: 12px; background: transparent; border: none; color: #ef4444; cursor: pointer; font-size: 1.1rem; padding: 4px; border-radius: 4px;" title="Excluir Poesia">🗑️</button>
          `;
          
          div.addEventListener('click', async (e) => {
            if (e.target.closest('.btn-delete-poesia')) {
              e.stopPropagation();
              if (confirm('Tem certeza que deseja excluir esta poesia do histórico?')) {
                try {
                  const delRes = await fetch(`/api/poesias/${item.id}`, { method: 'DELETE' });
                  if (delRes.ok) {
                    showToast('Poesia excluída do histórico.', 'success');
                    loadPoesiaHistory();
                  }
                } catch (err) {
                  showToast('Erro ao excluir poesia.', 'error');
                }
              }
              return;
            }

            // Carregar poesia clicada
            try {
              const res = await fetch(`/api/poesias/${item.id}`);
              const detail = await res.json();
              if (res.ok) {
                activePoesiaData = {
                  titulo: `Poema: ${detail.tema}`,
                  poesia: detail.poesia,
                  versaoFonetica: detail.versao_fonetica || detail.poesia,
                  esquemaRima: 'A-B-A-B',
                  analiseLiteraria: typeof detail.analise_metrica === 'string' ? JSON.parse(detail.analise_metrica) : (detail.analise_metrica || { rima: 85, ritmo: 80, aliteracao: 65, musicalidade: 90 }),
                  bnccCampos: detail.bncc || 'EI02EF01 / EI03EF02 • Escuta, Fala, Pensamento e Imaginação',
                  dicas: detail.dicas || '',
                  audioUrl: detail.audio_url,
                  tema: detail.tema,
                  estrutura: detail.estrutura || 'Quadras',
                  estilo: detail.estilo || 'Lúdico-cantado',
                  faixaEtaria: detail.faixa_etaria
                };

                if (poesiaPlaceholderText) poesiaPlaceholderText.style.display = 'none';
                if (poesiaMetricsBox) poesiaMetricsBox.style.display = 'flex';
                if (poesiaContentTabs) poesiaContentTabs.style.display = 'flex';
                if (poesiaActiveBox) poesiaActiveBox.style.display = 'flex';

                if (poesiaActiveTitle) poesiaActiveTitle.textContent = activePoesiaData.titulo;
                if (detail.audio_url) {
                  poesiaAudioPlayer.src = detail.audio_url;
                  if (btnDownloadPoesiaAudio) btnDownloadPoesiaAudio.href = detail.audio_url;
                  if (poesiaAudioPlayerBox) poesiaAudioPlayerBox.style.display = 'flex';
                } else {
                  if (poesiaAudioPlayerBox) poesiaAudioPlayerBox.style.display = 'none';
                }

                switchPoesiaTab('original');
                poesiaHistoryModal.style.display = 'none';
              }
            } catch (err) {
              showToast('Erro ao carregar detalhes da poesia.', 'error');
            }
          });

          listContainer.appendChild(div);
        });
      } else {
        listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary); padding: 20px;">Nenhuma poesia gerada até o momento.</p>';
      }
    } catch (err) {
      listContainer.innerHTML = '<p style="text-align:center; color:#ef4444;">Erro ao carregar histórico de poesias.</p>';
    }
  }

  // ============================================================
  // BRINCARATIVO (CIRCUITOS PSICOMOTORES E BRINCADEIRAS)
  // ============================================================
  const brincarAtivoModal = document.getElementById('brincarAtivoModal');
  const btnCloseBrincarAtivoModal = document.getElementById('btnCloseBrincarAtivoModal');
  const barBtnBrincarAtivo = document.getElementById('barBtnBrincarAtivo');
  
  const tabBrincarAtivoNova = document.getElementById('tabBrincarAtivoNova');
  const tabBrincarAtivoHistorico = document.getElementById('tabBrincarAtivoHistorico');
  const contentBrincarAtivoNova = document.getElementById('contentBrincarAtivoNova');
  const contentBrincarAtivoHistorico = document.getElementById('contentBrincarAtivoHistorico');
  
  const brincarAtivoFaixaSelect = document.getElementById('brincarAtivoFaixaSelect');
  const brincarAtivoRecursosInput = document.getElementById('brincarAtivoRecursosInput');
  const btnGenerateBrincarAtivo = document.getElementById('btnGenerateBrincarAtivo');
  const brincarAtivoLoader = document.getElementById('brincarAtivoLoader');
  const brincarAtivoLoaderText = document.getElementById('brincarAtivoLoaderText');
  const brincarAtivoResultArea = document.getElementById('brincarAtivoResultArea');
  const brincarAtivoReportArea = document.getElementById('brincarAtivoReportArea');
  
  const btnCopyBrincarAtivoReport = document.getElementById('btnCopyBrincarAtivoReport');
  const btnPdfBrincarAtivoReport = document.getElementById('btnPdfBrincarAtivoReport');
  const brincarAtivoListContainer = document.getElementById('brincarAtivoListContainer');
  const brincarAtivoNoData = document.getElementById('brincarAtivoNoData');
  
  let activeBrincarAtivoReport = null;

  // Abas do BrincarAtivo
  if (tabBrincarAtivoNova) {
    tabBrincarAtivoNova.addEventListener('click', () => {
      tabBrincarAtivoNova.classList.add('active');
      tabBrincarAtivoHistorico.classList.remove('active');
      contentBrincarAtivoNova.style.display = 'block';
      contentBrincarAtivoHistorico.style.display = 'none';
    });
  }

  if (tabBrincarAtivoHistorico) {
    tabBrincarAtivoHistorico.addEventListener('click', () => {
      tabBrincarAtivoHistorico.classList.add('active');
      tabBrincarAtivoNova.classList.remove('active');
      contentBrincarAtivoNova.style.display = 'none';
      contentBrincarAtivoHistorico.style.display = 'block';
      loadBrincarAtivoHistory();
    });
  }

  // Abrir Modal
  if (barBtnBrincarAtivo) {
    barBtnBrincarAtivo.addEventListener('click', () => {
      brincarAtivoModal.style.display = 'flex';
      brincarAtivoRecursosInput.value = '';
      brincarAtivoResultArea.style.display = 'none';
      brincarAtivoLoader.style.display = 'none';
      btnGenerateBrincarAtivo.disabled = false;
      activeBrincarAtivoReport = null;
      if (tabBrincarAtivoNova) tabBrincarAtivoNova.click();
    });
  }

  // Fechar Modal
  if (btnCloseBrincarAtivoModal) {
    btnCloseBrincarAtivoModal.addEventListener('click', () => {
      brincarAtivoModal.style.display = 'none';
    });
  }

  window.addEventListener('click', (e) => {
    if (e.target === brincarAtivoModal) {
      brincarAtivoModal.style.display = 'none';
    }
  });

  // Gerar Atividade
  if (btnGenerateBrincarAtivo) {
    btnGenerateBrincarAtivo.addEventListener('click', async () => {
      const faixaEtaria = brincarAtivoFaixaSelect.value;
      const recursos = brincarAtivoRecursosInput.value.trim();

      if (!recursos) {
        alert('Por favor, informe os materiais ou recursos disponíveis.');
        return;
      }

      btnGenerateBrincarAtivo.disabled = true;
      brincarAtivoLoader.style.display = 'flex';
      brincarAtivoResultArea.style.display = 'none';
      brincarAtivoLoaderText.textContent = 'Acessando referências BNCC...';

      let statusMsgIdx = 0;
      const statusMessages = [
        'Analisando faixa etária psicomotora...',
        'Estruturando proposta lúdica de circuito...',
        'Conectando objetivos específicos da BNCC...',
        'Gerando instruções passo a passo para o professor...',
        'Finalizando plano de circuito ativo...'
      ];

      const statusInterval = setInterval(() => {
        if (statusMsgIdx < statusMessages.length) {
          brincarAtivoLoaderText.textContent = statusMessages[statusMsgIdx];
          statusMsgIdx++;
        } else {
          brincarAtivoLoaderText.textContent = 'Formatando atividade...';
        }
      }, 4500);

      try {
        const response = await fetch('/api/brincar-ativo/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ faixaEtaria, recursos })
        });

        clearInterval(statusInterval);

        if (!response.ok) {
          const errData = await response.json();
          throw new Error(errData.error || 'Erro desconhecido');
        }

        const data = await response.json();
        activeBrincarAtivoReport = data;

        if (window.marked) {
          brincarAtivoReportArea.innerHTML = marked.parse(data.atividade);
        } else {
          brincarAtivoReportArea.textContent = data.atividade;
        }

        brincarAtivoLoader.style.display = 'none';
        brincarAtivoResultArea.style.display = 'flex';
        btnGenerateBrincarAtivo.disabled = false;

      } catch (err) {
        clearInterval(statusInterval);
        console.error(err);
        alert('Erro ao gerar atividade: ' + err.message);
        brincarAtivoLoader.style.display = 'none';
        btnGenerateBrincarAtivo.disabled = false;
      }
    });
  }

  // Copiar Parecer BrincarAtivo
  if (btnCopyBrincarAtivoReport) {
    btnCopyBrincarAtivoReport.addEventListener('click', () => {
      if (activeBrincarAtivoReport && activeBrincarAtivoReport.atividade) {
        navigator.clipboard.writeText(activeBrincarAtivoReport.atividade)
          .then(() => {
            btnCopyBrincarAtivoReport.textContent = '✅ Copiado!';
            setTimeout(() => { btnCopyBrincarAtivoReport.textContent = '📋 Copiar'; }, 2000);
          });
      }
    });
  }

  // Baixar PDF BrincarAtivo
  if (btnPdfBrincarAtivoReport) {
    btnPdfBrincarAtivoReport.addEventListener('click', () => {
      if (!activeBrincarAtivoReport) return;
      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>BrincarAtivo - Roteiro de Circuito</title>
          <style>
            body { font-family: 'Outfit', 'Inter', sans-serif; padding: 40px; color: #333; line-height: 1.6; }
            h1, h2, h3 { color: #10a37f; margin-top: 24px; margin-bottom: 12px; }
            h1 { border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; font-size: 22px; }
            .meta-box { background: #f8fafc; padding: 16px; border-radius: 8px; margin-bottom: 24px; border: 1px solid #e2e8f0; }
            .meta-label { font-weight: bold; color: #475569; }
            @media print {
              body { padding: 0; }
              button { display: none; }
            }
          </style>
        </head>
        <body>
          <h1>🏃‍♂️ BrincarAtivo - Planejamento Psicomotor</h1>
          <div class="meta-box">
            <div><span class="meta-label">Faixa Etária:</span> <span>${activeBrincarAtivoReport.faixaEtaria}</span></div>
            <div><span class="meta-label">Recursos:</span> <span>${activeBrincarAtivoReport.recursos}</span></div>
            <div><span class="meta-label">Data de Criação:</span> <span>${new Date(activeBrincarAtivoReport.createdAt).toLocaleDateString('pt-BR')}</span></div>
          </div>
          <div>${window.marked ? marked.parse(activeBrincarAtivoReport.atividade) : activeBrincarAtivoReport.atividade}</div>
          <script>
            window.onload = function() {
              window.print();
              setTimeout(() => { window.close(); }, 500);
            };
          <\/script>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // Carregar Histórico BrincarAtivo
  async function loadBrincarAtivoHistory() {
    try {
      const response = await fetch('/api/brincar-ativo/list');
      if (!response.ok) throw new Error('Erro ao carregar histórico');
      const list = await response.json();

      brincarAtivoListContainer.innerHTML = '';
      if (list.length === 0) {
        brincarAtivoNoData.style.display = 'block';
        return;
      }
      brincarAtivoNoData.style.display = 'none';

      list.forEach(item => {
        const div = document.createElement('div');
        div.className = 'quick-note-card';
        div.style.cursor = 'pointer';
        div.style.display = 'flex';
        div.style.flexDirection = 'column';
        div.style.gap = '6px';
        div.style.padding = '12px';
        
        const lines = item.recursos || '';
        const previewText = lines.length > 60 ? lines.substring(0, 60) + '...' : lines;
        
        div.innerHTML = `
          <div style="font-weight: 600; color: var(--text-primary); font-size: 0.92rem; display: flex; align-items: center; justify-content: space-between; gap: 6px;">
            <span>🏃‍♂️ ${escapeHtml(item.faixaEtaria.split(' ')[0])} (${item.faixaEtaria.includes('bem pequenas') ? 'Bem Pequenas' : (item.faixaEtaria.includes('pequenas') ? 'Pequenas' : 'Bebês')})</span>
            <button class="delete-btn" data-id="${item.id}" style="background: transparent; border: none; color: var(--text-muted); cursor: pointer; font-size: 0.95rem; padding: 2px 6px; border-radius: 4px; transition: color 0.2s, background 0.2s; display: flex; align-items: center; justify-content: center; z-index: 10;" title="Deletar atividade" onmouseover="this.style.color='#ff4d4f'; this.style.background='rgba(255, 77, 79, 0.1)'" onmouseout="this.style.color='var(--text-muted)'; this.style.background='transparent'">
              🗑️
            </button>
          </div>
          <div style="font-size: 0.8rem; color: var(--text-secondary);">Recursos: ${escapeHtml(previewText)}</div>
          <div style="font-size: 0.75rem; color: var(--text-muted);">${new Date(item.createdAt).toLocaleDateString('pt-BR')}</div>
        `;
        
        const deleteBtn = div.querySelector('.delete-btn');
        deleteBtn.addEventListener('click', async (e) => {
          e.stopPropagation();
          if (confirm(`Deseja realmente excluir esta atividade psicomotora do histórico?`)) {
            try {
              const delResp = await fetch(`/api/brincar-ativo/${item.id}`, { method: 'DELETE' });
              if (!delResp.ok) throw new Error('Falha ao deletar');
              alert('Atividade deletada com sucesso.');
              loadBrincarAtivoHistory();
              if (activeBrincarAtivoReport && activeBrincarAtivoReport.id === item.id) {
                activeBrincarAtivoReport = null;
                brincarAtivoFaixaSelect.value = '';
                brincarAtivoRecursosInput.value = '';
                brincarAtivoReportArea.innerHTML = '';
                brincarAtivoResultArea.style.display = 'none';
              }
            } catch (err) {
              alert('Erro ao excluir atividade: ' + err.message);
            }
          }
        });
        
        div.addEventListener('click', async () => {
          try {
            const detailResp = await fetch(`/api/brincar-ativo/${item.id}`);
            if (!detailResp.ok) throw new Error('Erro ao obter detalhes');
            const detail = await detailResp.json();
            
            activeBrincarAtivoReport = detail;
            brincarAtivoFaixaSelect.value = detail.faixaEtaria;
            brincarAtivoRecursosInput.value = detail.recursos;
            brincarAtivoReportArea.innerHTML = window.marked ? marked.parse(detail.atividade) : detail.atividade;
            
            brincarAtivoResultArea.style.display = 'flex';
            if (tabBrincarAtivoNova) tabBrincarAtivoNova.click();
          } catch (e) {
            alert('Falha ao abrir atividade.');
          }
        });
        
        brincarAtivoListContainer.appendChild(div);
      });
    } catch (err) {
      console.error(err);
    }
  }
};

// Player de áudio personalizado global para as mídias geradas
window.toggleCustomAudio = (btn) => {
  const player = btn.closest('.custom-audio-player');
  const audio = player.querySelector('audio');
  const playIcon = btn.querySelector('.play-icon');
  const pauseIcon = btn.querySelector('.pause-icon');
  const progress = player.querySelector('.audio-progress');
  const timeSpan = player.querySelector('.audio-time');

  if (audio.paused) {
    // Pausar outros players que possam estar ativos
    document.querySelectorAll('.custom-audio-player audio').forEach(a => {
      if (a !== audio && !a.paused) {
        a.pause();
        const otherBtn = a.closest('.custom-audio-player').querySelector('.audio-play-btn');
        otherBtn.querySelector('.play-icon').classList.remove('hidden');
        otherBtn.querySelector('.pause-icon').classList.add('hidden');
      }
    });

    audio.play();
    playIcon.classList.add('hidden');
    pauseIcon.classList.remove('hidden');
  } else {
    audio.pause();
    playIcon.classList.remove('hidden');
    pauseIcon.classList.add('hidden');
  }

  // Atualizar progresso em tempo real
  audio.ontimeupdate = () => {
    if (audio.duration) {
      const percent = (audio.currentTime / audio.duration) * 100;
      progress.style.width = percent + '%';
      
      const mins = Math.floor(audio.currentTime / 60);
      const secs = Math.floor(audio.currentTime % 60).toString().padStart(2, '0');
      timeSpan.textContent = `${mins}:${secs}`;
    }
  };

  audio.onended = () => {
    playIcon.classList.remove('hidden');
    pauseIcon.classList.add('hidden');
    progress.style.width = '0%';
    timeSpan.textContent = '0:00';
  };
};
  // ============================================================
  // MUSICANDO IDEIAS (ESTÚDIO PROFISSIONAL)
  // ============================================================
  const barBtnMusica = document.getElementById('barBtnMusica');
  const musicaModal = document.getElementById('musicaModal');
  const btnCloseMusicaModal = document.getElementById('btnCloseMusicaModal');
  const btnOpenMusicaHistory = document.getElementById('btnOpenMusicaHistory');
  const musicaHistoryModal = document.getElementById('musicaHistoryModal');
  const btnCloseMusicaHistory = document.getElementById('btnCloseMusicaHistory');

  const musicaTemplateSelect = document.getElementById('musicaTemplateSelect');
  const musicaTemaInput = document.getElementById('musicaTemaInput');
  const musicaTurmaSelect = document.getElementById('musicaTurmaSelect');
  const musicaFaixaEtaria = document.getElementById('musicaFaixaEtaria');
  const musicaRitmo = document.getElementById('musicaRitmo');
  const musicaIntensidade = document.getElementById('musicaIntensidade');
  const musicaVozSelect = document.getElementById('musicaVozSelect');
  const musicaDuracaoSelect = document.getElementById('musicaDuracaoSelect');
  const btnGenerateMusica = document.getElementById('btnGenerateMusica');
  const musicaGenerateLoader = document.getElementById('musicaGenerateLoader');

  // Elementos do Lado Direito
  const musicaBnccBadge = document.getElementById('musicaBnccBadge');
  const musicaAudioPlayerBox = document.getElementById('musicaAudioPlayerBox');
  const musicaAudioPlayer = document.getElementById('musicaAudioPlayer');
  const musicaPlayerTitle = document.getElementById('musicaPlayerTitle');
  const btnToggleMusicLoop = document.getElementById('btnToggleMusicLoop');
  const btnDownloadMusicaAudio = document.getElementById('btnDownloadMusicaAudio');
  const musicaWaveformVisualizer = document.getElementById('musicaWaveformVisualizer');

  const musicaVersionsTabs = document.getElementById('musicaVersionsTabs');
  const btnTabVersaoPrincipal = document.getElementById('btnTabVersaoPrincipal');
  const btnTabVersaoCurta = document.getElementById('btnTabVersaoCurta');
  const btnTabVersaoDancante = document.getElementById('btnTabVersaoDancante');

  const musicaPlaceholderText = document.getElementById('musicaPlaceholderText');
  const musicaActiveContentBox = document.getElementById('musicaActiveContentBox');
  const musicaActiveTitle = document.getElementById('musicaActiveTitle');
  const musicaActiveBadge = document.getElementById('musicaActiveBadge');
  const musicaActiveLyrics = document.getElementById('musicaActiveLyrics');
  const musicaPedagogicalTipBox = document.getElementById('musicaPedagogicalTipBox');
  const musicaPedagogicalTipText = document.getElementById('musicaPedagogicalTipText');

  const btnCopyActiveLyrics = document.getElementById('btnCopyActiveLyrics');
  const btnDownloadActiveTxt = document.getElementById('btnDownloadActiveTxt');
  const btnExportActivePdf = document.getElementById('btnExportActivePdf');

  // TEMPLATES PRÉ-CONFIGURADOS DO MUSICANDO IDEIAS
  const MUSICA_TEMPLATES = {
    horta: {
      tema: "Plantar sementinhas na horta da escola, regar a terra com carinho, ver os brotinhos crescerem e colher vegetais coloridos e saudáveis.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      ritmo: "Cantiga de Roda",
      intensidade: "moderada",
      voz: "mulher",
      duracao: "1min",
      instrumentos: ["Violão acústico", "Flauta doce", "Pandeiro e percussão", "Xilofone infantil"]
    },
    familia: {
      tema: "O amor e o carinho da família, os abraços acolhedores na chegada e na saída da escola, gratidão e respeito aos pais e avós.",
      faixa: "Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)",
      ritmo: "Canção de Ninar",
      intensidade: "calma",
      voz: "mulher",
      duracao: "1min",
      instrumentos: ["Violão acústico", "Metalofone e sinos", "Flauta doce"]
    },
    higiene: {
      tema: "Lavar as mãozinhas com água e sabão antes do lanche, escovar os dentinhos após comer e cuidar do corpinho limpinho e cheiroso.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      ritmo: "Pop Infantil Alegre",
      intensidade: "dancante",
      voz: "crianca",
      duracao: "1min",
      instrumentos: ["Teclado e sintetizador", "Pandeiro e percussão", "Palmas e coro de crianças"]
    },
    mindlab: {
      tema: "Pensar antes de jogar, esperar a sua vez com calma, cooperar com os colegas de equipe e comemorar as jogadas inteligentes.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      ritmo: "Cantiga de Roda",
      intensidade: "moderada",
      voz: "homem",
      duracao: "1min",
      instrumentos: ["Violão acústico", "Pandeiro e percussão", "Xilofone infantil"]
    },
    verao: {
      tema: "O sol brilhando no céu, brincadeiras com água e areia no parque, beber água fresca e sentir a brisa da natureza.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      ritmo: "Forrózinho Lúdico",
      intensidade: "dancante",
      voz: "mulher",
      duracao: "1min",
      instrumentos: ["Acordeon", "Pandeiro e percussão", "Violão acústico", "Palmas e coro de crianças"]
    },
    alfabeto: {
      tema: "As letrinhas do alfabeto dançando, descobrindo os sons das vogais A E I O U e escrevendo o próprio nome com alegria.",
      faixa: "Crianças pequenas (4 anos a 5 anos e 11 meses)",
      ritmo: "Marchinha Escolar",
      intensidade: "dancante",
      voz: "mulher",
      duracao: "1min",
      instrumentos: ["Pandeiro e percussão", "Metalofone e sinos", "Palmas e coro de crianças"]
    },
    emocoes: {
      tema: "Reconhecer quando estamos felizes, com medo, bravos ou tranquilos, respirar fundo e receber um abraço amigo na roda.",
      faixa: "Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)",
      ritmo: "Canção de Ninar",
      intensidade: "calma",
      voz: "mulher",
      duracao: "1min",
      instrumentos: ["Violão acústico", "Flauta doce", "Metalofone e sinos"]
    }
  };

  // Estado atual da música gerada
  let activeMusicaData = {
    titulo: '',
    versaoPrincipal: '',
    versaoCurta: '',
    versaoDancante: '',
    bnccCampos: '',
    instrumentos: '',
    dicas: '',
    audioUrl: '',
    tema: '',
    ritmo: '',
    faixaEtaria: ''
  };
  let activeMusicaTab = 'principal';
  let isLoopActive = false;

  // Carregar turmas no seletor
  const loadTurmasForMusica = async () => {
    if (!musicaTurmaSelect) return;
    try {
      const res = await fetch('/api/turmas');
      if (res.ok) {
        const turmas = await res.json();
        musicaTurmaSelect.innerHTML = '<option value="">-- Selecionar Turma --</option>';
        turmas.forEach(t => {
          const opt = document.createElement('option');
          opt.value = t.id;
          opt.textContent = `${t.nome} (${t.ano || '2026'})`;
          opt.dataset.nome = t.nome;
          musicaTurmaSelect.appendChild(opt);
        });
      }
    } catch (err) {
      console.warn('Erro ao carregar turmas para música:', err);
    }
  };

  // Abrir Modal
  if (barBtnMusica) {
    barBtnMusica.addEventListener('click', () => {
      musicaModal.style.display = 'flex';
      loadTurmasForMusica();
      if (!musicaTemaInput.value) {
        applyMusicaTemplate('horta');
      }
    });
  }

  if (btnCloseMusicaModal) {
    btnCloseMusicaModal.addEventListener('click', () => {
      musicaModal.style.display = 'none';
      if (musicaAudioPlayer) musicaAudioPlayer.pause();
    });
  }

  musicaModal.addEventListener('click', (e) => {
    if (e.target === musicaModal) {
      musicaModal.style.display = 'none';
      if (musicaAudioPlayer) musicaAudioPlayer.pause();
    }
  });

  // Aplicar Template
  const applyMusicaTemplate = (key) => {
    const tmpl = MUSICA_TEMPLATES[key];
    if (!tmpl) return;

    if (musicaTemaInput) musicaTemaInput.value = tmpl.tema;
    if (musicaFaixaEtaria) musicaFaixaEtaria.value = tmpl.faixa;
    if (musicaRitmo) musicaRitmo.value = tmpl.ritmo;
    if (musicaIntensidade) musicaIntensidade.value = tmpl.intensidade;
    if (musicaVozSelect) musicaVozSelect.value = tmpl.voz;
    if (musicaDuracaoSelect) musicaDuracaoSelect.value = tmpl.duracao;

    // Ajustar checkboxes de instrumentos
    const checkboxes = document.querySelectorAll('#musicaInstrumentsContainer input[type="checkbox"]');
    checkboxes.forEach(cb => {
      cb.checked = tmpl.instrumentos.includes(cb.value);
    });
  };

  if (musicaTemplateSelect) {
    musicaTemplateSelect.addEventListener('change', (e) => {
      if (e.target.value) {
        applyMusicaTemplate(e.target.value);
      }
    });
  }

  // Alternar Versões no Painel Direito
  const switchMusicaVersionTab = (tab) => {
    activeMusicaTab = tab;
    [btnTabVersaoPrincipal, btnTabVersaoCurta, btnTabVersaoDancante].forEach(b => {
      if (b) {
        b.classList.remove('active');
        b.style.background = 'transparent';
        b.style.color = 'var(--text-secondary)';
      }
    });

    let currentLyrics = '';
    let badgeText = '';

    if (tab === 'principal') {
      if (btnTabVersaoPrincipal) {
        btnTabVersaoPrincipal.classList.add('active');
        btnTabVersaoPrincipal.style.background = 'rgba(168,85,247,0.15)';
        btnTabVersaoPrincipal.style.color = '#c084fc';
      }
      currentLyrics = activeMusicaData.versaoPrincipal;
      badgeText = '🌟 Versão Completa (com gestos)';
    } else if (tab === 'curta') {
      if (btnTabVersaoCurta) {
        btnTabVersaoCurta.classList.add('active');
        btnTabVersaoCurta.style.background = 'rgba(168,85,247,0.15)';
        btnTabVersaoCurta.style.color = '#c084fc';
      }
      currentLyrics = activeMusicaData.versaoCurta;
      badgeText = '⚡ Rascunho / Memorização Rápida';
    } else if (tab === 'dancante') {
      if (btnTabVersaoDancante) {
        btnTabVersaoDancante.classList.add('active');
        btnTabVersaoDancante.style.background = 'rgba(168,85,247,0.15)';
        btnTabVersaoDancante.style.color = '#c084fc';
      }
      currentLyrics = activeMusicaData.versaoDancante;
      badgeText = '🎉 Versão Dançante / Roda';
    }

    if (musicaActiveBadge) musicaActiveBadge.textContent = badgeText;
    if (musicaActiveLyrics) musicaActiveLyrics.textContent = currentLyrics || 'Nenhuma letra para esta versão.';
  };

  if (btnTabVersaoPrincipal) btnTabVersaoPrincipal.addEventListener('click', () => switchMusicaVersionTab('principal'));
  if (btnTabVersaoCurta) btnTabVersaoCurta.addEventListener('click', () => switchMusicaVersionTab('curta'));
  if (btnTabVersaoDancante) btnTabVersaoDancante.addEventListener('click', () => switchMusicaVersionTab('dancante'));

  // Controle de Loop de Áudio
  if (btnToggleMusicLoop) {
    btnToggleMusicLoop.addEventListener('click', () => {
      isLoopActive = !isLoopActive;
      if (musicaAudioPlayer) musicaAudioPlayer.loop = isLoopActive;
      btnToggleMusicLoop.textContent = isLoopActive ? '🔁 Loop: LIGADO' : '🔁 Loop: Desligado';
      btnToggleMusicLoop.style.background = isLoopActive ? 'rgba(16, 185, 129, 0.2)' : 'rgba(255,255,255,0.05)';
      btnToggleMusicLoop.style.color = isLoopActive ? '#34d399' : 'var(--text-secondary)';
    });
  }

  // Equalizer / Waveform Animation quando toca
  if (musicaAudioPlayer) {
    musicaAudioPlayer.addEventListener('play', () => {
      const bars = document.querySelectorAll('#musicaWaveformVisualizer .wave-bar');
      bars.forEach(b => b.classList.add('wave-active'));
    });
    musicaAudioPlayer.addEventListener('pause', () => {
      const bars = document.querySelectorAll('#musicaWaveformVisualizer .wave-bar');
      bars.forEach(b => b.classList.remove('wave-active'));
    });
  }

  // --- GERAR MÚSICA (COMPOR 3 VERSÕES + ÁUDIO) ---
  if (btnGenerateMusica) {
    btnGenerateMusica.addEventListener('click', async () => {
      const tema = (musicaTemaInput?.value || '').trim();
      if (!tema) {
        await showCustomAlert('Aviso', 'Por favor, informe a ideia ou tema da música.');
        return;
      }

      // Coletar instrumentos selecionados
      const selectedInstruments = Array.from(
        document.querySelectorAll('#musicaInstrumentsContainer input[type="checkbox"]:checked')
      ).map(cb => cb.value).join(', ');

      btnGenerateMusica.disabled = true;
      if (musicaGenerateLoader) musicaGenerateLoader.style.display = 'flex';

      try {
        const res = await fetch('/api/musicas/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            tema,
            faixaEtaria: musicaFaixaEtaria?.value,
            ritmo: musicaRitmo?.value,
            instrumentos: selectedInstruments || 'Violão acústico, Pandeiro e Flauta',
            intensidade: musicaIntensidade?.value || 'moderada',
            duracao: musicaDuracaoSelect?.value || '1min',
            voz: musicaVozSelect?.value || 'mulher',
            turmaId: musicaTurmaSelect?.value || null,
            gerarAudio: true
          })
        });

        const data = await res.json();

        if (res.ok && data.success) {
          activeMusicaData = {
            titulo: data.titulo || `Música: ${tema}`,
            versaoPrincipal: data.versaoPrincipal,
            versaoCurta: data.versaoCurta,
            versaoDancante: data.versaoDancante,
            bnccCampos: data.bnccCampos,
            instrumentos: data.instrumentosSugeridos || selectedInstruments,
            dicas: data.dicasPedagogicas,
            audioUrl: data.audioUrl,
            tema: tema,
            ritmo: data.ritmo || musicaRitmo?.value,
            faixaEtaria: data.faixaEtaria || musicaFaixaEtaria?.value
          };

          // Atualizar UI
          if (musicaPlaceholderText) musicaPlaceholderText.style.display = 'none';
          if (musicaVersionsTabs) musicaVersionsTabs.style.display = 'flex';
          if (musicaActiveContentBox) musicaActiveContentBox.style.display = 'flex';

          if (musicaActiveTitle) musicaActiveTitle.textContent = activeMusicaData.titulo;
          if (musicaBnccBadge) {
            musicaBnccBadge.textContent = `BNCC: ${activeMusicaData.bnccCampos.split('•')[0].trim()}`;
            musicaBnccBadge.style.display = 'inline-block';
          }

          if (musicaPedagogicalTipText && activeMusicaData.dicas) {
            musicaPedagogicalTipText.textContent = activeMusicaData.dicas;
            musicaPedagogicalTipBox.style.display = 'block';
          }

          // Se gerou áudio com MiniMax
          if (data.audioUrl) {
            musicaAudioPlayer.src = data.audioUrl;
            if (musicaPlayerTitle) musicaPlayerTitle.textContent = activeMusicaData.titulo;
            if (btnDownloadMusicaAudio) btnDownloadMusicaAudio.href = data.audioUrl;
            if (musicaAudioPlayerBox) musicaAudioPlayerBox.style.display = 'flex';
          } else {
            if (musicaAudioPlayerBox) musicaAudioPlayerBox.style.display = 'none';
          }

          switchMusicaVersionTab('principal');
          showToast('3 versões de música pedagógica compostas com sucesso!', 'success');

        } else {
          await showCustomAlert('Erro', data.error || 'Erro ao compor música.');
        }

      } catch (err) {
        console.error('Erro ao compor música:', err);
        await showCustomAlert('Erro', 'Não foi possível conectar ao servidor: ' + err.message);
      } finally {
        btnGenerateMusica.disabled = false;
        if (musicaGenerateLoader) musicaGenerateLoader.style.display = 'none';
      }
    });
  }

  // Copiar Letra Ativa
  if (btnCopyActiveLyrics) {
    btnCopyActiveLyrics.addEventListener('click', () => {
      const text = musicaActiveLyrics?.textContent || '';
      if (text) {
        navigator.clipboard.writeText(`${activeMusicaData.titulo}\n\n${text}`);
        showToast('Letra copiada para a área de transferência!', 'success');
      }
    });
  }

  // Baixar Letra TXT
  if (btnDownloadActiveTxt) {
    btnDownloadActiveTxt.addEventListener('click', () => {
      const text = musicaActiveLyrics?.textContent || '';
      if (!text) return;
      const content = `MÚSICA PEDAGÓGICA - PEDAGOGIA\n========================================\nTítulo: ${activeMusicaData.titulo}\nFaixa Etária: ${activeMusicaData.faixaEtaria}\nRitmo: ${activeMusicaData.ritmo}\nBNCC: ${activeMusicaData.bnccCampos}\nInstrumentos: ${activeMusicaData.instrumentos}\n========================================\n\n${text}\n\n----------------------------------------\nOrientação Pedagógica:\n${activeMusicaData.dicas}\n`;
      const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = `musica_${(activeMusicaData.titulo || 'pedagogica').replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase()}.txt`;
      document.body.appendChild(link);
      link.click();
      link.remove();
    });
  }

  // Exportar PDF Formatado
  if (btnExportActivePdf) {
    btnExportActivePdf.addEventListener('click', () => {
      const lyrics = musicaActiveLyrics?.textContent || '';
      if (!lyrics) return;

      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>${activeMusicaData.titulo} - PedaGog</title>
          <link rel="preconnect" href="https://fonts.googleapis.com">
          <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
          <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
          <style>
            body { font-family: 'Fredoka', 'Outfit', sans-serif; padding: 40px; color: #1e293b; background: #fffdfa; line-height: 1.7; }
            .header-box { border-bottom: 3px dashed #a855f7; padding-bottom: 16px; margin-bottom: 24px; }
            h1 { color: #7c3aed; margin: 0 0 8px 0; font-size: 2rem; }
            .meta-tags { display: flex; gap: 12px; font-size: 0.9rem; color: #64748b; font-weight: 600; margin-bottom: 8px; flex-wrap: wrap; }
            .meta-tag { background: #f3e8ff; color: #7e22ce; padding: 4px 10px; border-radius: 6px; }
            .lyrics-box { font-size: 1.15rem; background: #f8fafc; padding: 24px; border-radius: 12px; border: 1px solid #e2e8f0; white-space: pre-wrap; margin-bottom: 24px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); }
            .tip-box { background: #f0fdf4; border: 1px solid #bbf7d0; color: #166534; padding: 14px 18px; border-radius: 8px; font-size: 0.92rem; }
            @media print { body { padding: 20px; } button { display: none; } }
          </style>
        </head>
        <body>
          <div style="max-width: 750px; margin: 0 auto;">
            <div class="header-box">
              <div style="display: flex; justify-content: space-between; align-items: flex-start;">
                <div>
                  <h1>🎵 ${activeMusicaData.titulo}</h1>
                  <div class="meta-tags">
                    <span class="meta-tag">👶 ${activeMusicaData.faixaEtaria}</span>
                    <span class="meta-tag">🥁 ${activeMusicaData.ritmo}</span>
                    <span class="meta-tag">📚 ${activeMusicaData.bnccCampos.split('•')[0]}</span>
                  </div>
                  <div style="font-size: 0.85rem; color: #64748b;">🎸 Instrumentos: ${activeMusicaData.instrumentos}</div>
                </div>
                <button onclick="window.print()" style="background: #a855f7; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-weight: bold; font-family: sans-serif;">🖨️ Imprimir / Salvar PDF</button>
              </div>
            </div>
            
            <div class="lyrics-box">${lyrics}</div>

            ${activeMusicaData.dicas ? `
            <div class="tip-box">
              💡 <strong>Vivência Pedagógica Sugerida:</strong><br>
              ${activeMusicaData.dicas}
            </div>` : ''}
            
            <div style="margin-top: 30px; text-align: center; font-size: 0.8rem; color: #94a3b8; border-top: 1px solid #e2e8f0; padding-top: 10px;">
              Gerado por PedagogIA • Assistente Pedagógica da Professora Camila
            </div>
          </div>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // --- HISTÓRICO DE MÚSICAS ---
  if (btnOpenMusicaHistory) {
    btnOpenMusicaHistory.addEventListener('click', () => {
      musicaHistoryModal.style.display = 'flex';
      loadMusicaHistory();
    });
  }

  if (btnCloseMusicaHistory) {
    btnCloseMusicaHistory.addEventListener('click', () => {
      musicaHistoryModal.style.display = 'none';
    });
  }

  musicaHistoryModal.addEventListener('click', (e) => {
    if (e.target === musicaHistoryModal) {
      musicaHistoryModal.style.display = 'none';
    }
  });

  async function loadMusicaHistory() {
    const listContainer = document.getElementById('musicaHistoryList');
    if (!listContainer) return;
    listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando histórico...</p>';
    
    try {
      const response = await fetch('/api/musicas/list');
      const data = await response.json();
      if (data && data.length > 0) {
        listContainer.innerHTML = '';
        data.forEach(item => {
          const date = new Date(item.created_at).toLocaleString('pt-BR');
          const div = document.createElement('div');
          div.className = 'history-item-card';
          div.style.cssText = 'background: rgba(255,255,255,0.03); padding: 14px; border-radius: 10px; border: 1px solid var(--border-light); display: flex; flex-direction: column; gap: 8px; cursor: pointer; position: relative; transition: all 0.2s;';
          div.innerHTML = `
            <div style="display: flex; justify-content: space-between; align-items: flex-start; padding-right: 30px;">
              <strong style="color: #c084fc; font-size: 0.95rem;">${item.faixa_etaria} • ${item.ritmo}</strong>
              <span style="font-size: 0.72rem; color: var(--text-secondary);">${date}</span>
            </div>
            <p style="margin: 0; font-size: 0.85rem; color: var(--text-primary); opacity: 0.9;"><strong>Tema:</strong> ${item.tema}</p>
            ${item.audio_url ? `
              <div style="display: flex; align-items: center; gap: 8px; margin-top: 4px;">
                <span style="font-size: 0.75rem; color: #10b981; font-weight: 600;">🎧 Áudio Disponível</span>
              </div>
            ` : ''}
            <button class="btn-delete-musica" data-id="${item.id}" style="position: absolute; top: 12px; right: 12px; background: transparent; border: none; color: #ef4444; cursor: pointer; font-size: 1.1rem; padding: 4px; border-radius: 4px;" title="Excluir">🗑️</button>
          `;
          
          div.addEventListener('click', async (e) => {
            if (e.target.closest('.btn-delete-musica')) {
              e.stopPropagation();
              if (confirm('Tem certeza que deseja excluir esta música do histórico?')) {
                try {
                  const delRes = await fetch(`/api/musicas/${item.id}`, { method: 'DELETE' });
                  if (delRes.ok) {
                    showToast('Música excluída do histórico.', 'success');
                    loadMusicaHistory();
                  }
                } catch (err) {
                  showToast('Erro ao excluir música.', 'error');
                }
              }
              return;
            }

            // Carregar música clicada
            try {
              const res = await fetch(`/api/musicas/${item.id}`);
              const detail = await res.json();
              if (res.ok) {
                activeMusicaData = {
                  titulo: `Música: ${detail.tema}`,
                  versaoPrincipal: detail.versao_longa || detail.musica,
                  versaoCurta: detail.versao_curta || detail.musica,
                  versaoDancante: detail.versao_dancante || detail.musica,
                  bnccCampos: detail.bncc || 'EI02TS02 • Traços, Sons, Cores e Formas',
                  instrumentos: detail.instrumentos || 'Violão e Percussão',
                  dicas: '',
                  audioUrl: detail.audio_url,
                  tema: detail.tema,
                  ritmo: detail.ritmo,
                  faixaEtaria: detail.faixa_etaria
                };

                if (musicaPlaceholderText) musicaPlaceholderText.style.display = 'none';
                if (musicaVersionsTabs) musicaVersionsTabs.style.display = 'flex';
                if (musicaActiveContentBox) musicaActiveContentBox.style.display = 'flex';

                if (musicaActiveTitle) musicaActiveTitle.textContent = activeMusicaData.titulo;
                if (detail.audio_url) {
                  musicaAudioPlayer.src = detail.audio_url;
                  if (btnDownloadMusicaAudio) btnDownloadMusicaAudio.href = detail.audio_url;
                  if (musicaAudioPlayerBox) musicaAudioPlayerBox.style.display = 'flex';
                } else {
                  if (musicaAudioPlayerBox) musicaAudioPlayerBox.style.display = 'none';
                }

                switchMusicaVersionTab('principal');
                musicaHistoryModal.style.display = 'none';
              }
            } catch (err) {
              showToast('Erro ao carregar detalhes da música.', 'error');
            }
          });

          listContainer.appendChild(div);
        });
      } else {
        listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary); padding: 20px;">Nenhuma música gerada até o momento.</p>';
      }
    } catch (err) {
      listContainer.innerHTML = '<p style="text-align:center; color:#ef4444;">Erro ao carregar histórico de músicas.</p>';
    }
  }


  // ============================================================
  // INVENTANDO HISTÓRIAS (ESTÚDIO PROFISSIONAL)
  // ============================================================
  const HISTORIA_TEMPLATES = {
    arca: {
      titulo: 'A Arca da Imaginação',
      objeto: 'Arca Mágica de Madeira',
      tema: 'As crianças encontram uma arca misteriosa no parquinho que se abre apenas quando todos dão as mãos e compartilham uma ideia criativa.',
      estilo: 'Lúdico, Afetivo e Dialogado',
      faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)',
      visual: 'Cartoon colorido e acolhedor'
    },
    horta: {
      titulo: 'O Mistério da Horta Encantada',
      objeto: 'Semente Brilhante de Girassol',
      tema: 'A turma planta uma sementinha brilhante na horta da escola e descobre que ela cresce quando ouve canções de carinho e risadas.',
      estilo: 'Contação Clássica com Suspense Leve',
      faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)',
      visual: 'Aquarela suave infantil'
    },
    dinossauro: {
      titulo: 'O Pequeno Dinossauro Amigo',
      objeto: 'Pegada Colorida de Brinquedo',
      tema: 'Um pequeno dinossauro verde e tímido aparece na hora do lanche procurando amigos para brincar de roda e desenhar.',
      estilo: 'Lúdico, Afetivo e Dialogado',
      faixa: 'Crianças bem pequenas (1 ano e 7 meses a 3 anos e 11 meses)',
      visual: 'Cartoon colorido e acolhedor'
    },
    chuva: {
      titulo: 'O Dia em que a Chuva Dançou',
      objeto: 'Galochas Amarelas Saltitantes',
      tema: 'Em um dia chuvoso, as gotas batem na janela fazendo música e convidam as crianças para uma dança aconchegante dentro da sala.',
      estilo: 'Roda de Conversa Interativa',
      faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)',
      visual: 'Aquarela suave infantil'
    },
    bolhas: {
      titulo: 'O Reino Mágico das Bolhas de Sabão',
      objeto: 'Varinha de Fazer Bolhas Gigantes',
      tema: 'Cada bolha de sabão que as crianças assopram no pátio leva um desejo de abraço e alegria até as nuvens coloridas.',
      estilo: 'Lúdico, Afetivo e Dialogado',
      faixa: 'Bebês (0 a 1 ano e 6 meses)',
      visual: 'Giz de cera e textura lúdica'
    },
    brinquedos: {
      titulo: 'A Reunião Secreta dos Brinquedos',
      objeto: 'Ursinho de Pano Guardião',
      tema: 'Na hora do descanso, os brinquedos se organizam com muito capricho para esperar o acordar dos alunos com uma surpresa de blocos montados.',
      estilo: 'Aventura e Descoberta na Escola',
      faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)',
      visual: 'Livro infantil clássico e detalhado'
    },
    emocoes: {
      titulo: 'O Monstrinho das Cores e dos Sentimentos',
      objeto: 'Pote Brilhante das Emoções',
      tema: 'Um monstrinho amigo muda de cor quando sente alegria (amarelo), calma (azul) ou saudade (rosa), ensinando a turma a expressar o que sente.',
      estilo: 'Roda de Conversa Interativa',
      faixa: 'Crianças pequenas (4 anos a 5 anos e 11 meses)',
      visual: 'Cartoon colorido e acolhedor'
    }
  };

  const barBtnHistoria = document.getElementById('barBtnHistoria');
  const historiaModal = document.getElementById('historiaModal');
  const btnCloseHistoriaModal = document.getElementById('btnCloseHistoriaModal');
  const btnOpenHistoriaHistory = document.getElementById('btnOpenHistoriaHistory');
  const historiaHistoryModal = document.getElementById('historiaHistoryModal');
  const btnCloseHistoriaHistory = document.getElementById('btnCloseHistoriaHistory');

  const historiaTemplateSelect = document.getElementById('historiaTemplateSelect');
  const historiaTurmaSelect = document.getElementById('historiaTurmaSelect');
  const historiaPersonagemInput = document.getElementById('historiaPersonagemInput');
  const historiaObjetoMagicoInput = document.getElementById('historiaObjetoMagicoInput');
  const historiaFaixaEtaria = document.getElementById('historiaFaixaEtaria');
  const historiaParagrafos = document.getElementById('historiaParagrafos');
  const historiaEstilo = document.getElementById('historiaEstilo');
  const historiaEstiloVisual = document.getElementById('historiaEstiloVisual');
  const historiaTemaInput = document.getElementById('historiaTemaInput');
  const btnGenerateHistoria = document.getElementById('btnGenerateHistoria');
  const historiaGenerateLoader = document.getElementById('historiaGenerateLoader');

  // Elementos do Leitor e Visualizador
  const historiaPlaceholderText = document.getElementById('historiaPlaceholderText');
  const historiaActiveBox = document.getElementById('historiaActiveBox');
  const historiaActiveTitle = document.getElementById('historiaActiveTitle');
  const historiaActiveSubtitle = document.getElementById('historiaActiveSubtitle');
  const historiaBnccBadge = document.getElementById('historiaBnccBadge');

  // Player de Áudio
  const historiaAudioPlayerBox = document.getElementById('historiaAudioPlayerBox');
  const historiaAudioPlayer = document.getElementById('historiaAudioPlayer');
  const btnDownloadHistoriaAudio = document.getElementById('btnDownloadHistoriaAudio');
  const historiaWaveBars = document.querySelectorAll('.wave-bar-historia');

  // Abas
  const historiaContentTabs = document.getElementById('historiaContentTabs');
  const btnTabHistoriaCenas = document.getElementById('btnTabHistoriaCenas');
  const btnTabHistoriaTexto = document.getElementById('btnTabHistoriaTexto');
  const btnTabHistoriaAtividades = document.getElementById('btnTabHistoriaAtividades');
  const historiaCenasView = document.getElementById('historiaCenasView');
  const historiaTextoView = document.getElementById('historiaTextoView');
  const historiaAtividadesView = document.getElementById('historiaAtividadesView');

  // Cenas Interativas
  const btnPrevCena = document.getElementById('btnPrevCena');
  const btnNextCena = document.getElementById('btnNextCena');
  const historiaCenaIndicator = document.getElementById('historiaCenaIndicator');
  const historiaCenaTitle = document.getElementById('historiaCenaTitle');
  const historiaCenaText = document.getElementById('historiaCenaText');
  const historiaCenaImageContainer = document.getElementById('historiaCenaImageContainer');
  const historiaCenaImg = document.getElementById('historiaCenaImg');
  const btnGenerateSceneImage = document.getElementById('btnGenerateSceneImage');

  // BNCC e Perguntas
  const historiaBnccDesc = document.getElementById('historiaBnccDesc');
  const historiaPerguntasList = document.getElementById('historiaPerguntasList');

  // Ações
  const btnCopyActiveHistoria = document.getElementById('btnCopyActiveHistoria');
  const btnDownloadActiveHistoriaTxt = document.getElementById('btnDownloadActiveHistoriaTxt');
  const btnSendHistoriaToMusic = document.getElementById('btnSendHistoriaToMusic');
  const btnExportActiveHistoriaPdf = document.getElementById('btnExportActiveHistoriaPdf');

  let currentHistoriaData = null;
  let currentSceneIndex = 0;

  // Carregar turmas no select de histórias
  async function loadTurmasForHistoria() {
    if (!historiaTurmaSelect) return;
    try {
      const res = await fetch('/api/turmas');
      if (res.ok) {
        const turmas = await res.json();
        historiaTurmaSelect.innerHTML = '<option value="">-- Selecionar Turma --</option>';
        turmas.forEach(t => {
          const opt = document.createElement('option');
          opt.value = t.id;
          opt.textContent = `${t.nome} (${t.ano_letivo || '2026'})`;
          historiaTurmaSelect.appendChild(opt);
        });
      }
    } catch (e) {
      console.warn('Erro ao carregar turmas para histórias:', e);
    }
  }

  // Mudança de template
  if (historiaTemplateSelect) {
    historiaTemplateSelect.addEventListener('change', () => {
      const key = historiaTemplateSelect.value;
      if (key && HISTORIA_TEMPLATES[key]) {
        const tpl = HISTORIA_TEMPLATES[key];
        historiaTemaInput.value = tpl.tema;
        if (historiaObjetoMagicoInput) historiaObjetoMagicoInput.value = tpl.objeto;
        if (historiaEstilo) historiaEstilo.value = tpl.estilo;
        if (historiaFaixaEtaria) historiaFaixaEtaria.value = tpl.faixa;
        if (historiaEstiloVisual) historiaEstiloVisual.value = tpl.visual;
      }
    });
  }

  // Abertura do Modal
  if (barBtnHistoria) {
    barBtnHistoria.addEventListener('click', () => {
      historiaModal.style.display = 'flex';
      loadTurmasForHistoria();
      if (!currentHistoriaData) {
        if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'block';
        if (historiaActiveBox) historiaActiveBox.style.display = 'none';
        if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none';
        if (historiaContentTabs) historiaContentTabs.style.display = 'none';
      }
    });
  }

  if (btnCloseHistoriaModal) {
    historiaModal.addEventListener('click', (e) => { if (e.target === historiaModal) historiaModal.style.display = 'none'; });
    btnCloseHistoriaModal.addEventListener('click', () => historiaModal.style.display = 'none');
  }

  // Histórico
  if (btnOpenHistoriaHistory) {
    btnOpenHistoriaHistory.addEventListener('click', () => {
      historiaHistoryModal.style.display = 'flex';
      loadHistoriaHistory();
    });
  }
  if (btnCloseHistoriaHistory) btnCloseHistoriaHistory.addEventListener('click', () => historiaHistoryModal.style.display = 'none');
  historiaHistoryModal.addEventListener('click', (e) => { if (e.target === historiaHistoryModal) historiaHistoryModal.style.display = 'none'; });

  // Alternância de Abas
  function switchHistoriaTab(tab) {
    [btnTabHistoriaCenas, btnTabHistoriaTexto, btnTabHistoriaAtividades].forEach(b => {
      if (b) {
        b.classList.remove('active');
        b.style.background = 'transparent';
        b.style.color = 'var(--text-secondary)';
      }
    });
    if (historiaCenasView) historiaCenasView.style.display = 'none';
    if (historiaTextoView) historiaTextoView.style.display = 'none';
    if (historiaAtividadesView) historiaAtividadesView.style.display = 'none';

    if (tab === 'cenas') {
      if (btnTabHistoriaCenas) {
        btnTabHistoriaCenas.classList.add('active');
        btnTabHistoriaCenas.style.background = 'rgba(16,185,129,0.15)';
        btnTabHistoriaCenas.style.color = '#34d399';
      }
      if (historiaCenasView) historiaCenasView.style.display = 'flex';
    } else if (tab === 'texto') {
      if (btnTabHistoriaTexto) {
        btnTabHistoriaTexto.classList.add('active');
        btnTabHistoriaTexto.style.background = 'rgba(16,185,129,0.15)';
        btnTabHistoriaTexto.style.color = '#34d399';
      }
      if (historiaTextoView) historiaTextoView.style.display = 'block';
    } else if (tab === 'atividades') {
      if (btnTabHistoriaAtividades) {
        btnTabHistoriaAtividades.classList.add('active');
        btnTabHistoriaAtividades.style.background = 'rgba(16,185,129,0.15)';
        btnTabHistoriaAtividades.style.color = '#34d399';
      }
      if (historiaAtividadesView) historiaAtividadesView.style.display = 'flex';
    }
  }

  if (btnTabHistoriaCenas) btnTabHistoriaCenas.addEventListener('click', () => switchHistoriaTab('cenas'));
  if (btnTabHistoriaTexto) btnTabHistoriaTexto.addEventListener('click', () => switchHistoriaTab('texto'));
  if (btnTabHistoriaAtividades) btnTabHistoriaAtividades.addEventListener('click', () => switchHistoriaTab('atividades'));

  // Renderizar Cena Atual
  function renderCurrentScene() {
    if (!currentHistoriaData || !currentHistoriaData.cenas || currentHistoriaData.cenas.length === 0) return;
    const total = currentHistoriaData.cenas.length;
    if (currentSceneIndex < 0) currentSceneIndex = 0;
    if (currentSceneIndex >= total) currentSceneIndex = total - 1;

    const cena = currentHistoriaData.cenas[currentSceneIndex];
    if (historiaCenaIndicator) historiaCenaIndicator.textContent = `Cena ${currentSceneIndex + 1} de ${total}`;
    if (historiaCenaTitle) historiaCenaTitle.textContent = cena.titulo || `Ato ${currentSceneIndex + 1}`;
    if (historiaCenaText) historiaCenaText.textContent = cena.texto || '';

    // Imagem da cena
    if (cena.imageUrl) {
      if (historiaCenaImg) historiaCenaImg.src = cena.imageUrl;
      if (historiaCenaImageContainer) historiaCenaImageContainer.style.display = 'block';
      if (btnGenerateSceneImage) btnGenerateSceneImage.innerHTML = '🔄 Regenerar Ilustração';
    } else {
      if (historiaCenaImageContainer) historiaCenaImageContainer.style.display = 'none';
      if (btnGenerateSceneImage) btnGenerateSceneImage.innerHTML = '🎨 Gerar Ilustração';
    }

    if (btnPrevCena) btnPrevCena.disabled = currentSceneIndex === 0;
    if (btnNextCena) btnNextCena.disabled = currentSceneIndex === total - 1;
  }

  if (btnPrevCena) {
    btnPrevCena.addEventListener('click', () => {
      if (currentSceneIndex > 0) {
        currentSceneIndex--;
        renderCurrentScene();
      }
    });
  }

  if (btnNextCena) {
    btnNextCena.addEventListener('click', () => {
      if (currentHistoriaData && currentHistoriaData.cenas && currentSceneIndex < currentHistoriaData.cenas.length - 1) {
        currentSceneIndex++;
        renderCurrentScene();
      }
    });
  }

  // Gerar Ilustração da Cena Atual
  if (btnGenerateSceneImage) {
    btnGenerateSceneImage.addEventListener('click', async () => {
      if (!currentHistoriaData || !currentHistoriaData.cenas) return;
      const cena = currentHistoriaData.cenas[currentSceneIndex];
      if (!cena) return;

      const originalBtnHtml = btnGenerateSceneImage.innerHTML;
      btnGenerateSceneImage.disabled = true;
      btnGenerateSceneImage.innerHTML = '⏳ Ilustrando...';

      try {
        const res = await fetch('/api/historias/scene-image', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            prompt: cena.promptImagem || cena.texto || 'Cute children book illustration',
            estiloVisual: currentHistoriaData.estiloVisual || 'Cartoon colorido',
            cenaNumero: currentSceneIndex + 1
          })
        });

        const data = await res.json();
        if (res.ok && data.imageUrl) {
          cena.imageUrl = data.imageUrl;
          renderCurrentScene();
          showToast('Ilustração da cena criada com sucesso!', 'success');
        } else {
          showToast(data.error || 'Erro ao gerar ilustração.', 'error');
        }
      } catch (err) {
        showToast('Erro ao conectar com gerador de ilustração.', 'error');
      } finally {
        btnGenerateSceneImage.disabled = false;
        btnGenerateSceneImage.innerHTML = originalBtnHtml;
      }
    });
  }

  // Gerar História Completa
  if (btnGenerateHistoria) {
    btnGenerateHistoria.addEventListener('click', async () => {
      const tema = historiaTemaInput.value.trim();
      if (!tema) {
        showToast('Por favor, informe o tema ou enredo da história.', 'error');
        return;
      }

      btnGenerateHistoria.disabled = true;
      if (historiaGenerateLoader) historiaGenerateLoader.style.display = 'flex';
      if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'none';

      try {
        const response = await fetch('/api/historias/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            tema: tema,
            faixaEtaria: historiaFaixaEtaria ? historiaFaixaEtaria.value : 'Crianças pequenas',
            paragrafos: historiaParagrafos ? historiaParagrafos.value : '3',
            estilo: historiaEstilo ? historiaEstilo.value : 'Lúdico',
            estiloVisual: historiaEstiloVisual ? historiaEstiloVisual.value : 'Cartoon colorido',
            personagemPrincipal: historiaPersonagemInput ? historiaPersonagemInput.value.trim() : '',
            objetoMagico: historiaObjetoMagicoInput ? historiaObjetoMagicoInput.value.trim() : '',
            turmaId: historiaTurmaSelect ? historiaTurmaSelect.value : null
          })
        });

        const data = await response.json();

        if (response.ok && data.success) {
          currentHistoriaData = data;
          currentSceneIndex = 0;

          // Header
          if (historiaActiveTitle) historiaActiveTitle.textContent = data.titulo || 'História Mágica';
          if (historiaActiveSubtitle) {
            historiaActiveSubtitle.textContent = `Personagem: ${data.personagemPrincipal || 'Turma'} • ${data.cenas ? data.cenas.length : 3} Cenas • ${data.duracaoLeitura || '3 min'}`;
          }
          if (historiaBnccBadge) {
            historiaBnccBadge.textContent = `BNCC: ${data.bnccCampos || 'EI02EF04 / EI03EF05'}`;
            historiaBnccBadge.style.display = 'inline-block';
          }

          // Player de Áudio
          if (data.audioUrl) {
            if (historiaAudioPlayer) historiaAudioPlayer.src = data.audioUrl;
            if (btnDownloadHistoriaAudio) btnDownloadHistoriaAudio.href = data.audioUrl;
            if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'flex';

            if (historiaAudioPlayer) {
              historiaAudioPlayer.onplay = () => historiaWaveBars.forEach(b => b.classList.add('wave-active'));
              historiaAudioPlayer.onpause = () => historiaWaveBars.forEach(b => b.classList.remove('wave-active'));
              historiaAudioPlayer.onended = () => historiaWaveBars.forEach(b => b.classList.remove('wave-active'));
            }
          } else {
            if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none';
          }

          // Abas & Visualização
          if (historiaContentTabs) historiaContentTabs.style.display = 'flex';
          if (historiaActiveBox) historiaActiveBox.style.display = 'flex';
          
          // Texto completo
          if (historiaTextoView) historiaTextoView.textContent = data.historiaCompleta || '';

          // Atividades e BNCC
          if (historiaBnccDesc) historiaBnccDesc.textContent = data.bnccCampos || 'EI02EF04 / EI03EF05 • Escuta, Fala, Pensamento e Imaginação';
          if (historiaPerguntasList) {
            historiaPerguntasList.innerHTML = '';
            (data.perguntasCompreensao || []).forEach(p => {
              const pEl = document.createElement('div');
              pEl.style.cssText = 'padding: 4px 0; border-bottom: 1px dashed rgba(255,255,255,0.05);';
              pEl.textContent = p;
              historiaPerguntasList.appendChild(pEl);
            });
          }

          renderCurrentScene();
          switchHistoriaTab('cenas');
          showToast('História inventada com sucesso!', 'success');
        } else {
          showToast(data.error || 'Erro ao gerar história.', 'error');
        }
      } catch (err) {
        showToast('Erro de conexão ao gerar história.', 'error');
      } finally {
        if (historiaGenerateLoader) historiaGenerateLoader.style.display = 'none';
        btnGenerateHistoria.disabled = false;
      }
    });
  }

  // Copiar História
  if (btnCopyActiveHistoria) {
    btnCopyActiveHistoria.addEventListener('click', () => {
      if (currentHistoriaData && currentHistoriaData.historiaCompleta) {
        navigator.clipboard.writeText(currentHistoriaData.historiaCompleta);
        showToast('História copiada para a área de transferência!', 'success');
      }
    });
  }

  // Baixar TXT
  if (btnDownloadActiveHistoriaTxt) {
    btnDownloadActiveHistoriaTxt.addEventListener('click', () => {
      if (!currentHistoriaData) return;
      const content = `=========================================
📖 ${currentHistoriaData.titulo || 'HISTÓRIA PEDAGÓGICA'}
=========================================
Personagem Principal: ${currentHistoriaData.personagemPrincipal || 'Turma'}
Objeto Mágico: ${currentHistoriaData.objetoMagico || 'Especial'}
BNCC: ${currentHistoriaData.bnccCampos || 'EI02EF04'}
Duração Estimada: ${currentHistoriaData.duracaoLeitura || '3 min'}

--- HISTÓRIA COMPLETA ---
${currentHistoriaData.historiaCompleta || ''}

--- PERGUNTAS PARA RODA DE CONVERSA ---
${(currentHistoriaData.perguntasCompreensao || []).join('\n')}

Gerado por PedagogIA • Assistente da Professora Camila`;

      const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${(currentHistoriaData.titulo || 'historia').toLowerCase().replace(/\s+/g, '_')}.txt`;
      a.click();
      URL.revokeObjectURL(url);
    });
  }

  // Musicar História
  if (btnSendHistoriaToMusic) {
    btnSendHistoriaToMusic.addEventListener('click', () => {
      if (!currentHistoriaData) return;
      const barBtnMusica = document.getElementById('barBtnMusica');
      const musicaTemaInput = document.getElementById('musicaTemaInput');
      historiaModal.style.display = 'none';
      if (barBtnMusica) barBtnMusica.click();
      if (musicaTemaInput) {
        musicaTemaInput.value = `Canção sobre a história "${currentHistoriaData.titulo}": ${currentHistoriaData.objetoMagico || ''}, amizade e imaginação`;
      }
      showToast('História transferida para o Musicando Ideias!', 'info');
    });
  }

  // Exportar PDF Ilustrado
  if (btnExportActiveHistoriaPdf) {
    btnExportActiveHistoriaPdf.addEventListener('click', () => {
      if (!currentHistoriaData) return;
      const printWin = window.open('', '_blank');
      if (!printWin) {
        showToast('Permita pop-ups para gerar o PDF.', 'warning');
        return;
      }

      let cenasHtml = '';
      (currentHistoriaData.cenas || []).forEach((c, idx) => {
        cenasHtml += `
          <div style="margin-bottom: 20px; padding: 15px; border-left: 4px solid #10b981; background: #f8fafc; border-radius: 0 8px 8px 0;">
            <h3 style="margin-top: 0; color: #059669; font-size: 1.1rem;">${c.titulo || `Ato ${idx + 1}`}</h3>
            ${c.imageUrl ? `<div style="text-align: center; margin: 10px 0;"><img src="${c.imageUrl}" style="max-height: 220px; border-radius: 8px;" /></div>` : ''}
            <p style="font-size: 1rem; line-height: 1.7; color: #334155; margin: 0;">${c.texto || ''}</p>
          </div>
        `;
      });

      let perguntasHtml = '';
      (currentHistoriaData.perguntasCompreensao || []).forEach(p => {
        perguntasHtml += `<li style="margin-bottom: 6px;">${p}</li>`;
      });

      printWin.document.write(`
        <!DOCTYPE html>
        <html lang="pt-BR">
        <head>
          <meta charset="UTF-8">
          <title>${currentHistoriaData.titulo || 'História Pedagógica'} - Pedagog</title>
          <style>
            body { font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 35px; color: #1e293b; line-height: 1.6; max-width: 800px; margin: 0 auto; }
            h1 { color: #059669; margin: 0 0 6px 0; font-size: 1.8rem; }
            .header-box { border-bottom: 2px solid #e2e8f0; padding-bottom: 14px; margin-bottom: 24px; }
            .badge { display: inline-block; background: #d1fae5; color: #065f46; font-size: 0.8rem; padding: 4px 10px; border-radius: 6px; font-weight: bold; margin-right: 6px; }
            .btn-print { background: #10b981; color: white; border: none; padding: 10px 20px; border-radius: 8px; font-weight: bold; cursor: pointer; float: right; font-size: 0.95rem; }
            @media print { .btn-print { display: none; } body { padding: 0; } }
          </style>
        </head>
        <body>
          <button class="btn-print" onclick="window.print()">🖨️ Imprimir / Salvar PDF</button>
          <div class="header-box">
            <h1>📖 ${currentHistoriaData.titulo || 'História Pedagógica'}</h1>
            <div style="margin-top: 8px;">
              <span class="badge">Personagem: ${currentHistoriaData.personagemPrincipal || 'Turma'}</span>
              <span class="badge">Objeto: ${currentHistoriaData.objetoMagico || 'Especial'}</span>
              <span class="badge">BNCC: ${currentHistoriaData.bnccCampos || 'EI02EF04'}</span>
            </div>
          </div>

          <h2 style="color: #0f172a; font-size: 1.2rem; border-bottom: 1px solid #cbd5e1; padding-bottom: 6px;">🎬 Cenas da História</h2>
          ${cenasHtml}

          <div style="margin-top: 30px; padding: 18px; background: #f1f5f9; border-radius: 8px;">
            <h3 style="margin-top: 0; color: #0f172a; font-size: 1.05rem;">🧩 Roda de Conversa & Atividades</h3>
            <ul style="margin: 0; padding-left: 20px; color: #475569; font-size: 0.95rem;">
              ${perguntasHtml}
            </ul>
          </div>

          <div style="margin-top: 40px; text-align: center; font-size: 0.8rem; color: #94a3b8; border-top: 1px solid #e2e8f0; padding-top: 12px;">
            Pedagog • Estúdio de Literatura Infantil da Professora Camila Martella Gasparini Reifonas
          </div>
        </body>
        </html>
      `);
      printWin.document.close();
    });
  }

  // Carregar Histórico
  async function loadHistoriaHistory() {
    const listContainer = document.getElementById('historiaHistoryList');
    if (!listContainer) return;
    listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando histórias...</p>';
    try {
      const response = await fetch('/api/historias/list');
      const data = await response.json();
      if (data && data.length > 0) {
        listContainer.innerHTML = '';
        data.forEach(item => {
          const date = new Date(item.created_at).toLocaleString('pt-BR');
          const div = document.createElement('div');
          div.className = 'history-item-card';
          div.style.cssText = 'background: rgba(255,255,255,0.02); padding: 14px; border-radius: 8px; border: 1px solid var(--border-light); display: flex; flex-direction: column; gap: 6px; cursor: pointer; position: relative;';
          div.innerHTML = `
            <div style="display: flex; justify-content: space-between; align-items: flex-start; padding-right: 30px;">
              <strong style="color: #34d399; font-size: 0.95rem;">${item.titulo || item.tema || 'História'}</strong>
              <span style="font-size: 0.72rem; color: var(--text-secondary);">${date}</span>
            </div>
            <p style="margin: 0; font-size: 0.82rem; color: var(--text-primary); opacity: 0.9;">Tema: ${item.tema}</p>
            <div style="display: flex; gap: 8px; font-size: 0.72rem; color: var(--text-secondary);">
              <span>👶 ${item.faixa_etaria}</span>
              ${item.personagem_principal ? `<span>• 👤 ${item.personagem_principal}</span>` : ''}
              ${item.audio_url ? `<span>• 🎙️ Áudio MP3</span>` : ''}
            </div>
            <button class="btn-delete-historia" data-id="${item.id}" style="position: absolute; top: 12px; right: 12px; background: transparent; border: none; color: #ef4444; cursor: pointer; font-size: 1.1rem; padding: 4px; border-radius: 4px;" title="Excluir">🗑️</button>
          `;
          div.addEventListener('click', async (e) => {
            if (e.target.closest('.btn-delete-historia')) {
              e.stopPropagation();
              if (confirm('Tem certeza que deseja excluir esta história?')) {
                try {
                  const delRes = await fetch(`/api/historias/${item.id}`, { method: 'DELETE' });
                  if (delRes.ok) { showToast('História excluída.', 'success'); loadHistoriaHistory(); }
                } catch (err) { showToast('Erro ao excluir.', 'error'); }
              }
              return;
            }
            try {
              const res = await fetch(`/api/historias/${item.id}`);
              const detail = await res.json();
              if (res.ok) {
                currentHistoriaData = {
                  id: detail.id,
                  titulo: detail.titulo || `História: ${detail.tema}`,
                  personagemPrincipal: detail.personagem_principal || '',
                  objetoMagico: detail.objeto_magico || '',
                  historiaCompleta: detail.historia || '',
                  cenas: typeof detail.cenas === 'string' ? JSON.parse(detail.cenas) : (detail.cenas || []),
                  perguntasCompreensao: typeof detail.perguntas_compreensao === 'string' ? JSON.parse(detail.perguntas_compreensao) : (detail.perguntas_compreensao || []),
                  bnccCampos: detail.bncc || 'EI02EF04 / EI03EF05',
                  duracaoLeitura: detail.duracao_leitura || '3 min',
                  complexidade: detail.complexidade || 'Lúdica',
                  audioUrl: detail.audio_url || null,
                  estiloVisual: detail.estilo_visual || 'Cartoon colorido'
                };
                currentSceneIndex = 0;

                if (historiaActiveTitle) historiaActiveTitle.textContent = currentHistoriaData.titulo;
                if (historiaActiveSubtitle) {
                  historiaActiveSubtitle.textContent = `Personagem: ${currentHistoriaData.personagemPrincipal || 'Turma'} • ${currentHistoriaData.cenas ? currentHistoriaData.cenas.length : 3} Cenas`;
                }
                if (historiaBnccBadge) {
                  historiaBnccBadge.textContent = `BNCC: ${currentHistoriaData.bnccCampos}`;
                  historiaBnccBadge.style.display = 'inline-block';
                }

                if (currentHistoriaData.audioUrl) {
                  if (historiaAudioPlayer) historiaAudioPlayer.src = currentHistoriaData.audioUrl;
                  if (btnDownloadHistoriaAudio) btnDownloadHistoriaAudio.href = currentHistoriaData.audioUrl;
                  if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'flex';
                } else {
                  if (historiaAudioPlayerBox) historiaAudioPlayerBox.style.display = 'none';
                }

                if (historiaContentTabs) historiaContentTabs.style.display = 'flex';
                if (historiaActiveBox) historiaActiveBox.style.display = 'flex';
                if (historiaPlaceholderText) historiaPlaceholderText.style.display = 'none';

                if (historiaTextoView) historiaTextoView.textContent = currentHistoriaData.historiaCompleta;
                if (historiaBnccDesc) historiaBnccDesc.textContent = currentHistoriaData.bnccCampos;
                if (historiaPerguntasList) {
                  historiaPerguntasList.innerHTML = '';
                  (currentHistoriaData.perguntasCompreensao || []).forEach(p => {
                    const pEl = document.createElement('div');
                    pEl.style.cssText = 'padding: 4px 0; border-bottom: 1px dashed rgba(255,255,255,0.05);';
                    pEl.textContent = p;
                    historiaPerguntasList.appendChild(pEl);
                  });
                }

                renderCurrentScene();
                switchHistoriaTab('cenas');
                historiaHistoryModal.style.display = 'none';
              }
            } catch (err) { showToast('Erro ao carregar história.', 'error'); }
          });
          listContainer.appendChild(div);
        });
      } else {
        listContainer.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Nenhuma história salva ainda.</p>';
      }
    } catch (err) {
      listContainer.innerHTML = '<p style="text-align:center; color:#ef4444;">Erro ao carregar histórico de histórias.</p>';
    }
  }

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initApp);
} else {
  initApp();
}
// ==========================================================================
// PLANEJAMENTO MIND LAB
// ==========================================================================
document.addEventListener('DOMContentLoaded', () => {
  const barBtnMindLab = document.getElementById('barBtnMindLab');
  const mindLabModal = document.getElementById('mindLabModal');
  const btnCloseMindLabModal = document.getElementById('btnCloseMindLabModal');
  const mindLabGamesGrid = document.getElementById('mindLabGamesGrid');
  const mindLabOutroJogoInput = document.getElementById('mindLabOutroJogoInput');
  const btnGenerateMindLab = document.getElementById('btnGenerateMindLab');
  
  const mindLabJogos = {
    infantil: [
      "Gato e Rato", "Cães e Gatos", "Dominó de Cores", "Quebra-cabeças", "Jogos de Encaixe", "Castelo Lógico", "Safari", "Outro"
    ],
    fund1_inicio: [
      "Mancala", "Quoridor", "Hora do Rush", "Bloqueio", "Lig 4", "Pinguins Numa Fria", "Encruzilhada", "Lince", "Outro"
    ],
    fund1_fim: [
      "Abalone", "Quarto", "Octógono Fantástico", "Sudoku", "Damas", "Resta Um", "Xadrez Chinês", "Cilada", "Outro"
    ],
    fund2: [
      "Xadrez", "Mastermind (Senha)", "Abalone Avançado", "Go", "Hex", "Reversi (Othello)", "Blokus", "Outro"
    ]
  };

  function renderMindLabGames(faixa) {
    mindLabGamesGrid.innerHTML = '';
    const jogos = mindLabJogos[faixa] || [];
    jogos.forEach((jogo, index) => {
      const btn = document.createElement('button');
      btn.type = 'button';
      btn.className = `btn-music-option btn-mindlab-jogo ${index === 0 ? 'active' : ''}`;
      btn.dataset.jogo = jogo;
      btn.textContent = jogo === 'Outro' ? '✏️ Outro...' : `🎲 ${jogo}`;
      
      btn.addEventListener('click', () => {
        document.querySelectorAll('.btn-mindlab-jogo').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        if (jogo === 'Outro') {
          mindLabOutroJogoInput.style.display = 'block';
          mindLabOutroJogoInput.focus();
        } else {
          mindLabOutroJogoInput.style.display = 'none';
        }
      });
      mindLabGamesGrid.appendChild(btn);
    });
    mindLabOutroJogoInput.style.display = 'none';
  }

  // Setup Faixa Etária
  document.querySelectorAll('.btn-mindlab-faixa').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-mindlab-faixa').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
      renderMindLabGames(btn.dataset.faixa);
    });
  });

  // Setup Método e Foco
  document.querySelectorAll('.btn-mindlab-metodo').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-mindlab-metodo').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
    });
  });

  document.querySelectorAll('.btn-mindlab-foco').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.btn-mindlab-foco').forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
    });
  });

  if (barBtnMindLab) {
    barBtnMindLab.addEventListener('click', () => {
      mindLabModal.style.display = 'flex';
      renderMindLabGames('infantil');
      document.getElementById('mindLabTemaLivreInput').value = '';
    });
  }

  if (btnCloseMindLabModal) {
    btnCloseMindLabModal.addEventListener('click', () => {
      mindLabModal.style.display = 'none';
    });
    mindLabModal.addEventListener('click', (e) => {
      if (e.target === mindLabModal) mindLabModal.style.display = 'none';
    });
  }

  if (btnGenerateMindLab) {
    btnGenerateMindLab.addEventListener('click', async () => {
      const activeFaixa = document.querySelector('.btn-mindlab-faixa.active');
      const activeJogoBtn = document.querySelector('.btn-mindlab-jogo.active');
      const activeMetodo = document.querySelector('.btn-mindlab-metodo.active');
      const activeFoco = document.querySelector('.btn-mindlab-foco.active');
      
      const faixaStr = activeFaixa ? activeFaixa.textContent.replace('🧸 ', '').replace('🎒 ', '').replace('📚 ', '').replace('🎓 ', '') : '';
      let jogoStr = activeJogoBtn ? activeJogoBtn.dataset.jogo : '';
      if (jogoStr === 'Outro') {
        jogoStr = mindLabOutroJogoInput.value.trim() || 'Jogo não especificado';
      }
      
      const metodoStr = activeMetodo ? activeMetodo.dataset.metodo : '';
      const focoStr = activeFoco ? activeFoco.dataset.foco : '';
      const duracaoStr = document.getElementById('mindLabDuracaoSelect').value;
      const temaLivre = document.getElementById('mindLabTemaLivreInput').value.trim();

      const btnG = document.getElementById('btnGenerateMindLab');
      const loader = document.getElementById('mindLabGenerateLoader');
      const resultArea = document.getElementById('mindLabResultArea');
      const output = document.getElementById('mindLabOutput');
      
      btnG.style.display = 'none';
      loader.style.display = 'flex';
      resultArea.style.display = 'none';

      try {
        const res = await fetch('/api/mindlab/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token')}` },
          body: JSON.stringify({ faixa_etaria: faixaStr, jogo: jogoStr, metodo: metodoStr, foco: focoStr, duracao: duracaoStr, tema: temaLivre })
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Erro na requisição');
        
        output.innerHTML = typeof marked !== 'undefined' ? marked.parse(data.planejamento) : data.planejamento;
        output.dataset.raw = data.planejamento;
        resultArea.style.display = 'block';
        btnG.style.display = 'flex';
        btnG.innerHTML = '🧠 Criar Novo Planejamento';
      } catch (err) {
        alert('Erro ao gerar: ' + err.message);
        btnG.style.display = 'flex';
      } finally {
        loader.style.display = 'none';
      }
    });
  }

  const btnCopyMindLab = document.getElementById('btnCopyMindLab');
  if (btnCopyMindLab) {
    btnCopyMindLab.addEventListener('click', () => {
      const output = document.getElementById('mindLabOutput');
      if (output && output.dataset.raw) {
        navigator.clipboard.writeText(output.dataset.raw);
        btnCopyMindLab.innerHTML = '✅ Copiado!';
        setTimeout(() => {
          btnCopyMindLab.innerHTML = '📋 Copiar';
        }, 2000);
      }
    });
  }

  const btnPdfMindLab = document.getElementById('btnPdfMindLab');
  if (btnPdfMindLab) {
    btnPdfMindLab.addEventListener('click', () => {
      const output = document.getElementById('mindLabOutput');
      if (output && output.dataset.raw && window.jspdf) {
        const { jsPDF } = window.jspdf;
        const doc = new jsPDF();
        doc.setFontSize(12);
        doc.setFont("helvetica", "normal");
        const lines = doc.splitTextToSize(output.dataset.raw.replace(/[#*]/g, ''), 180);
        doc.text(lines, 15, 20);
        doc.save('Planejamento_Mind_Lab.pdf');
      } else {
        alert('Carregando biblioteca PDF ou nenhum conteúdo para salvar.');
      }
    });
  }

  const btnOpenMindLabHistory = document.getElementById('btnOpenMindLabHistory');
  const mindLabHistoryModal = document.getElementById('mindLabHistoryModal');
  const btnCloseMindLabHistory = document.getElementById('btnCloseMindLabHistory');
  const mindLabHistoryList = document.getElementById('mindLabHistoryList');

  if (btnOpenMindLabHistory) {
    btnOpenMindLabHistory.addEventListener('click', async () => {
      mindLabHistoryModal.style.display = 'flex';
      mindLabHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Carregando histórico...</div>';
      try {
        const res = await fetch('/api/mindlab/list', {
          headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
        });
        const data = await res.json();
        mindLabHistoryList.innerHTML = '';
        if (data.length === 0) {
          mindLabHistoryList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Nenhum planejamento salvo ainda.</div>';
          return;
        }
        data.forEach(item => {
          const div = document.createElement('div');
          div.style.background = 'var(--bg-tertiary)';
          div.style.padding = '12px 15px';
          div.style.borderRadius = '8px';
          div.style.display = 'flex';
          div.style.justifyContent = 'space-between';
          div.style.alignItems = 'center';
          div.innerHTML = `
            <div>
              <div style="font-weight: 600; font-size: 0.95rem; color: var(--text-primary);">🎲 ${item.jogo} - ${item.faixa_etaria}</div>
              <div style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 4px;">🎯 ${item.foco}</div>
              <div style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 4px;">${new Date(item.created_at).toLocaleString()}</div>
            </div>
            <div style="display: flex; gap: 8px;">
              <button class="btn-ver-mindlab btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px;">Ver</button>
              <button class="btn-del-mindlab btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.85rem; border-radius: 6px; color: #ef4444; border-color: rgba(239, 68, 68, 0.3);">🗑️</button>
            </div>
          `;
          mindLabHistoryList.appendChild(div);
        });

        document.querySelectorAll('.btn-ver-mindlab').forEach(btn => {
          btn.addEventListener('click', async (e) => {
            const id = e.currentTarget.dataset.id;
            try {
              const res = await fetch(`/api/mindlab/${id}`, {
                headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
              });
              const itemData = await res.json();
              
              document.getElementById('mindLabOutput').innerHTML = typeof marked !== 'undefined' ? marked.parse(itemData.planejamento) : itemData.planejamento;
              document.getElementById('mindLabOutput').dataset.raw = itemData.planejamento;
              document.getElementById('mindLabResultArea').style.display = 'block';
              
              mindLabHistoryModal.style.display = 'none';
              document.getElementById('btnGenerateMindLab').style.display = 'flex';
            } catch (err) { alert('Erro ao carregar planejamento.'); }
          });
        });

        document.querySelectorAll('.btn-del-mindlab').forEach(btn => {
          btn.addEventListener('click', async (e) => {
            if(!confirm('Tem certeza que deseja apagar este planejamento?')) return;
            const id = e.currentTarget.dataset.id;
            try {
              await fetch(`/api/mindlab/${id}`, {
                method: 'DELETE',
                headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
              });
              e.currentTarget.closest('div[style*="var(--bg-tertiary)"]').remove();
            } catch (err) { alert('Erro ao deletar.'); }
          });
        });

      } catch (err) {
        mindLabHistoryList.innerHTML = '<div style="color: #ef4444; padding: 20px;">Erro ao carregar histórico.</div>';
      }
    });
  }

  if (btnCloseMindLabHistory) {
    btnCloseMindLabHistory.addEventListener('click', () => {
      mindLabHistoryModal.style.display = 'none';
    });
  }

  // ============================================================
  // CRIAR CARTAZES
  // ============================================================
  const barBtnCartazes = document.getElementById('barBtnCartazes');
  const cartazesModal = document.getElementById('cartazesModal');
  const btnCloseCartazesModal = document.getElementById('btnCloseCartazesModal');

  const tabCartazesCriar = document.getElementById('tabCartazesCriar');
  const tabCartazesHistorico = document.getElementById('tabCartazesHistorico');
  const panelCartazesCriar = document.getElementById('panelCartazesCriar');
  const panelCartazesHistorico = document.getElementById('panelCartazesHistorico');

  const cartazTituloInput = document.getElementById('cartazTituloInput');
  const cartazSubtituloInput = document.getElementById('cartazSubtituloInput');
  const cartazCardsInput = document.getElementById('cartazCardsInput');
  const cartazRodapeInput = document.getElementById('cartazRodapeInput');
  const cartazTemplateSelect = document.getElementById('cartazTemplateSelect');
  const cartazTurmaSelect = document.getElementById('cartazTurmaSelect');
  const btnCartazResetTemplate = document.getElementById('btnCartazResetTemplate');

  const cartazBgColor = document.getElementById('cartazBgColor');
  const cartazTextColor = document.getElementById('cartazTextColor');
  const cartazFontSelect = document.getElementById('cartazFontSelect');
  const cartazBorderSelect = document.getElementById('cartazBorderSelect');
  const cartazPromptImagem = document.getElementById('cartazPromptImagem');
  const btnGenerateCartazImage = document.getElementById('btnGenerateCartazImage');
  const btnRemoveCartazImage = document.getElementById('btnRemoveCartazImage');
  const btnGenerateCartaz = document.getElementById('btnGenerateCartaz');
  const cartazGenerateLoader = document.getElementById('cartazGenerateLoader');

  const btnExportCartazPNG = document.getElementById('btnExportCartazPNG');
  const btnExportCartazPDF = document.getElementById('btnExportCartazPDF');
  const btnEditCartazToggle = document.getElementById('btnEditCartazToggle');
  const btnPrintCartaz = document.getElementById('btnPrintCartaz');
  const cartazEditArea = document.getElementById('cartazEditArea');
  const cartazHtmlEditor = document.getElementById('cartazHtmlEditor');
  const btnUpdateCartazPreview = document.getElementById('btnUpdateCartazPreview');

  const cartazPrintableArea = document.getElementById('cartazPrintableArea');
  const cartazPreviewTitle = document.getElementById('cartazPreviewTitle');
  const cartazPreviewContent = document.getElementById('cartazPreviewContent');
  const cartazPreviewImageContainer = document.getElementById('cartazPreviewImageContainer');
  const cartazPreviewImage = document.getElementById('cartazPreviewImage');

  const cartazesHistoryContainer = document.getElementById('cartazesHistoryContainer');
  const cartazesNoData = document.getElementById('cartazesNoData');

  let activeCartazData = null;

  // DICIONÁRIO DE TEMPLATES PEDAGÓGICOS PRÉ-CONFIGURADOS
  const CARTAZ_TEMPLATES = {
    combinados: {
      titulo: "🌟 Combinados da Nossa Turma",
      subtitulo: "Educação Infantil • Convivência e Respeito",
      cards: [
        "🤝 Cuidamos dos nossos amigos com carinho",
        "🧸 Guardamos os brinquedos nos cantos certos",
        "🤫 Falamos baixinho na roda de conversa",
        "🧼 Lavamos as mãos antes do lanche",
        "👂 Ouvimos a professora e os colegas com atenção"
      ],
      rodape: "Educando com afeto, empatia e respeito mútuo",
      bg: "#fff9eb",
      text: "#2d3748",
      font: "'Fredoka', sans-serif",
      prompt: "Children holding hands happily in a colorful kindergarten classroom, cute 3D Pixar illustration, bright warm colors, no text"
    },
    rotina: {
      titulo: "🍏 Rotina Diária & Lanche Saudável",
      subtitulo: "Desenvolvimento de Autonomia e Hábitos Saudáveis",
      cards: [
        "🌅 Roda de Acolhida e Canções do Bom Dia",
        "🧼 Higiene e Lavagem Cuidadosa das Mãos",
        "🍎 Hora do Lanche: Servir-se sem desperdícios",
        "🌳 Vivências no Parque, Areia e Natureza",
        "😴 Roda de Histórias, Livros e Relaxamento"
      ],
      rodape: "Promovendo a autonomia e o autocuidado no cotidiano",
      bg: "#f0fdf4",
      text: "#166534",
      font: "'Fredoka', sans-serif",
      prompt: "Cute children having healthy fruit snack at kindergarten table, friendly cartoon vector style, bright colors, no text"
    },
    aniversarios: {
      titulo: "🎂 Mural dos Aniversariantes",
      subtitulo: "Celebrando a vida e o crescimento das nossas crianças!",
      cards: [
        "🎈 Que cada dia seja repleto de brincadeiras!",
        "🎉 Parabéns aos aniversariantes do mês!",
        "🌟 Muita saúde, descobertas e sorrisos!"
      ],
      rodape: "Com todo carinho da Professora e dos Colegas",
      bg: "#fdf2f8",
      text: "#9d174d",
      font: "'Fredoka', sans-serif",
      prompt: "Festive colorful birthday balloons and confetti with smiling animal mascots, cute 3D Pixar illustration, no text"
    },
    brinquedos: {
      titulo: "🧸 Organização dos Brinquedos e Cantos",
      subtitulo: "Nosso espaço escolar é de todos nós!",
      cards: [
        "🧩 Blocos de montar: Caixa Azul",
        "🚗 Carrinhos e transportes: Caixa Verde",
        "📚 Livros de histórias: Estante Baixa",
        "🎨 Tintas e massinhas: Armário de Artes"
      ],
      rodape: "Cuidar dos materiais é um ato de carinho e respeito",
      bg: "#eff6ff",
      text: "#1e40af",
      font: "'Fredoka', sans-serif",
      prompt: "Cute organized classroom toy shelf with colorful wooden blocks and teddy bears, cartoon style, no text"
    },
    bncc_eu_outro: {
      titulo: "🤝 O Eu, o Outro e o Nós",
      subtitulo: "Campo de Experiência BNCC • EI02EO / EI03EO",
      cards: [
        "🌟 Reconhecer e valorizar suas próprias qualidades",
        "💖 Desenvolver empatia e respeito aos sentimentos alheios",
        "🗣️ Resolver pequenos conflitos através do diálogo",
        "🎨 Compartilhar materiais e respeitar a vez dos amigos"
      ],
      rodape: "BNCC Educação Infantil • Identidade, Autonomia e Convivência",
      bg: "#eff6ff",
      text: "#1e40af",
      font: "'Outfit', sans-serif",
      prompt: "Children of diverse backgrounds smiling together and sharing toys, gentle watercolor illustration, no text"
    },
    bncc_corpo: {
      titulo: "🏃 Corpo, Gestos e Movimentos",
      subtitulo: "Campo de Experiência BNCC • EI02CG / EI03CG",
      cards: [
        "🤸 Circuitos motores, equilíbrio, saltos e giros",
        "🎶 Cantigas de roda e expressão corporal rítmica",
        "🚲 Deslocamentos espaciais e controle corporal",
        "⚽ Gincanas cooperativas e respeito a regras"
      ],
      rodape: "BNCC Educação Infantil • Corporeidade, Saúde e Movimento",
      bg: "#fdf2f8",
      text: "#9d174d",
      font: "'Fredoka', sans-serif",
      prompt: "Cute children running, jumping, and playing ring around the rosie outdoors, lively vibrant illustration, no text"
    },
    bncc_tracos: {
      titulo: "🎨 Traços, Sons, Cores e Formas",
      subtitulo: "Campo de Experiência BNCC • EI02TS / EI03TS",
      cards: [
        "🖌️ Pinturas com texturas e tintas naturais",
        "🥁 Exploração de instrumentos musicais e ritmos",
        "🖍️ Desenhos livres de observação e imaginação",
        "🎭 Esculturas com massinha, argila e sucatas"
      ],
      rodape: "BNCC Educação Infantil • Sensibilidade, Expressão e Arte",
      bg: "#fff9eb",
      text: "#b45309",
      font: "'Caveat', cursive",
      prompt: "Children happily painting on big canvases with colorful paint splashes, cute art studio, no text"
    },
    bncc_escuta: {
      titulo: "📖 Escuta, Fala, Pensamento e Imaginação",
      subtitulo: "Campo de Experiência BNCC • EI02EF / EI03EF",
      cards: [
        "📚 Roda de contação e manuseio de livros infantis",
        "🗣️ Expressão oral de ideias, sentimentos e histórias",
        "🎵 Cantigas, parlendas, rimas e trava-línguas",
        "✍️ Contato lúdico com a função social da escrita"
      ],
      rodape: "BNCC Educação Infantil • Linguagem e Letramento Inicial",
      bg: "#f0fdf4",
      text: "#15803d",
      font: "'Fredoka', sans-serif",
      prompt: "Teacher reading an open fairy tale storybook to cozy circle of children, magical soft glow, Pixar 3D, no text"
    },
    bncc_espacos: {
      titulo: "🔍 Espaços, Tempos, Quantidades e Relações",
      subtitulo: "Campo de Experiência BNCC • EI02ET / EI03ET",
      cards: [
        "🌱 Observação do plantio na horta e natureza",
        "🔢 Contagem lúdica com elementos concretos",
        "📐 Identificação de formas geométricas no ambiente",
        "⏳ Noções de tempo: ontem, hoje, amanhã e rotina"
      ],
      rodape: "BNCC Educação Infantil • Curiosidade e Investigação Científica",
      bg: "#eff6ff",
      text: "#1e3a8a",
      font: "'Outfit', sans-serif",
      prompt: "Kids exploring green garden with magnifying glass and planting flowers, vibrant clean illustration, no text"
    },
    mindlab_regras: {
      titulo: "♟️ Cantinho dos Jogos Mind Lab",
      subtitulo: "Metodologia de Jogos & Desenvolvimento Socioemocional",
      cards: [
        "🎯 Pensar antes de agir e planejar sua jogada",
        "🤝 Saber ganhar e saber perder com elegância",
        "⏳ Aguardar a sua vez com calma e autocontrole",
        "💡 Aprender com as tentativas e criar novas estratégias"
      ],
      rodape: "Mind Lab Brasil • Jogos Pedagógicos e Habilidades do Século XXI",
      bg: "#f8fafc",
      text: "#1e293b",
      font: "'Outfit', sans-serif",
      prompt: "Children happily playing a wooden tabletop board game together, focus and teamwork, 3D Pixar, no text"
    },
    mindlab_cooperacao: {
      titulo: "🧩 Desafios de Raciocínio & Cooperação",
      subtitulo: "Metodologia Mind Lab • Resolução de Problemas",
      cards: [
        "👥 O trabalho em equipe nos leva mais longe",
        "🔍 Escuta atenta das ideias dos colegas",
        "🚀 Cada desafio é uma oportunidade de aprender"
      ],
      rodape: "Desenvolvendo liderança, empatia e tomada de decisão",
      bg: "#f0fdf4",
      text: "#166534",
      font: "'Fredoka', sans-serif",
      prompt: "Children putting together giant colorful puzzle pieces together, cooperation, joyful 3D illustration, no text"
    },
    aviso_pais: {
      titulo: "📌 Recado Importante para as Famílias",
      subtitulo: "Comunicação Escola & Comunidade Escolar",
      cards: [
        "📅 Próxima Reunião Pedagógica: Sexta-feira às 17h",
        "🎒 Trazer uma muda de roupa extra identificada",
        "👟 Uso de calçado confortável para o dia de parque",
        "💧 Manter a garrafinha de água individual na mochila"
      ],
      rodape: "A parceria entre escola e família é fundamental para o sucesso das crianças!",
      bg: "#fff9eb",
      text: "#1e293b",
      font: "'Outfit', sans-serif",
      prompt: "Friendly cartoon school bulletin board with colorful notes and cheerful mascot, clean vector, no text"
    },
    mostra_cultural: {
      titulo: "🎉 Convite: Mostra Pedagógica & Cultural",
      subtitulo: "Venha prestigiar as produções e vivências dos nossos pequenos!",
      cards: [
        "🎨 Exposição dos Painéis de Arte e Garatujas",
        "📸 Linha do Tempo das Descobertas do Semestre",
        "🎶 Apresentação Musical e Parlendas da Turma",
        "🌿 Visitação guiada à Horta e Projetos Coletivos"
      ],
      rodape: "Contamos com a presença de todas as famílias!",
      bg: "#fdf2f8",
      text: "#831843",
      font: "'Playfair Display', serif",
      prompt: "Joyful school festival decoration with colorful bunting banners and children artworks, vibrant light, no text"
    }
  };



  // Switch Tab
  function switchCartazTab(tab) {
    if (tab === 'criar') {
      tabCartazesCriar.classList.add('active');
      tabCartazesHistorico.classList.remove('active');
      panelCartazesCriar.style.display = 'flex';
      panelCartazesHistorico.style.display = 'none';
      tabCartazesCriar.style.color = 'var(--text-primary)';
      tabCartazesHistorico.style.color = 'var(--text-secondary)';
    } else {
      tabCartazesCriar.classList.remove('active');
      tabCartazesHistorico.classList.add('active');
      panelCartazesCriar.style.display = 'none';
      panelCartazesHistorico.style.display = 'flex';
      tabCartazesCriar.style.color = 'var(--text-secondary)';
      tabCartazesHistorico.style.color = 'var(--text-primary)';
      loadCartazesHistory();
    }
  }

  if (tabCartazesCriar) tabCartazesCriar.addEventListener('click', () => switchCartazTab('criar'));
  if (tabCartazesHistorico) tabCartazesHistorico.addEventListener('click', () => switchCartazTab('historico'));

  // RENDERIZAR CONTEÚDO DO CARTAZ EM TEMPO REAL
  function renderCartazContentFromInputs() {
    const rawCards = (cartazCardsInput?.value || '').split('\n').map(l => l.trim()).filter(l => l.length > 0);
    const subtitulo = (cartazSubtituloInput?.value || '').trim();
    const rodape = (cartazRodapeInput?.value || '').trim();

    let html = '';
    if (subtitulo) {
      html += `<div style="text-align: center; font-size: 1.15rem; font-weight: 600; opacity: 0.9; margin-bottom: 12px; letter-spacing: 0.3px;">${subtitulo}</div>`;
    }

    if (rawCards.length > 0) {
      html += `<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">`;
      rawCards.forEach((line) => {
        html += `
          <div style="background: rgba(255, 255, 255, 0.4); backdrop-filter: blur(4px); border: 2px solid rgba(0, 0, 0, 0.08); border-radius: 12px; padding: 12px 16px; font-size: 1.05rem; font-weight: 600; display: flex; align-items: center; gap: 10px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);">
            <span>${line}</span>
          </div>
        `;
      });
      html += `</div>`;
    } else {
      html += `<p style="text-align: center; color: rgba(0,0,0,0.4); font-style: italic; padding: 20px 0;">Digite os destaques ou escolha um modelo ao lado.</p>`;
    }

    if (rodape) {
      html += `<div style="margin-top: auto; padding-top: 14px; text-align: center; font-size: 0.85rem; font-weight: 600; opacity: 0.75; border-top: 1px dashed rgba(0,0,0,0.15);">${rodape}</div>`;
    }

    cartazPreviewContent.innerHTML = html;
    if (cartazHtmlEditor) cartazHtmlEditor.value = html;
  }

  // Live Style Updates
  function updateLivePreview() {
    const bg = cartazBgColor.value;
    const text = cartazTextColor.value;
    const font = cartazFontSelect.value;
    const border = cartazBorderSelect.value;
    const title = cartazTituloInput.value.trim() || 'Título do Cartaz';
    const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';

    cartazPrintableArea.style.backgroundColor = bg;
    cartazPrintableArea.style.color = text;
    cartazPrintableArea.style.fontFamily = font;

    cartazPrintableArea.style.width = '100%';
    cartazPrintableArea.style.maxWidth = orientacao === 'paisagem' ? '680px' : '480px';
    cartazPrintableArea.style.aspectRatio = orientacao === 'paisagem' ? '1.414 / 1' : '1 / 1.414';
    cartazPrintableArea.style.height = 'auto';

    cartazPreviewTitle.textContent = title;
    cartazPreviewTitle.style.borderColor = text;

    if (border === 'none') {
      cartazPrintableArea.style.border = 'none';
    } else {
      cartazPrintableArea.style.border = `${border} ${text}`;
    }
  }

  // Event Listeners para inputs em tempo real
  [
    cartazTituloInput,
    cartazSubtituloInput,
    cartazCardsInput,
    cartazRodapeInput
  ].forEach(elem => {
    if (elem) {
      elem.addEventListener('input', () => {
        renderCartazContentFromInputs();
        updateLivePreview();
      });
    }
  });

  [
    cartazBgColor, 
    cartazTextColor, 
    cartazFontSelect, 
    cartazBorderSelect, 
    document.getElementById('cartazOrientacaoSelect')
  ].forEach(elem => {
    if (elem) elem.addEventListener('input', updateLivePreview);
    if (elem && elem.tagName === 'SELECT') elem.addEventListener('change', updateLivePreview);
  });

  // Preset Palettes
  document.querySelectorAll('.btn-palette-preset').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const bg = btn.dataset.bg;
      const text = btn.dataset.text;
      cartazBgColor.value = bg;
      cartazTextColor.value = text;
      updateLivePreview();
    });
  });

  // Gerar Ilustração com IA (MiniMax T2I)
  if (btnGenerateCartazImage) {
    btnGenerateCartazImage.addEventListener('click', async () => {
      const prompt = (cartazPromptImagem?.value || '').trim();
      if (!prompt) {
        await showCustomAlert('Aviso', 'Digite uma descrição para a ilustração no campo acima.');
        return;
      }

      try {
        btnGenerateCartazImage.disabled = true;
        btnGenerateCartazImage.textContent = '⏳ Gerando com IA...';

        const fullPrompt = `${prompt}, high resolution children book illustration, cute Pixar 3D, colorful, no text, clean vector`;

        const resp = await fetch('/api/comics/generate-frame', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ prompt: fullPrompt })
        });

        if (!resp.ok) {
          const err = await resp.json();
          throw new Error(err.error || 'Falha ao gerar ilustração');
        }

        const data = await resp.json();
        if (data.imageUrl) {
          cartazPreviewImage.src = data.imageUrl;
          cartazPreviewImageContainer.style.display = 'block';
          updateLivePreview();
          await showCustomAlert('Ilustração Pronta!', 'A imagem foi gerada e adicionada ao cartaz com sucesso.');
        }
      } catch (err) {
        console.error('Erro ao gerar ilustração do cartaz:', err);
        await showCustomAlert('Erro', 'Não foi possível gerar a ilustração: ' + err.message);
      } finally {
        btnGenerateCartazImage.disabled = false;
        btnGenerateCartazImage.innerHTML = '<span>🪄 Gerar Ilustração com IA</span>';
      }
    });
  }

  if (btnRemoveCartazImage) {
    btnRemoveCartazImage.addEventListener('click', () => {
      cartazPreviewImage.src = '';
      cartazPreviewImageContainer.style.display = 'none';
      if (cartazPromptImagem) cartazPromptImagem.value = '';
      updateLivePreview();
    });
  }

  // --- GERAR CONTEÚDO COM PEDAGOGIA (IA) ---
  if (btnGenerateCartaz) {
    btnGenerateCartaz.addEventListener('click', async () => {
      const titulo = (cartazTituloInput?.value || '').trim();
      const subtitulo = (cartazSubtituloInput?.value || '').trim();
      const promptImagem = (cartazPromptImagem?.value || '').trim();
      const orientacao = document.getElementById('cartazOrientacaoSelect')?.value || 'retrato';

      if (!titulo) {
        await showCustomAlert('Aviso', 'Por favor, informe ao menos o Título Principal do Cartaz.');
        return;
      }

      btnGenerateCartaz.disabled = true;
      if (cartazGenerateLoader) cartazGenerateLoader.style.display = 'flex';

      try {
        const res = await fetch('/api/cartazes/generate', {
          method: 'POST',
          headers: { 
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            titulo,
            tema: subtitulo || titulo,
            corFundo: cartazBgColor?.value || '#fff9eb',
            corTexto: cartazTextColor?.value || '#2d3748',
            layout: 'educativo',
            promptImagem,
            tamanho: 'A4',
            orientacao
          })
        });

        const data = await res.json();
        if (res.ok) {
          activeCartazData = data;
          
          if (data.conteudo) {
            // Extrair texto limpo de tópicos/cards para o input editável
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = data.conteudo;
            const items = Array.from(tempDiv.querySelectorAll('li, p, div')).map(el => el.textContent.trim()).filter(t => t.length > 5 && !t.toLowerCase().includes(titulo.toLowerCase()));
            
            if (items.length > 0) {
              cartazCardsInput.value = items.slice(0, 6).join('\n');
            } else {
              cartazCardsInput.value = tempDiv.textContent.trim();
            }
          }

          if (data.imagemUrl) {
            cartazPreviewImage.src = data.imagemUrl;
            cartazPreviewImageContainer.style.display = 'block';
          }

          renderCartazContentFromInputs();
          updateLivePreview();
          showToast('Cartaz diagramado pela PedagogIA com sucesso!', 'success');
        } else {
          await showCustomAlert('Erro', data.error || 'Erro ao gerar cartaz com IA.');
        }
      } catch (err) {
        console.error('Erro ao gerar cartaz:', err);
        await showCustomAlert('Erro', 'Não foi possível conectar ao assistente: ' + err.message);
      } finally {
        btnGenerateCartaz.disabled = false;
        if (cartazGenerateLoader) cartazGenerateLoader.style.display = 'none';
      }
    });
  }

  // --- EXPORTAR PNG EM ALTA RESOLUÇÃO ---
  if (btnExportCartazPNG) {
    btnExportCartazPNG.addEventListener('click', async () => {
      try {
        btnExportCartazPNG.disabled = true;
        btnExportCartazPNG.textContent = '⏳ Gerando PNG...';

        if (typeof html2canvas === 'undefined') {
          throw new Error('Biblioteca html2canvas não disponível.');
        }

        const canvas = await html2canvas(cartazPrintableArea, {
          scale: 3, // Alta resolução 300 DPI equivalente
          useCORS: true,
          logging: false,
          backgroundColor: cartazBgColor.value || '#fff9eb'
        });

        const title = (cartazTituloInput.value || 'cartaz_pedagog').replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase();
        const link = document.createElement('a');
        link.download = `${title}.png`;
        link.href = canvas.toDataURL('image/png');
        document.body.appendChild(link);
        link.click();
        link.remove();

      } catch (err) {
        console.error('Erro ao exportar PNG:', err);
        await showCustomAlert('Erro', 'Não foi possível gerar o PNG: ' + err.message);
      } finally {
        btnExportCartazPNG.disabled = false;
        btnExportCartazPNG.textContent = '🖼️ Baixar PNG';
      }
    });
  }

  // --- EXPORTAR PDF IMPRIMÍVEL ---
  if (btnExportCartazPDF) {
    btnExportCartazPDF.addEventListener('click', async () => {
      try {
        btnExportCartazPDF.disabled = true;
        btnExportCartazPDF.textContent = '⏳ Criando PDF...';

        if (typeof html2canvas === 'undefined' || typeof window.jspdf === 'undefined') {
          throw new Error('Bibliotecas de PDF necessárias não disponíveis.');
        }

        const orientacao = document.getElementById('cartazOrientacaoSelect')?.value === 'paisagem' ? 'l' : 'p';
        const canvas = await html2canvas(cartazPrintableArea, {
          scale: 3,
          useCORS: true,
          logging: false,
          backgroundColor: cartazBgColor.value || '#fff9eb'
        });

        const imgData = canvas.toDataURL('image/jpeg', 0.95);
        const { jsPDF } = window.jspdf;
        const pdf = new jsPDF(orientacao, 'pt', 'a4');
        const pdfWidth = orientacao === 'l' ? 842 : 595;
        const pdfHeight = orientacao === 'l' ? 595 : 842;

        pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);
        const title = (cartazTituloInput.value || 'cartaz_pedagog').replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase();
        pdf.save(`${title}.pdf`);

      } catch (err) {
        console.error('Erro ao exportar PDF:', err);
        await showCustomAlert('Erro', 'Não foi possível gerar o PDF: ' + err.message);
      } finally {
        btnExportCartazPDF.disabled = false;
        btnExportCartazPDF.textContent = '📄 Baixar PDF';
      }
    });
  }

  // Print Poster
  if (btnPrintCartaz) {
    btnPrintCartaz.addEventListener('click', () => {
      const title = cartazTituloInput.value.trim() || 'Cartaz Pedagógico';
      const bg = cartazBgColor.value;
      const text = cartazTextColor.value;
      const font = cartazFontSelect.value;
      const border = cartazBorderSelect.value;
      const tamanho = document.getElementById('cartazTamanhoSelect') ? document.getElementById('cartazTamanhoSelect').value : 'A4';
      const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
      
      const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block' && cartazPreviewImageContainer.style.position !== 'absolute'
        ? `<div style="width: 100%; margin-bottom: 20px; border-radius: 8px; overflow: hidden; border: 2px solid rgba(0,0,0,0.1); text-align: center; background: rgba(0,0,0,0.02);"><img src="${cartazPreviewImage.src}" style="max-width: 100%; max-height: 350px; object-fit: contain; display: inline-block;"></div>`
        : '';

      let printContent = '';
      const hasCanvasItems = cartazPrintableArea.querySelectorAll('.canvas-item').length > 0;
      
      if (hasCanvasItems) {
        // Clone printable area and cleanup handles / active state borders for print output
        const tempContainer = document.createElement('div');
        tempContainer.innerHTML = cartazPrintableArea.innerHTML;
        tempContainer.querySelectorAll('.canvas-resize-handle').forEach(h => h.remove());
        tempContainer.querySelectorAll('.canvas-item').forEach(item => {
          item.classList.remove('active-item');
          item.removeAttribute('contenteditable');
          if (item.style.border && item.style.border.includes('dashed')) {
            item.style.border = 'none';
          }
        });
        printContent = tempContainer.innerHTML;
      } else {
        printContent = `
          <h1>${title}</h1>
          ${imgContainerHtml}
          <div class="content-area">
            ${cartazPreviewContent.innerHTML}
          </div>
        `;
      }

      const printWindow = window.open('', '_blank');
      printWindow.document.write(`
        <html>
        <head>
          <title>${title} - PedaGog</title>
          <link rel="preconnect" href="https://fonts.googleapis.com">
          <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
          <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&family=Caveat:wght@400;700&family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
          <style>
            * {
              -webkit-print-color-adjust: exact !important;
              print-color-adjust: exact !important;
              box-sizing: border-box;
            }
            @page {
              size: ${tamanho} ${orientacao === 'paisagem' ? 'landscape' : 'portrait'};
              margin: 10mm;
            }
            body { 
              font-family: ${font}; 
              margin: 0; 
              padding: 20px; 
              background-color: #f7fafc; 
              display: flex; 
              justify-content: center; 
              align-items: center; 
              min-height: 100vh;
            }
            .cartaz-frame {
              background-color: ${bg};
              color: ${text};
              padding: 40px;
              border-radius: 16px;
              width: 100%;
              max-width: ${orientacao === 'paisagem' ? '1200px' : '800px'};
              aspect-ratio: ${orientacao === 'paisagem' ? '1.414 / 1' : '1 / 1.414'};
              box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
              box-sizing: border-box;
              border: ${border === 'none' ? 'none' : `${border} ${text}`};
              display: flex;
              flex-direction: column;
              position: relative;
              overflow: hidden;
              container-type: inline-size;
            }
            h1 {
              text-align: center;
              margin-top: 0;
              font-size: 3.5rem;
              border-bottom: 3px solid ${text};
              padding-bottom: 16px;
              margin-bottom: 30px;
            }
            .content-area {
              font-size: 1.5rem;
              line-height: 1.6;
              display: flex;
              flex-direction: ${orientacao === 'paisagem' ? 'row' : 'column'};
              flex-wrap: wrap;
              gap: 20px;
              justify-content: center;
            }
            /* Suporte para cards na content-area */
            .content-area > div, .content-area > p, .content-area > ul {
              box-sizing: border-box;
              background: rgba(255, 255, 255, 0.3);
              padding: 20px;
              border-radius: 12px;
              box-shadow: 0 2px 4px rgba(0,0,0,0.05);
              width: ${orientacao === 'paisagem' ? 'calc(50% - 20px)' : '100%'};
              flex: ${orientacao === 'paisagem' ? '1 1 calc(50% - 20px)' : '0 0 auto'};
              margin: 0;
            }
            ul {
              margin-left: 20px;
            }
            li {
              margin-bottom: 12px;
            }

            /* Estilos específicos do Canvas no PDF/Print */
            .canvas-item {
              position: absolute !important;
              box-sizing: border-box;
            }

            @media print {
              body { background: transparent; padding: 0; display: block; }
              .cartaz-frame { 
                box-shadow: none; 
                border-radius: 0; 
                max-width: 100%; 
                width: 100%; 
                height: auto; 
                min-height: 100%;
                padding: 30px; 
              }
              button { display: none; }
            }
          </style>
        </head>
        <body>
          <div class="cartaz-frame">
            ${printContent}
          </div>
          <script>
            window.onload = function() {
              window.print();
            }
          <\/script>
        </body>
        </html>
      `);
      printWindow.document.close();
    });
  }

  // Load History list
  async function loadCartazesHistory() {
    if (!cartazesHistoryContainer) return;
    cartazesHistoryContainer.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 20px;">Carregando histórico...</div>';
    
    try {
      const res = await fetch('/api/cartazes/list', {
        headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
      });
      const data = await res.json();
      cartazesHistoryContainer.innerHTML = '';
      
      if (!data || data.length === 0) {
        cartazesNoData.style.display = 'block';
        return;
      }
      cartazesNoData.style.display = 'none';

      data.forEach(item => {
        const card = document.createElement('div');
        card.style.background = 'var(--bg-tertiary)';
        card.style.border = '1px solid var(--border-light)';
        card.style.borderRadius = '10px';
        card.style.padding = '16px';
        card.style.display = 'flex';
        card.style.flexDirection = 'column';
        card.style.justifyContent = 'space-between';
        card.style.gap = '12px';
        card.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';

        const thumbnail = item.imagemUrl 
          ? `<div style="height: 120px; overflow:hidden; border-radius: 6px; border: 1px solid var(--border-light); margin-bottom: 6px;">
               <img src="${item.imagemUrl}" style="width:100%; height:100%; object-fit:cover;">
             </div>`
          : `<div style="height: 120px; border-radius: 6px; background: ${item.corFundo || '#fff9eb'}; color: ${item.corTexto || '#2d3748'}; display:flex; align-items:center; justify-content:center; border: 1px solid var(--border-light); margin-bottom: 6px; font-weight: bold; font-size: 0.8rem; overflow: hidden; padding: 10px; text-align:center;">
               ${item.titulo}
             </div>`;

        card.innerHTML = `
          <div>
            ${thumbnail}
            <h5 style="margin: 0; font-size: 1rem; color: var(--text-primary); font-family: 'Outfit', sans-serif;">${item.titulo}</h5>
            <p style="margin: 4px 0 0 0; font-size: 0.8rem; color: var(--text-secondary);">Foco: ${item.tema}</p>
            <span style="font-size: 0.75rem; color: var(--text-muted); display: block; margin-top: 6px;">Layout: ${item.layout.toUpperCase()}</span>
          </div>
          <div style="display: flex; gap: 8px; justify-content: flex-end; border-top: 1px solid var(--border-light); padding-top: 10px;">
            <button class="btn-ver-cartaz btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.8rem; border-radius: 6px; cursor: pointer; background: rgba(59, 130, 246, 0.1); border-color: rgba(59, 130, 246, 0.3); color: #60a5fa;">Ver / Editar</button>
            <button class="btn-del-cartaz btn-secondary" data-id="${item.id}" style="padding: 6px 12px; font-size: 0.8rem; border-radius: 6px; cursor: pointer; color: #ef4444; border-color: rgba(239, 68, 68, 0.3);">🗑️</button>
          </div>
        `;
        cartazesHistoryContainer.appendChild(card);
      });

      // Bind Ver/Editar Buttons
      document.querySelectorAll('.btn-ver-cartaz').forEach(btn => {
        btn.addEventListener('click', async (e) => {
          const id = e.currentTarget.dataset.id;
          try {
            const r = await fetch(`/api/cartazes/${id}`, {
              headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
            });
            const poster = await r.json();
            
            // Set Inputs
            cartazTituloInput.value = poster.titulo;
            cartazTemaInput.value = poster.tema;
            cartazLayoutSelect.value = poster.layout;
            cartazBgColor.value = poster.corFundo;
            cartazTextColor.value = poster.corTexto;
            cartazHtmlEditor.value = poster.conteudo;
            cartazPreviewContent.innerHTML = poster.conteudo;

            if (poster.imagemUrl) {
              cartazPreviewImage.src = poster.imagemUrl;
              cartazPreviewImageContainer.style.display = 'block';
            } else {
              cartazPreviewImageContainer.style.display = 'none';
            }

            updateLivePreview();
            switchCartazTab('criar');
          } catch (err) {
            showToast('Erro ao carregar cartaz.', 'error');
          }
        });
      });

      // Bind Delete Buttons
      document.querySelectorAll('.btn-del-cartaz').forEach(btn => {
        btn.addEventListener('click', async (e) => {
          if (!confirm('Tem certeza que deseja apagar este cartaz?')) return;
          const id = e.currentTarget.dataset.id;
          try {
            const r = await fetch(`/api/cartazes/${id}`, {
              method: 'DELETE',
              headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
            });
            if (r.ok) {
              showToast('Cartaz deletado com sucesso.', 'success');
              loadCartazesHistory();
            } else {
              showToast('Erro ao deletar cartaz.', 'error');
            }
          } catch (err) {
            showToast('Erro de conexão ao deletar cartaz.', 'error');
          }
        });
      });

    } catch (err) {
      console.error(err);
      cartazesHistoryContainer.innerHTML = '<div style="color: #ef4444; padding: 20px;">Erro ao carregar histórico de cartazes.</div>';
    }
  }

  // --- MODO DESIGN CANVAS (EDITOR INTERATIVO DE CARTAZES) ---
  const btnCanvasModeToggle = document.getElementById('btnCanvasModeToggle');
  const canvasControlPanel = document.getElementById('canvasControlPanel');
  const btnCanvasAddText = document.getElementById('btnCanvasAddText');
  const btnCanvasAddCard = document.getElementById('btnCanvasAddCard');
  const canvasFontFamily = document.getElementById('canvasFontFamily');
  const canvasFontSize = document.getElementById('canvasFontSize');
  const canvasTextColor = document.getElementById('canvasTextColor');
  const canvasBgColorInput = document.getElementById('canvasBgColor');
  const canvasRotation = document.getElementById('canvasRotation');
  const canvasOpacity = document.getElementById('canvasOpacity');
  const btnCanvasZIndexUp = document.getElementById('btnCanvasZIndexUp');
  const btnCanvasZIndexDown = document.getElementById('btnCanvasZIndexDown');
  const btnCanvasDelete = document.getElementById('btnCanvasDelete');

  // Novos controles do Painel de Assets Lateral
  const canvasAssetSearch = document.getElementById('canvasAssetSearch');
  const canvasAssetsContainer = document.getElementById('canvasAssetsContainer');
  const btnTabAssetPostits = document.getElementById('btnTabAssetPostits');
  const btnTabAssetStickers = document.getElementById('btnTabAssetStickers');
  const btnTabAssetFormas = document.getElementById('btnTabAssetFormas');

  let canvasModeActive = false;
  let selectedCanvasItem = null;
  let isDraggingCanvas = false;
  let isResizingCanvas = false;
  let dragStartX, dragStartY;
  let dragStartLeft, dragStartTop;
  let dragStartWidth, dragStartHeight;
  let activeAssetTab = 'postit';

  // --- ESTÚDIO DE CENAS EM CAMADAS (novo layer manager) ---
  const btnDecomposeScene = document.getElementById('btnDecomposeScene');
  const btnAddSceneLayer = document.getElementById('btnAddSceneLayer');
  const sceneLayerManagerList = document.getElementById('sceneLayerManagerList');
  const sceneDecomposeLoader = document.getElementById('sceneDecomposeLoader');
  const sceneDecomposeStatus = document.getElementById('sceneDecomposeStatus');

  // Estado das camadas
  let sceneLayers = [];
  let sceneLayerCounter = 0;

  // Cria uma linha de camada no painel
  function createSceneLayerRow(id, isBackground) {
    const row = document.createElement('div');
    row.dataset.layerId = id;
    row.style.cssText = `display:flex; align-items:center; gap:6px; padding:6px 8px;
      background:rgba(255,255,255,0.04); border:1px solid rgba(139,92,246,0.2);
      border-radius:8px; transition: border-color 0.2s;`;

    const badge = document.createElement('div');
    badge.style.cssText = `min-width:22px; height:22px; border-radius:50%; 
      background:${isBackground ? 'rgba(16,163,127,0.3)' : 'rgba(139,92,246,0.3)'};
      display:flex; align-items:center; justify-content:center; font-size:0.7rem; font-weight:700;
      color:${isBackground ? '#10a37f' : '#a78bfa'}; flex-shrink:0;`;
    badge.textContent = isBackground ? '🌄' : sceneLayers.filter(l => !l.isBackground).length;

    const input = document.createElement('input');
    input.type = 'text';
    input.placeholder = isBackground
      ? 'Cenário de fundo (Ex: parque de diversões)'
      : 'Elemento (Ex: menino de 6 anos)';
    input.style.cssText = `flex:1; background:transparent; border:none; outline:none; 
      color:var(--text-primary); font-size:0.82rem; padding:2px 0; min-width:0;`;
    input.addEventListener('input', () => {
      const layer = sceneLayers.find(l => l.id === id);
      if (layer) layer.description = input.value;
    });

    // Botões de ação
    const btnVisibility = document.createElement('button');
    btnVisibility.title = 'Ocultar/Mostrar camada no canvas';
    btnVisibility.innerHTML = '👁️';
    btnVisibility.style.cssText = `background:none; border:none; cursor:pointer; font-size:0.9rem; 
      padding:2px; opacity:1; transition:opacity 0.2s; flex-shrink:0;`;
    let visible = true;
    btnVisibility.addEventListener('click', () => {
      const layer = sceneLayers.find(l => l.id === id);
      if (!layer || !layer.canvasItem) return;
      visible = !visible;
      layer.visible = visible;
      layer.canvasItem.style.display = visible ? '' : 'none';
      btnVisibility.style.opacity = visible ? '1' : '0.3';
      btnVisibility.title = visible ? 'Ocultar camada' : 'Mostrar camada';
    });

    const btnPin = document.createElement('button');
    btnPin.title = 'Fixar posição (impede arrastar)';
    btnPin.innerHTML = '📌';
    btnPin.style.cssText = `background:none; border:none; cursor:pointer; font-size:0.9rem; 
      padding:2px; opacity:0.4; transition:opacity 0.2s; flex-shrink:0;`;
    let pinned = false;
    btnPin.addEventListener('click', () => {
      const layer = sceneLayers.find(l => l.id === id);
      if (!layer || !layer.canvasItem) return;
      pinned = !pinned;
      layer.pinned = pinned;
      layer.canvasItem.style.pointerEvents = pinned ? 'none' : '';
      layer.canvasItem.style.cursor = pinned ? 'default' : 'move';
      btnPin.style.opacity = pinned ? '1' : '0.4';
      btnPin.title = pinned ? 'Desafixar posição' : 'Fixar posição';
    });

    const btnDelete = document.createElement('button');
    btnDelete.title = 'Remover camada';
    btnDelete.innerHTML = '🗑️';
    btnDelete.style.cssText = `background:none; border:none; cursor:pointer; font-size:0.9rem; 
      padding:2px; opacity:0.6; transition:opacity 0.2s; flex-shrink:0;`;
    btnDelete.addEventListener('mouseenter', () => btnDelete.style.opacity = '1');
    btnDelete.addEventListener('mouseleave', () => btnDelete.style.opacity = '0.6');
    btnDelete.addEventListener('click', () => {
      // Remove do canvas se já gerado
      const layer = sceneLayers.find(l => l.id === id);
      if (layer?.canvasItem) layer.canvasItem.remove();
      // Remove do state
      sceneLayers = sceneLayers.filter(l => l.id !== id);
      // Remove do DOM
      row.remove();
      // Reindexar badges dos elementos
      reindexLayerBadges();
    });

    row.appendChild(badge);
    row.appendChild(input);
    row.appendChild(btnVisibility);
    row.appendChild(btnPin);
    if (!isBackground) row.appendChild(btnDelete); // Fundo não pode ser deletado da lista

    return { row, input, badge };
  }

  function reindexLayerBadges() {
    let elIdx = 0;
    sceneLayers.forEach(l => {
      if (!l.isBackground && l.rowBadge) {
        l.rowBadge.textContent = ++elIdx;
      }
    });
  }

  function addSceneLayerEntry(isBackground = false) {
    const id = `sl_${++sceneLayerCounter}`;
    const layerObj = { id, description: '', isBackground, visible: true, pinned: false, canvasItem: null };
    sceneLayers.push(layerObj);

    const { row, input, badge } = createSceneLayerRow(id, isBackground);
    layerObj.rowInput = input;
    layerObj.rowBadge = badge;
    if (sceneLayerManagerList) sceneLayerManagerList.appendChild(row);
    input.focus();
    return layerObj;
  }

  // Inicializa com camada de fundo padrão
  addSceneLayerEntry(true);

  if (btnAddSceneLayer) {
    btnAddSceneLayer.addEventListener('click', () => {
      addSceneLayerEntry(false);
      reindexLayerBadges();
    });
  }

  // ===== REMOÇÃO DE FUNDO BRANCO VIA CANVAS API =====
  async function removeWhiteBackground(imgUrl, threshold = 235) {
    return new Promise((resolve) => {
      const img = new Image();
      img.crossOrigin = 'anonymous';
      img.onload = () => {
        const offscreen = document.createElement('canvas');
        offscreen.width = img.naturalWidth;
        offscreen.height = img.naturalHeight;
        const ctx = offscreen.getContext('2d', { willReadFrequently: true });
        ctx.drawImage(img, 0, 0);

        const imageData = ctx.getImageData(0, 0, offscreen.width, offscreen.height);
        const data = imageData.data;
        const softRange = 20;

        for (let i = 0; i < data.length; i += 4) {
          const r = data[i], g = data[i + 1], b = data[i + 2];
          const minChannel = Math.min(r, g, b);

          if (minChannel >= threshold) {
            data[i + 3] = 0;
          } else if (minChannel >= threshold - softRange) {
            const ratio = (minChannel - (threshold - softRange)) / softRange;
            data[i + 3] = Math.round((1 - ratio) * data[i + 3]);
          }
        }

        ctx.putImageData(imageData, 0, 0);
        resolve(offscreen.toDataURL('image/png'));
      };
      img.onerror = () => resolve(imgUrl);
      img.src = imgUrl;
    });
  }

  // ===== ADICIONA ITEM DE CAMADA NO CANVAS =====
  function addSceneLayerToCanvas(layerData) {
    if (!cartazPrintableArea) return null;

    const item = document.createElement('div');
    item.className = 'canvas-item canvas-scene-layer';
    item.setAttribute('data-layer-name', layerData.name || '');
    item.setAttribute('data-rotation', '0');
    item.style.cssText = `position:absolute; background:transparent; box-sizing:border-box;`;
    item.style.zIndex = layerData.isBackground ? '0' : String(10 + (layerData.zOffset || 0));

    // Cria a imagem SEM usar innerHTML (preserva o handle de resize)
    const imgEl = document.createElement('img');
    imgEl.style.cssText = `width:100%; height:100%; object-fit:${layerData.isBackground ? 'cover' : 'contain'}; pointer-events:none; display:block;`;
    imgEl.src = layerData.url;
    item.appendChild(imgEl);

    // Handle de resize — criado uma única vez e permanece
    const handle = document.createElement('div');
    handle.className = 'canvas-resize-handle';
    item.appendChild(handle);

    if (layerData.isBackground) {
      item.style.left = '0';
      item.style.top = '0';
      item.style.width = '100%';
      item.style.height = '100%';
      item.title = '🖼️ Cenário de Fundo';
    } else {
      item.style.left = (layerData.left || 10) + '%';
      item.style.top = (layerData.top || 10) + '%';
      item.style.width = (layerData.width || 30) + '%';
      item.style.height = (layerData.height || 30) + '%';
      item.title = '🎬 ' + (layerData.name || 'Elemento');

      // Remove fundo branco: atualiza apenas o src da img (preserva o handle)
      removeWhiteBackground(layerData.url).then(transparentUrl => {
        imgEl.src = transparentUrl;
      });
    }

    cartazPrintableArea.appendChild(item);
    setupCanvasItemEvents(item);
    return item;
  }

  // ===== BOTÃO CRIAR CENA =====
  if (btnDecomposeScene) {
    btnDecomposeScene.addEventListener('click', async () => {
      // Validar que há pelo menos fundo + 1 elemento com descrição
      const bgLayer = sceneLayers.find(l => l.isBackground);
      if (!bgLayer?.description?.trim()) {
        showToast('Descreva o cenário de fundo (Camada 🌄)!', 'warning');
        if (bgLayer?.rowInput) bgLayer.rowInput.focus();
        return;
      }
      const elementLayers = sceneLayers.filter(l => !l.isBackground && l.description?.trim());
      if (elementLayers.length === 0) {
        showToast('Adicione pelo menos um elemento (➕ Adicionar Camada)!', 'warning');
        return;
      }

      if (!canvasModeActive) {
        if (cartazEditArea && cartazEditArea.style.display !== 'none') {
          btnEditCartazToggle && btnEditCartazToggle.click();
        }
        enterCanvasMode();
      }

      btnDecomposeScene.disabled = true;
      btnDecomposeScene.style.opacity = '0.6';
      if (sceneDecomposeLoader) sceneDecomposeLoader.style.display = 'flex';

      // Remover camadas anteriores do canvas
      cartazPrintableArea.querySelectorAll('.canvas-scene-layer').forEach(el => el.remove());
      sceneLayers.forEach(l => { l.canvasItem = null; });

      // Gerar cada camada individualmente (uma por uma para acompanhar progresso)
      const totalLayers = 1 + elementLayers.length; // fundo + elementos
      let done = 0;

      const updateStatus = () => {
        done++;
        if (sceneDecomposeStatus) sceneDecomposeStatus.textContent = `Gerando camada ${done}/${totalLayers}...`;
      };

      try {
        const titulo = activeCartazData?.titulo || '';
        const token = localStorage.getItem('token');

        // Gera todas as imagens em paralelo via API (usando os prompts diretos das camadas)
        const allPrompts = [
          { isBackground: true, description: bgLayer.description, layerRef: bgLayer },
          ...elementLayers.map(l => ({ isBackground: false, description: l.description, layerRef: l }))
        ];

        if (sceneDecomposeStatus) sceneDecomposeStatus.textContent = `Enviando para a IA...`;

        const response = await fetch('/api/cartazes/decompose-scene', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
          body: JSON.stringify({
            titulo,
            // Mandamos a estrutura de camadas diretamente (novo campo layers_manual)
            layers_manual: allPrompts.map(p => ({
              isBackground: p.isBackground,
              description: p.description
            }))
          })
        });

        if (!response.ok) {
          const errData = await response.json().catch(() => ({}));
          throw new Error(errData.error || 'Erro na geração da cena.');
        }

        const data = await response.json();
        if (!data.success) throw new Error('Resposta inválida do servidor.');

        if (sceneDecomposeStatus) sceneDecomposeStatus.textContent = 'Montando as camadas no canvas...';

        // Fundo
        if (data.backgroundUrl && bgLayer) {
          bgLayer.canvasItem = addSceneLayerToCanvas({
            url: data.backgroundUrl, name: bgLayer.description, isBackground: true
          });
        }

        // Elementos
        const spread = [
          { left: 8, top: 32 }, { left: 42, top: 38 },
          { left: 64, top: 28 }, { left: 22, top: 56 }
        ];
        if (Array.isArray(data.layers)) {
          data.layers.forEach((layer, idx) => {
            if (!layer.url) return;
            const elLayerRef = elementLayers[idx];
            const pos = spread[idx % spread.length];
            const canvasItem = addSceneLayerToCanvas({
              url: layer.url,
              name: layer.name || elLayerRef?.description || `Elemento ${idx + 1}`,
              isBackground: false,
              left: pos.left, top: pos.top, width: 30, height: 30,
              zOffset: idx + 1
            });
            if (elLayerRef) elLayerRef.canvasItem = canvasItem;
          });
        }

        showToast('🎬 Cena montada! Use os botões 👁️ 📌 🗑️ para controlar cada camada.', 'success');

      } catch (err) {
        console.error('[Cenas em Camadas]', err);
        showToast('Erro ao criar a cena: ' + err.message, 'error');
      } finally {
        btnDecomposeScene.disabled = false;
        btnDecomposeScene.style.opacity = '1';
        if (sceneDecomposeLoader) sceneDecomposeLoader.style.display = 'none';
      }
    });
  }

  // Cria um item de camada de imagem direto no canvas (background ou sticker)
  // Remoção de fundo branco via Canvas API — gera PNG com transparência real
  async function removeWhiteBackground(imgUrl, threshold = 235) {
    return new Promise((resolve) => {
      const img = new Image();
      img.crossOrigin = 'anonymous'; // necessário para getImageData funcionar
      img.onload = () => {
        const offscreen = document.createElement('canvas');
        offscreen.width = img.naturalWidth;
        offscreen.height = img.naturalHeight;
        const ctx = offscreen.getContext('2d', { willReadFrequently: true });
        ctx.drawImage(img, 0, 0);

        const imageData = ctx.getImageData(0, 0, offscreen.width, offscreen.height);
        const data = imageData.data;
        // threshold: pixels com R,G,B >= threshold são considerados "fundos a remover"
        // softRange: faixa de suavização para bordas anti-aliased
        const softRange = 20;

        for (let i = 0; i < data.length; i += 4) {
          const r = data[i];
          const g = data[i + 1];
          const b = data[i + 2];

          // Pega o mínimo dos canais (garante que só pixels "esbranquiçados" sejam afetados)
          const minChannel = Math.min(r, g, b);

          if (minChannel >= threshold) {
            // Área central do branco: totalmente transparente
            data[i + 3] = 0;
          } else if (minChannel >= threshold - softRange) {
            // Zona de borda: transição linear suave para preservar contornos
            const ratio = (minChannel - (threshold - softRange)) / softRange;
            data[i + 3] = Math.round((1 - ratio) * data[i + 3]);
          }
          // Pixels abaixo do threshold - softRange: mantém opacidade original
        }

        ctx.putImageData(imageData, 0, 0);
        resolve(offscreen.toDataURL('image/png'));
      };
      img.onerror = () => {
        console.warn('[removeWhiteBackground] Falha ao carregar imagem, usando original:', imgUrl);
        resolve(imgUrl);
      };
      img.src = imgUrl;
    });
  }

  function addSceneLayerToCanvas(layerData) {
    if (!canvasModeActive || !cartazPrintableArea) return;

    const item = document.createElement('div');
    item.className = 'canvas-item canvas-scene-layer';
    item.setAttribute('data-layer-name', layerData.name || '');
    item.setAttribute('data-rotation', '0');
    item.style.position = 'absolute';
    item.style.left = (layerData.left || 10) + '%';
    item.style.top = (layerData.top || 10) + '%';
    item.style.width = (layerData.width || 35) + '%';
    item.style.height = (layerData.height || 35) + '%';
    item.style.zIndex = layerData.isBackground ? '0' : String(10 + (layerData.zOffset || 0));
    item.style.background = 'transparent';

    if (layerData.isBackground) {
      item.style.left = '0';
      item.style.top = '0';
      item.style.width = '100%';
      item.style.height = '100%';
      item.style.zIndex = '0';
      item.style.pointerEvents = 'none';
      item.innerHTML = `<img src="${layerData.url}" 
        style="width:100%; height:100%; object-fit:cover; pointer-events:none; display:block;">`;
      item.title = '🖼️ Cenário de Fundo';

      const handle = document.createElement('div');
      handle.className = 'canvas-resize-handle';
      item.appendChild(handle);
      cartazPrintableArea.appendChild(item);
      item.style.pointerEvents = 'auto';
      setupCanvasItemEvents(item);

    } else {
      // Adiciona o item ao canvas com um placeholder de loading
      item.innerHTML = `<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;opacity:0.4;">
        <span style="font-size:1.5rem;animation:spin 1s linear infinite;">⏳</span>
      </div>`;
      item.title = '🎬 ' + (layerData.name || 'Elemento');

      const handle = document.createElement('div');
      handle.className = 'canvas-resize-handle';
      item.appendChild(handle);
      cartazPrintableArea.appendChild(item);
      setupCanvasItemEvents(item);

      // Remove o fundo branco de forma assíncrona via Canvas API
      removeWhiteBackground(layerData.url).then(transparentDataUrl => {
        item.innerHTML = `<img src="${transparentDataUrl}" 
          style="width:100%; height:100%; object-fit:contain; pointer-events:none; display:block;">`;
        const newHandle = document.createElement('div');
        newHandle.className = 'canvas-resize-handle';
        item.appendChild(newHandle);
      });
    }

    return item;
  }

  // Renderiza a lista de camadas no painel lateral
  function renderSceneLayers(layers) {
    if (!sceneLayersItems) return;
    sceneLayersItems.innerHTML = '';

    const allLayers = [{ name: '🖼️ Cenário de Fundo', isBackground: true }, ...layers.map(l => ({ ...l }))];
    allLayers.forEach((layer, index) => {
      const chip = document.createElement('div');
      chip.style.cssText = `display:flex; align-items:center; gap:8px; padding:5px 8px; 
        background:rgba(255,255,255,0.05); border:1px solid rgba(139,92,246,0.2); 
        border-radius:6px; font-size:0.78rem; color:var(--text-primary); cursor:pointer;`;
      chip.innerHTML = `
        <span style="font-size:1rem;">${layer.isBackground ? '🌄' : '✨'}</span>
        <span style="flex:1;">${layer.name}</span>
        <span style="font-size:0.68rem; color:var(--text-secondary);">Camada ${index}</span>
      `;
      chip.title = `${layer.isBackground ? 'Fundo da cena' : 'Elemento: ' + layer.name}`;
      sceneLayersItems.appendChild(chip);
    });
  }

  if (btnDecomposeScene) {
    btnDecomposeScene.addEventListener('click', async () => {
      const prompt = sceneDecomposePrompt ? sceneDecomposePrompt.value.trim() : '';
      if (!prompt) {
        showToast('Descreva a cena antes de gerar!', 'warning');
        return;
      }

      // Garantir que o modo canvas está ativo
      if (!canvasModeActive) {
        if (cartazEditArea && cartazEditArea.style.display !== 'none') {
          btnEditCartazToggle && btnEditCartazToggle.click();
        }
        enterCanvasMode();
      }

      // Mostrar loading
      btnDecomposeScene.disabled = true;
      btnDecomposeScene.style.opacity = '0.6';
      if (sceneDecomposeLoader) {
        sceneDecomposeLoader.style.display = 'flex';
      }
      if (sceneLayersList) sceneLayersList.style.display = 'none';

      const statusSteps = [
        'Planejando a cena com IA...',
        'Identificando elementos e cenário...',
        'Gerando imagem de fundo...',
        'Gerando elementos individuais...',
        'Montando as camadas no canvas...'
      ];
      let stepIdx = 0;
      const statusInterval = setInterval(() => {
        if (sceneDecomposeStatus && stepIdx < statusSteps.length) {
          sceneDecomposeStatus.textContent = statusSteps[stepIdx++];
        }
      }, 3500);

      try {
        const titulo = activeCartazData?.titulo || '';
        const response = await fetch('/api/cartazes/decompose-scene', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${localStorage.getItem('token')}`
          },
          body: JSON.stringify({ tema: prompt, titulo })
        });

        clearInterval(statusInterval);

        if (!response.ok) {
          const errData = await response.json().catch(() => ({}));
          throw new Error(errData.error || 'Erro na geração da cena.');
        }

        const data = await response.json();
        if (!data.success) throw new Error('Resposta inválida do servidor.');

        if (sceneDecomposeStatus) sceneDecomposeStatus.textContent = 'Montando as camadas no canvas...';

        // Limpar canvas antes de montar (remover outros items de cena se houver)
        const oldLayers = cartazPrintableArea.querySelectorAll('.canvas-scene-layer');
        oldLayers.forEach(l => l.remove());

        // Adicionar background
        if (data.backgroundUrl) {
          addSceneLayerToCanvas({ url: data.backgroundUrl, name: 'Cenário de Fundo', isBackground: true });
        }

        // Adicionar cada elemento com posição escalonada
        if (Array.isArray(data.layers)) {
          data.layers.forEach((layer, idx) => {
            if (layer.url) {
              const spread = [
                { left: 10, top: 30 },
                { left: 38, top: 35 },
                { left: 62, top: 28 },
                { left: 25, top: 55 }
              ];
              const pos = spread[idx % spread.length];
              addSceneLayerToCanvas({
                url: layer.url,
                name: layer.name || `Elemento ${idx + 1}`,
                isBackground: false,
                left: pos.left,
                top: pos.top,
                width: 28,
                height: 28,
                zOffset: idx + 1
              });
            }
          });

          // Renderizar lista de camadas no painel
          renderSceneLayers(data.layers);
          if (sceneLayersList) sceneLayersList.style.display = 'flex';
        }

        showToast('🎬 Cena montada em camadas! Clique nos elementos para mover, girar e redimensionar.', 'success');

      } catch (err) {
        clearInterval(statusInterval);
        console.error('[Decompose Scene]', err);
        showToast('Erro ao criar a cena em camadas: ' + err.message, 'error');
      } finally {
        btnDecomposeScene.disabled = false;
        btnDecomposeScene.style.opacity = '1';
        if (sceneDecomposeLoader) sceneDecomposeLoader.style.display = 'none';
      }
    });
  }

  function enterCanvasMode() {
    canvasModeActive = true;
    if (btnCanvasModeToggle) {
      btnCanvasModeToggle.textContent = '💾 Salvar Canvas';
      btnCanvasModeToggle.style.background = '#10a37f';
      btnCanvasModeToggle.style.color = 'white';
    }
    if (canvasControlPanel) canvasControlPanel.style.display = 'flex';

    // Alternar painéis laterais
    const configPanel = document.getElementById('cartazLeftConfigPanel');
    const canvasPanel = document.getElementById('cartazLeftCanvasPanel');
    if (configPanel) configPanel.style.display = 'none';
    if (canvasPanel) canvasPanel.style.display = 'flex';
    
    // Iniciar na aba correspondente de assets
    selectAssetTab(activeAssetTab);
    
    cartazPrintableArea.style.position = 'relative';
    const rectParent = cartazPrintableArea.getBoundingClientRect();
    
    const items = [];
    if (cartazPreviewTitle) items.push(cartazPreviewTitle);
    if (cartazPreviewImageContainer && cartazPreviewImageContainer.style.display !== 'none') {
      items.push(cartazPreviewImageContainer);
    }
    
    const cards = Array.from(cartazPreviewContent.children);
    cards.forEach(card => {
      items.push(card);
    });
    
    const clientRects = items.map(item => item.getBoundingClientRect());
    
    items.forEach((item, index) => {
      const rect = clientRects[index];
      
      const leftPercent = ((rect.left - rectParent.left) / rectParent.width) * 100;
      const topPercent = ((rect.top - rectParent.top) / rectParent.height) * 100;
      const widthPercent = (rect.width / rectParent.width) * 100;
      const heightPercent = (rect.height / rectParent.height) * 100;
      
      item.classList.add('canvas-item');
      item.style.position = 'absolute';
      item.style.left = `${leftPercent}%`;
      item.style.top = `${topPercent}%`;
      item.style.width = `${widthPercent}%`;
      item.style.height = `${heightPercent}%`;
      item.style.margin = '0';
      
      item.setAttribute('contenteditable', 'true');
      
      if (!item.querySelector('.canvas-resize-handle')) {
        const handle = document.createElement('div');
        handle.className = 'canvas-resize-handle';
        item.appendChild(handle);
      }
      
      if (item.parentNode === cartazPreviewContent) {
        cartazPrintableArea.appendChild(item);
      }
      
      setupCanvasItemEvents(item);
    });
    
    cartazPreviewContent.style.display = 'none';
    showToast('Modo Design Canvas ativado! Adicione elementos e ajuste o mural livremente.', 'info');
  }

  function exitCanvasMode() {
    canvasModeActive = false;
    if (btnCanvasModeToggle) {
      btnCanvasModeToggle.textContent = '🎨 Design Canvas';
      btnCanvasModeToggle.style.background = 'transparent';
      btnCanvasModeToggle.style.color = 'var(--text-secondary)';
    }
    if (canvasControlPanel) canvasControlPanel.style.display = 'none';

    // Alternar painéis de volta
    const configPanel = document.getElementById('cartazLeftConfigPanel');
    const canvasPanel = document.getElementById('cartazLeftCanvasPanel');
    if (configPanel) configPanel.style.display = 'flex';
    if (canvasPanel) canvasPanel.style.display = 'none';
    
    if (selectedCanvasItem) {
      selectedCanvasItem.classList.remove('active-item');
      selectedCanvasItem = null;
    }
    
    const items = cartazPrintableArea.querySelectorAll('.canvas-item');
    items.forEach(item => {
      item.removeAttribute('contenteditable');
    });

    // Limpar o HTML para persistência (remover seleções/handles)
    const tempContainer = document.createElement('div');
    tempContainer.innerHTML = cartazPrintableArea.innerHTML;
    tempContainer.querySelectorAll('.canvas-resize-handle').forEach(h => h.remove());
    tempContainer.querySelectorAll('.canvas-item').forEach(el => {
      el.classList.remove('active-item');
      el.removeAttribute('contenteditable');
      if (el.style.border && el.style.border.includes('dashed')) {
        el.style.border = 'none';
      }
    });
    const cleanHtml = tempContainer.innerHTML;

    // Persistir alterações de canvas no banco
    if (activeCartazData && activeCartazData.id) {
      fetch(`/api/cartazes/${activeCartazData.id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${localStorage.getItem('token')}`
        },
        body: JSON.stringify({
          conteudo: cleanHtml,
          corFundo: cartazBgColor.value,
          corTexto: cartazTextColor.value
        })
      }).then(res => {
        if (res.ok) {
          showToast('Layout do Canvas salvo no servidor!', 'success');
          loadCartazesHistory();
        } else {
          showToast('Erro ao salvar layout no servidor.', 'error');
        }
      }).catch(e => {
        console.error(e);
        showToast('Erro de conexão ao salvar canvas.', 'error');
      });
    } else {
      showToast('Layout salvo temporariamente. Crie o cartaz para salvar definitivamente.', 'warning');
    }
  }

  function setupCanvasItemEvents(item) {
    item.addEventListener('click', (e) => {
      if (!canvasModeActive) return;
      e.stopPropagation();
      
      if (selectedCanvasItem) {
        selectedCanvasItem.classList.remove('active-item');
      }
      selectedCanvasItem = item;
      item.classList.add('active-item');
      
      updateToolbarForSelected();
    });

    // Clique duplo para focar e editar texto
    item.addEventListener('dblclick', (e) => {
      if (!canvasModeActive) return;
      if (item.querySelector('img')) return; // Evita editar imagens
      
      e.stopPropagation();
      item.setAttribute('contenteditable', 'true');
      item.focus();
      
      // Coloca o cursor de digitação no texto
      const range = document.createRange();
      range.selectNodeContents(item);
      range.collapse(false);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
    });
    
    item.addEventListener('mousedown', (e) => {
      if (!canvasModeActive) return;
      if (e.target.classList.contains('canvas-resize-handle')) return;
      
      // Se o item já estiver focado/editando, permite seleção de texto livre sem arrastar
      if (item.getAttribute('contenteditable') === 'true' && document.activeElement === item) {
        return;
      }
      
      e.preventDefault();
      selectedCanvasItem = item;
      document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
      item.classList.add('active-item');
      updateToolbarForSelected();
      
      isDraggingCanvas = true;
      dragStartX = e.clientX;
      dragStartY = e.clientY;
      
      const parentRect = cartazPrintableArea.getBoundingClientRect();
      const itemRect = item.getBoundingClientRect();
      
      dragStartLeft = ((itemRect.left - parentRect.left) / parentRect.width) * 100;
      dragStartTop = ((itemRect.top - parentRect.top) / parentRect.height) * 100;

      // Previne o highlight azul do browser durante o drag
      document.body.style.userSelect = 'none';
      
      document.addEventListener('mousemove', handleCanvasDrag);
      document.addEventListener('mouseup', stopCanvasDrag);
    });
    
    item.addEventListener('touchstart', (e) => {
      if (!canvasModeActive) return;
      if (e.target.classList.contains('canvas-resize-handle')) return;
      
      if (item.getAttribute('contenteditable') === 'true' && document.activeElement === item) {
        return;
      }
      
      selectedCanvasItem = item;
      document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
      item.classList.add('active-item');
      updateToolbarForSelected();
      
      isDraggingCanvas = true;
      const touch = e.touches[0];
      dragStartX = touch.clientX;
      dragStartY = touch.clientY;
      
      const parentRect = cartazPrintableArea.getBoundingClientRect();
      const itemRect = item.getBoundingClientRect();
      
      dragStartLeft = ((itemRect.left - parentRect.left) / parentRect.width) * 100;
      dragStartTop = ((itemRect.top - parentRect.top) / parentRect.height) * 100;
      
      document.addEventListener('touchmove', handleCanvasTouchDrag, { passive: false });
      document.addEventListener('touchend', stopCanvasDrag);
    });
    
    const handle = item.querySelector('.canvas-resize-handle');
    if (handle) {
      handle.addEventListener('mousedown', (e) => {
        if (!canvasModeActive) return;
        e.stopPropagation();
        e.preventDefault();

        // Garante que o item clicado seja o selecionado
        document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
        selectedCanvasItem = item;
        item.classList.add('active-item');
        updateToolbarForSelected();

        isResizingCanvas = true;
        dragStartX = e.clientX;
        dragStartY = e.clientY;

        const parentRect = cartazPrintableArea.getBoundingClientRect();
        const itemRect = item.getBoundingClientRect();

        dragStartWidth = (itemRect.width / parentRect.width) * 100;
        dragStartHeight = (itemRect.height / parentRect.height) * 100;

        // Previne seleção de texto durante o drag de resize
        document.body.style.userSelect = 'none';

        document.addEventListener('mousemove', handleCanvasResize);
        document.addEventListener('mouseup', stopCanvasResize);
      });

      handle.addEventListener('touchstart', (e) => {
        if (!canvasModeActive) return;
        e.stopPropagation();
        e.preventDefault();

        document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
        selectedCanvasItem = item;
        item.classList.add('active-item');
        updateToolbarForSelected();

        isResizingCanvas = true;
        const touch = e.touches[0];
        dragStartX = touch.clientX;
        dragStartY = touch.clientY;

        const parentRect = cartazPrintableArea.getBoundingClientRect();
        const itemRect = item.getBoundingClientRect();

        dragStartWidth = (itemRect.width / parentRect.width) * 100;
        dragStartHeight = (itemRect.height / parentRect.height) * 100;

        document.addEventListener('touchmove', handleCanvasTouchResize, { passive: false });
        document.addEventListener('touchend', stopCanvasResize);
      });
    }
  }

  function handleCanvasDrag(e) {
    if (!isDraggingCanvas || !selectedCanvasItem) return;
    const dx = e.clientX - dragStartX;
    const dy = e.clientY - dragStartY;
    const parentRect = cartazPrintableArea.getBoundingClientRect();
    const dxPercent = (dx / parentRect.width) * 100;
    const dyPercent = (dy / parentRect.height) * 100;
    
    let newLeft = dragStartLeft + dxPercent;
    let newTop = dragStartTop + dyPercent;
    
    const itemRect = selectedCanvasItem.getBoundingClientRect();
    const itemWPercent = (itemRect.width / parentRect.width) * 100;
    const itemHPercent = (itemRect.height / parentRect.height) * 100;
    
    if (newLeft < 0) newLeft = 0;
    if (newTop < 0) newTop = 0;
    if (newLeft + itemWPercent > 100) newLeft = 100 - itemWPercent;
    if (newTop + itemHPercent > 100) newTop = 100 - itemHPercent;
    
    selectedCanvasItem.style.left = `${newLeft}%`;
    selectedCanvasItem.style.top = `${newTop}%`;
  }
  
  function handleCanvasTouchDrag(e) {
    if (!isDraggingCanvas || !selectedCanvasItem) return;
    e.preventDefault();
    const touch = e.touches[0];
    const dx = touch.clientX - dragStartX;
    const dy = touch.clientY - dragStartY;
    const parentRect = cartazPrintableArea.getBoundingClientRect();
    const dxPercent = (dx / parentRect.width) * 100;
    const dyPercent = (dy / parentRect.height) * 100;
    
    let newLeft = dragStartLeft + dxPercent;
    let newTop = dragStartTop + dyPercent;
    
    const itemRect = selectedCanvasItem.getBoundingClientRect();
    const itemWPercent = (itemRect.width / parentRect.width) * 100;
    const itemHPercent = (itemRect.height / parentRect.height) * 100;
    
    if (newLeft < 0) newLeft = 0;
    if (newTop < 0) newTop = 0;
    if (newLeft + itemWPercent > 100) newLeft = 100 - itemWPercent;
    if (newTop + itemHPercent > 100) newTop = 100 - itemHPercent;
    
    selectedCanvasItem.style.left = `${newLeft}%`;
    selectedCanvasItem.style.top = `${newTop}%`;
  }
  
  function stopCanvasDrag() {
    isDraggingCanvas = false;
    document.body.style.userSelect = ''; // Restaura seleção de texto
    document.removeEventListener('mousemove', handleCanvasDrag);
    document.removeEventListener('mouseup', stopCanvasDrag);
    document.removeEventListener('touchmove', handleCanvasTouchDrag);
    document.removeEventListener('touchend', stopCanvasDrag);
  }
  
  function handleCanvasResize(e) {
    if (!isResizingCanvas || !selectedCanvasItem) return;
    const dx = e.clientX - dragStartX;
    const dy = e.clientY - dragStartY;
    const parentRect = cartazPrintableArea.getBoundingClientRect();
    const dxPercent = (dx / parentRect.width) * 100;
    const dyPercent = (dy / parentRect.height) * 100;
    
    let newWidth = dragStartWidth + dxPercent;
    let newHeight = dragStartHeight + dyPercent;
    
    if (newWidth < 10) newWidth = 10;
    if (newHeight < 5) newHeight = 5;
    
    const itemLeft = parseFloat(selectedCanvasItem.style.left) || 0;
    const itemTop = parseFloat(selectedCanvasItem.style.top) || 0;
    
    if (itemLeft + newWidth > 100) newWidth = 100 - itemLeft;
    if (itemTop + newHeight > 100) newHeight = 100 - itemTop;
    
    selectedCanvasItem.style.width = `${newWidth}%`;
    selectedCanvasItem.style.height = `${newHeight}%`;
  }
  
  function handleCanvasTouchResize(e) {
    if (!isResizingCanvas || !selectedCanvasItem) return;
    e.preventDefault();
    const touch = e.touches[0];
    const dx = touch.clientX - dragStartX;
    const dy = touch.clientY - dragStartY;
    const parentRect = cartazPrintableArea.getBoundingClientRect();
    const dxPercent = (dx / parentRect.width) * 100;
    const dyPercent = (dy / parentRect.height) * 100;
    
    let newWidth = dragStartWidth + dxPercent;
    let newHeight = dragStartHeight + dyPercent;
    
    if (newWidth < 10) newWidth = 10;
    if (newHeight < 5) newHeight = 5;
    
    const itemLeft = parseFloat(selectedCanvasItem.style.left) || 0;
    const itemTop = parseFloat(selectedCanvasItem.style.top) || 0;
    
    if (itemLeft + newWidth > 100) newWidth = 100 - itemLeft;
    if (itemTop + newHeight > 100) newHeight = 100 - itemTop;
    
    selectedCanvasItem.style.width = `${newWidth}%`;
    selectedCanvasItem.style.height = `${newHeight}%`;
  }
  
  function stopCanvasResize() {
    isResizingCanvas = false;
    document.body.style.userSelect = ''; // Restaura seleção de texto
    document.removeEventListener('mousemove', handleCanvasResize);
    document.removeEventListener('mouseup', stopCanvasResize);
    document.removeEventListener('touchmove', handleCanvasTouchResize);
    document.removeEventListener('touchend', stopCanvasResize);
  }

  function rgbToHex(rgb) {
    if (!rgb || rgb === 'transparent') return '#ffffff';
    if (rgb.startsWith('#')) return rgb;
    const match = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
    if (!match) return '#ffffff';
    const r = parseInt(match[1]);
    const g = parseInt(match[2]);
    const b = parseInt(match[3]);
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  }

  function updateToolbarForSelected() {
    if (!selectedCanvasItem) return;
    
    const ff = window.getComputedStyle(selectedCanvasItem).fontFamily.replace(/['"]/g, '').split(',')[0].trim();
    if (canvasFontFamily) canvasFontFamily.value = ff;
    
    const fs = parseFloat(window.getComputedStyle(selectedCanvasItem).fontSize);
    if (canvasFontSize) canvasFontSize.value = Math.round(fs);
    
    const col = rgbToHex(window.getComputedStyle(selectedCanvasItem).color);
    if (canvasTextColor) canvasTextColor.value = col;
    
    const bg = rgbToHex(window.getComputedStyle(selectedCanvasItem).backgroundColor);
    if (canvasBgColorInput) canvasBgColorInput.value = bg;

    const rot = selectedCanvasItem.getAttribute('data-rotation') || '0';
    if (canvasRotation) canvasRotation.value = rot;

    const op = window.getComputedStyle(selectedCanvasItem).opacity || '1';
    if (canvasOpacity) canvasOpacity.value = Math.round(parseFloat(op) * 100);
  }

  if (canvasFontFamily) {
    canvasFontFamily.addEventListener('change', () => {
      if (selectedCanvasItem) selectedCanvasItem.style.fontFamily = canvasFontFamily.value;
    });
  }
  if (canvasFontSize) {
    canvasFontSize.addEventListener('input', () => {
      if (selectedCanvasItem) selectedCanvasItem.style.fontSize = `${canvasFontSize.value}px`;
    });
  }
  if (canvasTextColor) {
    canvasTextColor.addEventListener('input', () => {
      if (selectedCanvasItem) selectedCanvasItem.style.color = canvasTextColor.value;
    });
  }
  if (canvasBgColorInput) {
    canvasBgColorInput.addEventListener('input', () => {
      if (selectedCanvasItem) selectedCanvasItem.style.backgroundColor = canvasBgColorInput.value;
    });
  }
  if (canvasRotation) {
    canvasRotation.addEventListener('input', () => {
      if (selectedCanvasItem) {
        const val = canvasRotation.value;
        selectedCanvasItem.style.transform = `rotate(${val}deg)`;
        selectedCanvasItem.setAttribute('data-rotation', val);
      }
    });
  }
  if (canvasOpacity) {
    canvasOpacity.addEventListener('input', () => {
      if (selectedCanvasItem) {
        const val = canvasOpacity.value;
        selectedCanvasItem.style.opacity = parseFloat(val) / 100;
      }
    });
  }
  if (btnCanvasZIndexUp) {
    btnCanvasZIndexUp.addEventListener('click', () => {
      if (selectedCanvasItem) {
        const currentZ = parseInt(selectedCanvasItem.style.zIndex) || 1;
        selectedCanvasItem.style.zIndex = currentZ + 1;
      }
    });
  }
  if (btnCanvasZIndexDown) {
    btnCanvasZIndexDown.addEventListener('click', () => {
      if (selectedCanvasItem) {
        const currentZ = parseInt(selectedCanvasItem.style.zIndex) || 1;
        selectedCanvasItem.style.zIndex = Math.max(1, currentZ - 1);
      }
    });
  }
  if (btnCanvasDelete) {
    btnCanvasDelete.addEventListener('click', () => {
      if (selectedCanvasItem) {
        selectedCanvasItem.remove();
        selectedCanvasItem = null;
      }
    });
  }
  
  if (btnCanvasAddText) {
    btnCanvasAddText.addEventListener('click', () => {
      if (!canvasModeActive) return;
      const textItem = document.createElement('div');
      textItem.className = 'canvas-item';
      textItem.innerHTML = 'Novo Texto (Clique duplo para editar)';
      textItem.style.left = '10%';
      textItem.style.top = '15%';
      textItem.style.width = '50%';
      textItem.style.height = '8%';
      textItem.style.fontSize = '20px';
      textItem.style.color = cartazTextColor.value || '#2d3748';
      textItem.style.fontFamily = cartazFontSelect.value || 'Fredoka';
      textItem.setAttribute('contenteditable', 'true');
      
      const handle = document.createElement('div');
      handle.className = 'canvas-resize-handle';
      textItem.appendChild(handle);
      
      cartazPrintableArea.appendChild(textItem);
      setupCanvasItemEvents(textItem);
      textItem.click();
    });
  }
  
  if (btnCanvasAddCard) {
    btnCanvasAddCard.addEventListener('click', () => {
      if (!canvasModeActive) return;
      const cardItem = document.createElement('div');
      cardItem.className = 'canvas-item';
      cardItem.style.background = 'rgba(255, 255, 255, 0.4)';
      cardItem.style.border = '2px dashed ' + (cartazTextColor.value || '#2d3748');
      cardItem.style.borderRadius = '12px';
      cardItem.style.left = '20%';
      cardItem.style.top = '25%';
      cardItem.style.width = '45%';
      cardItem.style.height = '20%';
      cardItem.style.padding = '15px';
      cardItem.innerHTML = '<h3>Novo Card</h3><p>Edite este texto...</p>';
      cardItem.style.fontFamily = cartazFontSelect.value || 'Fredoka';
      cardItem.setAttribute('contenteditable', 'true');
      
      const handle = document.createElement('div');
      handle.className = 'canvas-resize-handle';
      cardItem.appendChild(handle);
      
      cartazPrintableArea.appendChild(cardItem);
      setupCanvasItemEvents(cardItem);
      cardItem.click();
    });
  }

  if (btnCanvasModeToggle) {
    btnCanvasModeToggle.addEventListener('click', () => {
      if (canvasModeActive) {
        exitCanvasMode();
      } else {
        if (cartazEditArea && cartazEditArea.style.display !== 'none') {
          btnEditCartazToggle.click();
        }
        enterCanvasMode();
      }
    });
  }

  if (cartazPrintableArea) {
    cartazPrintableArea.addEventListener('click', (e) => {
      if (!canvasModeActive) return;
      if (e.target === cartazPrintableArea) {
        if (selectedCanvasItem) {
          selectedCanvasItem.classList.remove('active-item');
          selectedCanvasItem = null;
        }
      }
    });
  }

  function selectAssetTab(tab) {
    activeAssetTab = tab;
    [btnTabAssetPostits, btnTabAssetStickers, btnTabAssetFormas].forEach(btn => {
      if (!btn) return;
      const tabIdName = `btnTabAsset${tab.charAt(0).toUpperCase() + tab.slice(1)}s`;
      if (btn.id === tabIdName) {
        btn.classList.add('active');
        btn.style.background = 'rgba(59, 130, 246, 0.1)';
        btn.style.color = 'var(--text-primary)';
        btn.style.fontWeight = 'bold';
      } else {
        btn.classList.remove('active');
        btn.style.background = 'transparent';
        btn.style.color = 'var(--text-secondary)';
        btn.style.fontWeight = 'normal';
      }
    });
    loadCanvasAssets(tab, canvasAssetSearch ? canvasAssetSearch.value : '');
  }

  if (btnTabAssetPostits) btnTabAssetPostits.addEventListener('click', () => selectAssetTab('postit'));
  if (btnTabAssetStickers) btnTabAssetStickers.addEventListener('click', () => selectAssetTab('sticker'));
  if (btnTabAssetFormas) btnTabAssetFormas.addEventListener('click', () => selectAssetTab('forma'));

  if (canvasAssetSearch) {
    canvasAssetSearch.addEventListener('input', (e) => {
      loadCanvasAssets(activeAssetTab, e.target.value);
    });
  }

  async function loadCanvasAssets(tipo, busca = '') {
    if (!canvasAssetsContainer) return;
    canvasAssetsContainer.innerHTML = '<div style="grid-column: 1/-1; text-align: center; color: var(--text-secondary); font-size: 0.8rem; padding: 20px;">Carregando...</div>';
    
    try {
      const res = await fetch(`/api/biblioteca-assets?tipo=${tipo}&busca=${encodeURIComponent(busca)}`, {
        headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
      });
      const data = await res.json();
      canvasAssetsContainer.innerHTML = '';
      
      if (!data || data.length === 0) {
        canvasAssetsContainer.innerHTML = '<div style="grid-column: 1/-1; text-align: center; color: var(--text-muted); font-size: 0.75rem; padding: 20px;">Nenhum item encontrado.</div>';
        return;
      }
      
      data.forEach(asset => {
        const item = document.createElement('div');
        item.style.cursor = 'pointer';
        item.style.padding = '8px';
        item.style.borderRadius = '6px';
        item.style.background = 'var(--bg-tertiary)';
        item.style.border = '1px solid var(--border-light)';
        item.style.display = 'flex';
        item.style.flexDirection = 'column';
        item.style.alignItems = 'center';
        item.style.justifyContent = 'center';
        item.style.gap = '6px';
        item.style.transition = 'all 0.2s';
        item.style.aspectRatio = '1';
        item.title = asset.nome;
        
        item.addEventListener('mouseenter', () => {
          item.style.transform = 'scale(1.05)';
          item.style.borderColor = 'rgba(59, 130, 246, 0.5)';
        });
        item.addEventListener('mouseleave', () => {
          item.style.transform = 'scale(1)';
          item.style.borderColor = 'var(--border-light)';
        });
        
        let previewHtml = '';
        if (asset.tipo === 'postit') {
          previewHtml = `<div style="width: 32px; height: 32px; background: ${asset.url}; border-radius: 4px; box-shadow: 1px 2px 4px rgba(0,0,0,0.15); transform: rotate(-5deg);"></div>`;
        } else if (asset.tipo === 'sticker') {
          previewHtml = `<img src="${asset.url}" style="width: 36px; height: 36px; object-fit: contain;">`;
        } else if (asset.tipo === 'forma') {
          if (asset.url === 'rect') {
            previewHtml = `<div style="width: 36px; height: 24px; border: 2px solid var(--text-primary); border-radius: 2px;"></div>`;
          } else if (asset.url === 'square') {
            previewHtml = `<div style="width: 30px; height: 30px; border: 2px solid var(--text-primary); border-radius: 2px;"></div>`;
          } else if (asset.url === 'circle') {
            previewHtml = `<div style="width: 32px; height: 32px; border: 2px solid var(--text-primary); border-radius: 50%;"></div>`;
          } else if (asset.url === 'ellipse') {
            previewHtml = `<div style="width: 36px; height: 22px; border: 2px solid var(--text-primary); border-radius: 50%;"></div>`;
          } else if (asset.url === 'line') {
            previewHtml = `<div style="width: 36px; height: 2px; background: var(--text-primary); margin: 15px 0;"></div>`;
          } else if (asset.url === 'triangle') {
            previewHtml = `<div style="width: 32px; height: 32px; background: var(--text-primary); clip-path: polygon(50% 0%, 0% 100%, 100% 100%);"></div>`;
          } else if (asset.url === 'star') {
            previewHtml = `<div style="font-size: 24px; color: var(--text-primary); display: flex; align-items: center; justify-content: center; height: 32px;">⭐</div>`;
          } else if (asset.url === 'arrow') {
            previewHtml = `<div style="font-size: 24px; color: var(--text-primary); display: flex; align-items: center; justify-content: center; height: 32px;">➡️</div>`;
          }
        }
        
        item.innerHTML = `
          ${previewHtml}
          <span style="font-size: 0.65rem; color: var(--text-primary); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%;">${asset.nome}</span>
        `;
        
        item.addEventListener('click', () => addAssetToCanvas(asset));
        canvasAssetsContainer.appendChild(item);
      });
    } catch(err) {
      console.error(err);
      canvasAssetsContainer.innerHTML = '<div style="grid-column: 1/-1; text-align: center; color: #ef4444; font-size: 0.75rem; padding: 10px;">Erro ao carregar elementos.</div>';
    }
  }

  function addAssetToCanvas(asset) {
    if (!canvasModeActive) return;
    
    const item = document.createElement('div');
    item.className = 'canvas-item';
    item.style.position = 'absolute';
    item.style.left = '35%';
    item.style.top = '35%';
    item.style.width = '30%';
    item.style.height = '15%';
    item.style.zIndex = '10';
    
    if (asset.tipo === 'postit') {
      item.style.background = asset.url;
      item.style.color = '#2d3748';
      item.style.boxShadow = '3px 5px 10px rgba(0,0,0,0.15)';
      item.style.borderRadius = '4px';
      const randomRot = Math.round(Math.random() * 8 - 4);
      item.style.transform = `rotate(${randomRot}deg)`;
      item.setAttribute('data-rotation', randomRot);
      item.style.padding = '12px';
      item.style.fontFamily = "'Caveat', cursive";
      item.style.fontSize = '22px';
      item.innerHTML = 'Anotação...';
      item.setAttribute('contenteditable', 'true');
      item.style.width = '35%';
      item.style.height = '20%';
    } else if (asset.tipo === 'sticker') {
      item.style.background = 'transparent';
      item.innerHTML = `<img src="${asset.url}" style="width: 100%; height: 100%; object-fit: contain; pointer-events: none;">`;
      item.style.width = '20%';
      item.style.height = '20%';
      item.setAttribute('data-rotation', '0');
    } else if (asset.tipo === 'forma') {
      item.style.background = 'transparent';
      item.style.border = '3px solid ' + (cartazTextColor.value || '#2d3748');
      item.setAttribute('data-rotation', '0');
      if (asset.url === 'rect') {
        item.style.borderRadius = '4px';
      } else if (asset.url === 'square') {
        item.style.borderRadius = '4px';
        item.style.width = '20%';
        item.style.height = '20%';
      } else if (asset.url === 'circle' || asset.url === 'ellipse') {
        item.style.borderRadius = '50%';
        item.style.width = '20%';
        item.style.height = '20%';
      } else if (asset.url === 'line') {
        item.style.border = 'none';
        item.style.borderTop = '4px solid ' + (cartazTextColor.value || '#2d3748');
        item.style.height = '10px';
        item.style.width = '40%';
      } else if (asset.url === 'triangle') {
        item.style.border = 'none';
        item.style.background = cartazTextColor.value || '#2d3748';
        item.style.clipPath = 'polygon(50% 0%, 0% 100%, 100% 100%)';
        item.style.width = '20%';
        item.style.height = '20%';
      } else if (asset.url === 'star') {
        item.style.border = 'none';
        item.style.color = cartazTextColor.value || '#2d3748';
        item.style.fontSize = '48px';
        item.style.display = 'flex';
        item.style.alignItems = 'center';
        item.style.justifyContent = 'center';
        item.innerHTML = '⭐';
        item.style.width = '20%';
        item.style.height = '20%';
      } else if (asset.url === 'arrow') {
        item.style.border = 'none';
        item.style.color = cartazTextColor.value || '#2d3748';
        item.style.fontSize = '48px';
        item.style.display = 'flex';
        item.style.alignItems = 'center';
        item.style.justifyContent = 'center';
        item.innerHTML = '➡️';
        item.style.width = '20%';
        item.style.height = '20%';
      }
    }
    
    const handle = document.createElement('div');
    handle.className = 'canvas-resize-handle';
    item.appendChild(handle);
    
    cartazPrintableArea.appendChild(item);
    setupCanvasItemEvents(item);
    item.click();
  }
});

// ==========================================================================
// MÓDULOS EXPANDIDOS: DOSSIÊ DO ALUNO, PROTOCOLO DE CRISES, ATAS & STICKERS
// ==========================================================================
document.addEventListener('DOMContentLoaded', () => {

  // ------------------------------------------------------------------------
  // 1. DOSSIÊ & LINHA DO TEMPO DO ALUNO
  // ------------------------------------------------------------------------
  const alunoTimelineModal = document.getElementById('alunoTimelineModal');
  const btnCloseAlunoTimeline = document.getElementById('btnCloseAlunoTimeline');
  const timelineAlunoNome = document.getElementById('timelineAlunoNome');
  const timelineAlunoInfo = document.getElementById('timelineAlunoInfo');
  const timelineContentArea = document.getElementById('timelineContentArea');
  const btnExportFichaConselho = document.getElementById('btnExportFichaConselho');
  let currentTimelineAlunoId = null;

  if (btnCloseAlunoTimeline) btnCloseAlunoTimeline.addEventListener('click', () => alunoTimelineModal.style.display = 'none');
  if (alunoTimelineModal) alunoTimelineModal.addEventListener('click', (e) => { if (e.target === alunoTimelineModal) alunoTimelineModal.style.display = 'none'; });

  window.viewChildTimeline = async (alunoId) => {
    currentTimelineAlunoId = alunoId;
    alunoTimelineModal.style.display = 'flex';
    timelineContentArea.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando dossiê...</p>';

    try {
      const res = await fetch(`/api/alunos/${alunoId}/timeline`);
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Erro ao carregar dados');

      const aluno = data.aluno;
      timelineAlunoNome.textContent = `Dossiê: ${aluno.nome} ${aluno.especial ? '⭐ (Ed. Especial)' : ''}`;
      timelineAlunoInfo.textContent = `Nasc: ${aluno.data_nasc ? new Date(aluno.data_nasc).toLocaleDateString('pt-BR') : 'Não informada'} • Pais: ${aluno.pais || 'Não informados'} • Saúde: ${aluno.observacoes_saude || 'Nenhuma alergia/restrição'}`;

      let html = '';

      // Seção Observações
      const obs = data.timeline.observacoes || [];
      html += `<h4 style="color:#f43f5e; margin:10px 0 6px 0; font-size:0.95rem;">📝 Observações Registradas (${obs.length})</h4>`;
      if (obs.length === 0) {
        html += '<p style="font-size:0.8rem; color:var(--text-secondary);">Nenhuma observação registrada ainda.</p>';
      } else {
        obs.forEach(o => {
          html += `
            <div style="background:rgba(244,63,94,0.05); border-left:3px solid #f43f5e; padding:8px 12px; border-radius:4px; font-size:0.82rem; margin-bottom:6px;">
              <div style="display:flex; justify-content:space-between; color:var(--text-secondary); font-size:0.75rem;">
                <strong>📅 ${o.date || ''} ${o.time || ''}</strong>
                ${o.tags ? `<span>🏷️ ${o.tags}</span>` : ''}
              </div>
              <p style="margin:4px 0 0 0; color:var(--text-primary);">${escapeHtml(o.report || '')}</p>
            </div>
          `;
        });
      }

      // Seção Stickers & Conquistas
      const stks = data.timeline.stickers || [];
      html += `<h4 style="color:#fbbf24; margin:14px 0 6px 0; font-size:0.95rem;">🌟 Conquistas & Stickers Recebidos (${stks.length})</h4>`;
      if (stks.length === 0) {
        html += '<p style="font-size:0.8rem; color:var(--text-secondary);">Nenhum sticker concedido ainda.</p>';
      } else {
        html += '<div style="display:flex; flex-wrap:wrap; gap:8px;">';
        stks.forEach(s => {
          html += `
            <div style="background:rgba(245,158,11,0.1); border:1px solid rgba(245,158,11,0.3); border-radius:6px; padding:6px 10px; font-size:0.8rem;">
              <span style="font-size:1.1rem;">${s.icone || '🌟'}</span> <strong>${escapeHtml(s.titulo)}</strong>
              <div style="font-size:0.7rem; color:var(--text-secondary);">${escapeHtml(s.categoria)} • ${new Date(s.created_at).toLocaleDateString('pt-BR')}</div>
            </div>
          `;
        });
        html += '</div>';
      }

      // Seção Histórias
      const hists = data.timeline.historias || [];
      if (hists.length > 0) {
        html += `<h4 style="color:#10b981; margin:14px 0 6px 0; font-size:0.95rem;">📖 Histórias em que Participou (${hists.length})</h4>`;
        hists.forEach(h => {
          html += `
            <div style="background:rgba(16,185,129,0.05); border-left:3px solid #10b981; padding:8px 12px; border-radius:4px; font-size:0.82rem; margin-bottom:6px;">
              <strong>${escapeHtml(h.titulo || h.tema)}</strong>
              <div style="font-size:0.72rem; color:var(--text-secondary);">${h.faixa_etaria} • ${new Date(h.created_at).toLocaleDateString('pt-BR')}</div>
            </div>
          `;
        });
      }

      // Seção Ocorrências / Crises
      const crises = data.timeline.crises || [];
      if (crises.length > 0) {
        html += `<h4 style="color:#ef4444; margin:14px 0 6px 0; font-size:0.95rem;">🚨 Registros de Mediação / Acolhimento (${crises.length})</h4>`;
        crises.forEach(cr => {
          html += `
            <div style="background:rgba(239,68,68,0.05); border-left:3px solid #ef4444; padding:8px 12px; border-radius:4px; font-size:0.82rem; margin-bottom:6px;">
              <div style="display:flex; justify-content:space-between; font-size:0.75rem; color:#f87171;">
                <strong>${escapeHtml(cr.tipo_evento)} (${cr.intensidade})</strong>
                <span>${new Date(cr.data_hora).toLocaleString('pt-BR')}</span>
              </div>
              <p style="margin:4px 0 0 0; color:var(--text-primary);">${escapeHtml(cr.descricao)}</p>
              <div style="font-size:0.75rem; color:var(--text-secondary); margin-top:2px;"><strong>Acolhimento:</strong> ${escapeHtml(cr.medidas_tomadas)}</div>
            </div>
          `;
        });
      }

      // Seção Relatórios Semestrais
      const rels = data.timeline.relatorios || [];
      if (rels.length > 0) {
        html += `<h4 style="color:#3b82f6; margin:14px 0 6px 0; font-size:0.95rem;">📄 Relatórios Semestrais Emitidos (${rels.length})</h4>`;
        rels.forEach(r => {
          html += `
            <div style="background:rgba(59,130,246,0.05); border-left:3px solid #3b82f6; padding:8px 12px; border-radius:4px; font-size:0.82rem; margin-bottom:6px;">
              <strong>${r.semestre}º Semestre de ${r.ano_letivo} (${r.faixa_etaria})</strong>
              <p style="margin:4px 0 0 0; color:var(--text-primary); max-height:100px; overflow-y:auto; font-size:0.8rem;">${escapeHtml(r.conteudo_relatorio)}</p>
            </div>
          `;
        });
      }

      timelineContentArea.innerHTML = html;
    } catch (err) {
      timelineContentArea.innerHTML = `<p style="color:#ef4444; text-align:center;">Erro: ${err.message}</p>`;
    }
  };

  // Exportar Ficha para Conselho de Classe
  if (btnExportFichaConselho) {
    btnExportFichaConselho.addEventListener('click', async () => {
      if (!currentTimelineAlunoId) return;
      try {
        const res = await fetch(`/api/alunos/${currentTimelineAlunoId}/conselho-ficha`);
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Falha ao buscar ficha');

        const aluno = data.aluno;
        const win = window.open('', '_blank');
        win.document.write(`
          <!DOCTYPE html>
          <html lang="pt-BR">
          <head>
            <meta charset="UTF-8">
            <title>Ficha de Conselho - ${aluno.nome}</title>
            <style>
              body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 40px; color: #1e293b; line-height: 1.6; max-width: 800px; margin: 0 auto; }
              h1 { color: #1e40af; border-bottom: 2px solid #cbd5e1; padding-bottom: 8px; margin-bottom: 16px; font-size: 1.6rem; }
              .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 20px; background: #f8fafc; padding: 15px; border-radius: 8px; border: 1px solid #e2e8f0; }
              .btn-p { background: #3b82f6; color: white; border: none; padding: 10px 20px; border-radius: 6px; font-weight: bold; cursor: pointer; float: right; }
              @media print { .btn-p { display: none; } body { padding: 0; } }
            </style>
          </head>
          <body>
            <button class="btn-p" onclick="window.print()">🖨️ Imprimir Ficha</button>
            <h1>📋 Ficha Individual de Acompanhamento / Conselho de Classe</h1>
            <div class="grid">
              <div><strong>Aluno(a):</strong> ${aluno.nome}</div>
              <div><strong>Turma:</strong> ${aluno.turma_nome || 'N/A'}</div>
              <div><strong>Data Nasc:</strong> ${aluno.data_nasc ? new Date(aluno.data_nasc).toLocaleDateString('pt-BR') : 'N/A'}</div>
              <div><strong>Educação Especial:</strong> ${aluno.especial ? 'Sim (' + (aluno.especial_detalhes || '') + ')' : 'Não'}</div>
              <div><strong>Total de Observações:</strong> ${data.totalObservacoes}</div>
              <div><strong>Emissão:</strong> ${data.dataFicha}</div>
            </div>
            <h3>🌟 Conquistas Pedagógicas:</h3>
            <ul>
              ${(data.conquistas || []).map(c => `<li><strong>${c.titulo}</strong> (${c.categoria})</li>`).join('') || '<li>Nenhuma conquista pontual registrada.</li>'}
            </ul>
            <div style="margin-top: 50px; display: flex; justify-content: space-between; border-top: 1px solid #cbd5e1; padding-top: 20px;">
              <div style="text-align: center; width: 45%;">___________________________<br>Professora Titular</div>
              <div style="text-align: center; width: 45%;">___________________________<br>Coordenação Pedagógica</div>
            </div>
          </body>
          </html>
        `);
        win.document.close();
      } catch (e) {
        alert('Erro ao gerar ficha: ' + e.message);
      }
    });
  }

  // ------------------------------------------------------------------------
  // 2. IMPORTAÇÃO CSV DE ALUNOS
  // ------------------------------------------------------------------------
  const csvImportModal = document.getElementById('csvImportModal');
  const btnCloseCsvImport = document.getElementById('btnCloseCsvImport');
  const csvImportTurmaSelect = document.getElementById('csvImportTurmaSelect');
  const csvFileInput = document.getElementById('csvFileInput');
  const csvTextContent = document.getElementById('csvTextContent');
  const btnProcessCsvImport = document.getElementById('btnProcessCsvImport');

  if (btnCloseCsvImport) btnCloseCsvImport.addEventListener('click', () => csvImportModal.style.display = 'none');
  if (csvImportModal) csvImportModal.addEventListener('click', (e) => { if (e.target === csvImportModal) csvImportModal.style.display = 'none'; });

  // Botão abrir CSV import (se presente na tela de turmas ou sidebar)
  window.openCsvImportModal = () => {
    csvImportModal.style.display = 'flex';
    if (csvImportTurmaSelect) {
      csvImportTurmaSelect.innerHTML = '';
      (currentTurmas || []).forEach(t => {
        const opt = document.createElement('option');
        opt.value = t.id;
        opt.textContent = t.nome;
        csvImportTurmaSelect.appendChild(opt);
      });
    }
  };

  if (csvFileInput) {
    csvFileInput.addEventListener('change', (e) => {
      const file = e.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (evt) => {
          if (csvTextContent) csvTextContent.value = evt.target.result;
        };
        reader.readAsText(file, 'UTF-8');
      }
    });
  }

  if (btnProcessCsvImport) {
    btnProcessCsvImport.addEventListener('click', async () => {
      const turmaId = csvImportTurmaSelect ? csvImportTurmaSelect.value : null;
      const csv = csvTextContent ? csvTextContent.value.trim() : '';

      if (!turmaId || !csv) {
        alert('Por favor, selecione a turma e forneça o conteúdo CSV.');
        return;
      }

      btnProcessCsvImport.disabled = true;
      btnProcessCsvImport.textContent = '⏳ Importando...';

      try {
        const res = await fetch('/api/alunos/import-csv', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ turma_id: turmaId, csv_content: csv })
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Erro na importação');

        alert(`✅ Sucesso! ${data.count} alunos foram importados para a turma.`);
        csvImportModal.style.display = 'none';
        if (typeof fetchAlunos === 'function') await fetchAlunos();
        if (typeof renderAlunosList === 'function') renderAlunosList();
      } catch (err) {
        alert('Erro ao importar CSV: ' + err.message);
      } finally {
        btnProcessCsvImport.disabled = false;
        btnProcessCsvImport.textContent = '📥 Importar Alunos';
      }
    });
  }

  // ------------------------------------------------------------------------
  // 3. PROTOCOLO DE CRISES & MEDIAÇÃO COMPORTAMENTAL
  // ------------------------------------------------------------------------
  const btnProtocoloCrise = document.getElementById('btnProtocoloCrise');
  const criseModal = document.getElementById('criseModal');
  const btnCloseCriseModal = document.getElementById('btnCloseCriseModal');
  const btnOpenCrisesHistory = document.getElementById('btnOpenCrisesHistory');
  const criseHistoryModal = document.getElementById('criseHistoryModal');
  const btnCloseCriseHistory = document.getElementById('btnCloseCriseHistory');
  const criseTurmaSelect = document.getElementById('criseTurmaSelect');
  const criseAlunoInput = document.getElementById('criseAlunoInput');
  const criseTipoSelect = document.getElementById('criseTipoSelect');
  const criseIntensidadeSelect = document.getElementById('criseIntensidadeSelect');
  const criseDescricaoInput = document.getElementById('criseDescricaoInput');
  const criseMedidasInput = document.getElementById('criseMedidasInput');
  const btnSalvarCrise = document.getElementById('btnSalvarCrise');
  const criseWhatsappOutput = document.getElementById('criseWhatsappOutput');
  const btnCopyCriseWhatsapp = document.getElementById('btnCopyCriseWhatsapp');
  const btnSendWhatsappDirect = document.getElementById('btnSendWhatsappDirect');
  const criseHistoryList = document.getElementById('criseHistoryList');

  function populateCriseTurmas() {
    if (!criseTurmaSelect) return;
    criseTurmaSelect.innerHTML = '<option value="">-- Selecionar Turma --</option>';
    (currentTurmas || []).forEach(t => {
      const opt = document.createElement('option');
      opt.value = t.id;
      opt.textContent = t.nome;
      criseTurmaSelect.appendChild(opt);
    });
  }

  if (btnProtocoloCrise) {
    btnProtocoloCrise.addEventListener('click', () => {
      criseModal.style.display = 'flex';
      populateCriseTurmas();
    });
  }
  if (btnCloseCriseModal) btnCloseCriseModal.addEventListener('click', () => criseModal.style.display = 'none');
  if (criseModal) criseModal.addEventListener('click', (e) => { if (e.target === criseModal) criseModal.style.display = 'none'; });

  if (btnOpenCrisesHistory) {
    btnOpenCrisesHistory.addEventListener('click', async () => {
      criseHistoryModal.style.display = 'flex';
      if (!criseHistoryList) return;
      criseHistoryList.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando...</p>';
      try {
        const res = await fetch('/api/crises/list');
        const data = await res.json();
        if (data.length === 0) {
          criseHistoryList.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Nenhuma ocorrência registrada.</p>';
          return;
        }
        criseHistoryList.innerHTML = data.map(c => `
          <div style="background:rgba(255,255,255,0.02); border:1px solid var(--border-light); padding:12px; border-radius:8px; display:flex; flex-direction:column; gap:4px; position:relative;">
            <div style="display:flex; justify-content:space-between; padding-right:24px;">
              <strong style="color:#ef4444; font-size:0.9rem;">${escapeHtml(c.aluno_nome)} • ${escapeHtml(c.tipo_evento)}</strong>
              <span style="font-size:0.72rem; color:var(--text-secondary);">${new Date(c.data_hora).toLocaleString('pt-BR')}</span>
            </div>
            <p style="margin:4px 0; font-size:0.82rem; color:var(--text-primary);">${escapeHtml(c.descricao)}</p>
            <div style="font-size:0.75rem; color:var(--text-secondary);"><strong>Medidas:</strong> ${escapeHtml(c.medidas_tomadas)}</div>
            <button onclick="deleteCriseRecord('${c.id}')" style="position:absolute; top:8px; right:8px; background:none; border:none; color:#ef4444; cursor:pointer;" title="Excluir">🗑️</button>
          </div>
        `).join('');
      } catch (e) {
        criseHistoryList.innerHTML = `<p style="color:#ef4444;">Erro ao carregar: ${e.message}</p>`;
      }
    });
  }

  window.deleteCriseRecord = async (id) => {
    if (confirm('Deseja excluir este registro de mediação?')) {
      await fetch(`/api/crises/${id}`, { method: 'DELETE' });
      if (btnOpenCrisesHistory) btnOpenCrisesHistory.click();
    }
  };

  if (btnCloseCriseHistory) btnCloseCriseHistory.addEventListener('click', () => criseHistoryModal.style.display = 'none');

  if (btnSalvarCrise) {
    btnSalvarCrise.addEventListener('click', async () => {
      const alunoNome = criseAlunoInput ? criseAlunoInput.value.trim() : '';
      const tipo = criseTipoSelect ? criseTipoSelect.value : '';
      const intensidade = criseIntensidadeSelect ? criseIntensidadeSelect.value : 'Moderada';
      const desc = criseDescricaoInput ? criseDescricaoInput.value.trim() : '';
      const medidas = criseMedidasInput ? criseMedidasInput.value.trim() : '';
      const turmaId = criseTurmaSelect ? criseTurmaSelect.value : null;

      if (!alunoNome || !desc) {
        alert('Por favor, informe o nome da criança e a descrição do ocorrido.');
        return;
      }

      btnSalvarCrise.disabled = true;
      btnSalvarCrise.innerHTML = '⏳ Gerando Registro e Mensagem...';

      try {
        const res = await fetch('/api/crises/register', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            aluno_nome: alunoNome,
            turma_id: turmaId,
            tipo_evento: tipo,
            intensidade: intensidade,
            descricao: desc,
            medidas_tomadas: medidas
          })
        });

        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Falha ao registrar ocorrência');

        if (criseWhatsappOutput) criseWhatsappOutput.textContent = data.mensagemWhatsapp || '';
        if (btnSendWhatsappDirect) {
          btnSendWhatsappDirect.href = `https://api.whatsapp.com/send?text=${encodeURIComponent(data.mensagemWhatsapp || '')}`;
          btnSendWhatsappDirect.style.display = 'block';
        }
        alert('✅ Protocolo registrado com sucesso! Mensagem para os pais gerada.');
      } catch (err) {
        alert('Erro ao registrar crise: ' + err.message);
      } finally {
        btnSalvarCrise.disabled = false;
        btnSalvarCrise.innerHTML = '🛡️ Registrar & Gerar Mensagem WhatsApp';
      }
    });
  }

  if (btnCopyCriseWhatsapp) {
    btnCopyCriseWhatsapp.addEventListener('click', () => {
      if (criseWhatsappOutput && criseWhatsappOutput.textContent) {
        navigator.clipboard.writeText(criseWhatsappOutput.textContent);
        alert('Mensagem copiada para a área de transferência!');
      }
    });
  }

  // ------------------------------------------------------------------------
  // 4. ATAS DE REUNIÃO & CONSELHO DE CLASSE
  // ------------------------------------------------------------------------
  const btnAtasReuniao = document.getElementById('btnAtasReuniao');
  const ataModal = document.getElementById('ataModal');
  const btnCloseAtaModal = document.getElementById('btnCloseAtaModal');
  const btnOpenAtasHistory = document.getElementById('btnOpenAtasHistory');
  const atasHistoryModal = document.getElementById('atasHistoryModal');
  const btnCloseAtasHistory = document.getElementById('btnCloseAtasHistory');
  const ataTurmaSelect = document.getElementById('ataTurmaSelect');
  const ataTipoSelect = document.getElementById('ataTipoSelect');
  const ataTituloInput = document.getElementById('ataTituloInput');
  const ataParticipantesInput = document.getElementById('ataParticipantesInput');
  const ataPautaInput = document.getElementById('ataPautaInput');
  const ataDiscussoesInput = document.getElementById('ataDiscussoesInput');
  const ataDeliberacoesInput = document.getElementById('ataDeliberacoesInput');
  const btnGerarAta = document.getElementById('btnGerarAta');
  const ataOutputText = document.getElementById('ataOutputText');
  const btnCopyAta = document.getElementById('btnCopyAta');
  const btnPrintAtaPdf = document.getElementById('btnPrintAtaPdf');
  const atasHistoryList = document.getElementById('atasHistoryList');

  function populateAtaTurmas() {
    if (!ataTurmaSelect) return;
    ataTurmaSelect.innerHTML = '<option value="">-- Geral / Toda a Escola --</option>';
    (currentTurmas || []).forEach(t => {
      const opt = document.createElement('option');
      opt.value = t.id;
      opt.textContent = t.nome;
      ataTurmaSelect.appendChild(opt);
    });
  }

  if (btnAtasReuniao) {
    btnAtasReuniao.addEventListener('click', () => {
      ataModal.style.display = 'flex';
      populateAtaTurmas();
    });
  }
  if (btnCloseAtaModal) btnCloseAtaModal.addEventListener('click', () => ataModal.style.display = 'none');
  if (ataModal) ataModal.addEventListener('click', (e) => { if (e.target === ataModal) ataModal.style.display = 'none'; });

  if (btnGerarAta) {
    btnGerarAta.addEventListener('click', async () => {
      const titulo = ataTituloInput ? ataTituloInput.value.trim() : '';
      const tipo = ataTipoSelect ? ataTipoSelect.value : '';
      const discussoes = ataDiscussoesInput ? ataDiscussoesInput.value.trim() : '';
      const pauta = ataPautaInput ? ataPautaInput.value.trim() : '';
      const part = ataParticipantesInput ? ataParticipantesInput.value.split(',').map(p => p.trim()) : [];
      const delib = ataDeliberacoesInput ? ataDeliberacoesInput.value.trim() : '';
      const turmaId = ataTurmaSelect ? ataTurmaSelect.value : null;

      if (!titulo || !discussoes) {
        alert('Por favor, informe o título da reunião e os tópicos discutidos.');
        return;
      }

      btnGerarAta.disabled = true;
      btnGerarAta.innerHTML = '⏳ Redigindo Ata Oficial com IA...';

      try {
        const res = await fetch('/api/atas/generate', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            tipo_reuniao: tipo,
            titulo: titulo,
            turma_id: turmaId,
            pauta: pauta,
            participantes: part,
            discussoes: discussoes,
            deliberacoes: delib
          })
        });

        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Falha ao redigir ata');

        if (ataOutputText) ataOutputText.textContent = data.textoAta || '';
        alert('✅ Ata formal redigida com sucesso!');
      } catch (err) {
        alert('Erro ao gerar ata: ' + err.message);
      } finally {
        btnGerarAta.disabled = false;
        btnGerarAta.innerHTML = '📋 Gerar Ata Oficial Formatada';
      }
    });
  }

  if (btnCopyAta) {
    btnCopyAta.addEventListener('click', () => {
      if (ataOutputText && ataOutputText.textContent) {
        navigator.clipboard.writeText(ataOutputText.textContent);
        alert('Ata copiada para a área de transferência!');
      }
    });
  }

  if (btnPrintAtaPdf) {
    btnPrintAtaPdf.addEventListener('click', () => {
      if (!ataOutputText || !ataOutputText.textContent) return;
      const win = window.open('', '_blank');
      win.document.write(`
        <!DOCTYPE html>
        <html lang="pt-BR">
        <head>
          <meta charset="UTF-8">
          <title>Ata de Reunião - Pedagog</title>
          <style>
            body { font-family: 'Times New Roman', Times, serif; padding: 45px; color: #000; line-height: 1.8; max-width: 800px; margin: 0 auto; text-align: justify; }
            h1 { text-align: center; font-size: 1.4rem; text-transform: uppercase; margin-bottom: 25px; }
            .btn-p { background: #8b5cf6; color: white; border: none; padding: 8px 16px; border-radius: 4px; font-weight: bold; cursor: pointer; float: right; font-family: sans-serif; }
            @media print { .btn-p { display: none; } body { padding: 0; } }
          </style>
        </head>
        <body>
          <button class="btn-p" onclick="window.print()">🖨️ Imprimir / Salvar PDF</button>
          <h1>ATA DE REUNIÃO ESCOLAR</h1>
          <div>${escapeHtml(ataOutputText.textContent).replace(/\n/g, '<br>')}</div>
        </body>
        </html>
      `);
      win.document.close();
    });
  }

  if (btnOpenAtasHistory) {
    btnOpenAtasHistory.addEventListener('click', async () => {
      atasHistoryModal.style.display = 'flex';
      if (!atasHistoryList) return;
      atasHistoryList.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Carregando atas...</p>';
      try {
        const res = await fetch('/api/atas/list');
        const data = await res.json();
        if (data.length === 0) {
          atasHistoryList.innerHTML = '<p style="text-align:center; color:var(--text-secondary);">Nenhuma ata salva.</p>';
          return;
        }
        atasHistoryList.innerHTML = data.map(a => `
          <div style="background:rgba(255,255,255,0.02); border:1px solid var(--border-light); padding:12px; border-radius:8px; display:flex; justify-content:space-between; align-items:center;">
            <div>
              <strong style="color:#a78bfa; font-size:0.92rem;">${escapeHtml(a.titulo)}</strong>
              <div style="font-size:0.75rem; color:var(--text-secondary);">${escapeHtml(a.tipo_reuniao)} • ${new Date(a.data_reuniao).toLocaleDateString('pt-BR')}</div>
            </div>
            <button onclick="deleteAtaRecord('${a.id}')" style="background:none; border:none; color:#ef4444; cursor:pointer;" title="Excluir">🗑️</button>
          </div>
        `).join('');
      } catch (e) {
        atasHistoryList.innerHTML = `<p style="color:#ef4444;">Erro: ${e.message}</p>`;
      }
    });
  }

  window.deleteAtaRecord = async (id) => {
    if (confirm('Deseja excluir esta ata?')) {
      await fetch(`/api/atas/${id}`, { method: 'DELETE' });
      if (btnOpenAtasHistory) btnOpenAtasHistory.click();
    }
  };

  if (btnCloseAtasHistory) btnCloseAtasHistory.addEventListener('click', () => atasHistoryModal.style.display = 'none');

  // ------------------------------------------------------------------------
  // 5. STICKERS GAMIFICADOS & CARTELA A4 DE IMPRESSÃO
  // ------------------------------------------------------------------------
  const btnStickersConquistas = document.getElementById('btnStickersConquistas');
  const stickerModal = document.getElementById('stickerModal');
  const btnCloseStickerModal = document.getElementById('btnCloseStickerModal');
  const stickerTurmaSelect = document.getElementById('stickerTurmaSelect');
  const stickerAlunoInput = document.getElementById('stickerAlunoInput');
  const stickerCategoriaSelect = document.getElementById('stickerCategoriaSelect');
  const stickerTituloInput = document.getElementById('stickerTituloInput');
  const stickerDescricaoInput = document.getElementById('stickerDescricaoInput');
  const btnEmitirSticker = document.getElementById('btnEmitirSticker');
  const stickersListGrid = document.getElementById('stickersListGrid');
  const btnPrintStickerSheet = document.getElementById('btnPrintStickerSheet');

  function populateStickerTurmas() {
    if (!stickerTurmaSelect) return;
    stickerTurmaSelect.innerHTML = '<option value="">-- Selecionar Turma --</option>';
    (currentTurmas || []).forEach(t => {
      const opt = document.createElement('option');
      opt.value = t.id;
      opt.textContent = t.nome;
      stickerTurmaSelect.appendChild(opt);
    });
  }

  async function loadStickersGrid() {
    if (!stickersListGrid) return;
    stickersListGrid.innerHTML = '<p style="text-align:center; color:var(--text-secondary); grid-column:1/-1;">Carregando...</p>';
    try {
      const res = await fetch('/api/stickers/list');
      const data = await res.json();
      if (data.length === 0) {
        stickersListGrid.innerHTML = '<p style="text-align:center; color:var(--text-secondary); grid-column:1/-1;">Nenhum sticker emitido ainda.</p>';
        return;
      }
      stickersListGrid.innerHTML = data.map(s => `
        <div style="background:rgba(255,255,255,0.03); border:2px dashed rgba(245,158,11,0.4); border-radius:10px; padding:10px; text-align:center; display:flex; flex-direction:column; align-items:center; gap:4px; position:relative;">
          <span style="font-size:1.8rem;">${s.icone || '🌟'}</span>
          <strong style="font-size:0.8rem; color:#fbbf24;">${escapeHtml(s.titulo)}</strong>
          <span style="font-size:0.75rem; color:var(--text-primary);">${escapeHtml(s.aluno_nome)}</span>
          ${s.qr_code_url ? `<img src="${s.qr_code_url}" style="width:50px; height:50px; margin-top:4px; border-radius:4px;" title="QR Code para a família">` : ''}
          <button onclick="deleteStickerRecord('${s.id}')" style="position:absolute; top:4px; right:4px; background:none; border:none; color:#ef4444; font-size:0.8rem; cursor:pointer;" title="Excluir">✕</button>
        </div>
      `).join('');
    } catch (e) {
      stickersListGrid.innerHTML = `<p style="color:#ef4444; grid-column:1/-1;">Erro: ${e.message}</p>`;
    }
  }

  if (btnStickersConquistas) {
    btnStickersConquistas.addEventListener('click', () => {
      stickerModal.style.display = 'flex';
      populateStickerTurmas();
      loadStickersGrid();
    });
  }
  if (btnCloseStickerModal) btnCloseStickerModal.addEventListener('click', () => stickerModal.style.display = 'none');
  if (stickerModal) stickerModal.addEventListener('click', (e) => { if (e.target === stickerModal) stickerModal.style.display = 'none'; });

  window.deleteStickerRecord = async (id) => {
    if (confirm('Deseja excluir este sticker?')) {
      await fetch(`/api/stickers/${id}`, { method: 'DELETE' });
      loadStickersGrid();
    }
  };

  if (btnEmitirSticker) {
    btnEmitirSticker.addEventListener('click', async () => {
      const alunoNome = stickerAlunoInput ? stickerAlunoInput.value.trim() : '';
      const titulo = stickerTituloInput ? stickerTituloInput.value.trim() : '';
      const cat = stickerCategoriaSelect ? stickerCategoriaSelect.value : 'Cooperação & Gentileza';
      const desc = stickerDescricaoInput ? stickerDescricaoInput.value.trim() : '';
      const turmaId = stickerTurmaSelect ? stickerTurmaSelect.value : null;

      if (!alunoNome || !titulo || !desc) {
        alert('Por favor, informe a criança, o título da conquista e a descrição.');
        return;
      }

      let icone = '🌟';
      if (cat.includes('Cooperação')) icone = '🤝';
      else if (cat.includes('Curiosidade')) icone = '🔬';
      else if (cat.includes('Autonomia')) icone = '🌱';
      else if (cat.includes('Artística')) icone = '🎨';
      else if (cat.includes('Coragem')) icone = '⭐';
      else if (cat.includes('Roda')) icone = '🗣️';

      try {
        const res = await fetch('/api/stickers/create', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            aluno_nome: alunoNome,
            turma_id: turmaId,
            titulo: titulo,
            categoria: cat,
            icone: icone,
            descricao: desc
          })
        });
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Falha ao emitir sticker');
        alert('✅ Conquista registrada com sucesso!');
        loadStickersGrid();
      } catch (err) {
        alert('Erro: ' + err.message);
      }
    });
  }

  // Imprimir Cartela A4 com Stickers Recortáveis
  if (btnPrintStickerSheet) {
    btnPrintStickerSheet.addEventListener('click', async () => {
      try {
        const res = await fetch('/api/stickers/list');
        const stickers = await res.json();
        if (stickers.length === 0) {
          alert('Emita ao menos um sticker antes de imprimir a cartela.');
          return;
        }

        const win = window.open('', '_blank');
        let stickersHtml = '';
        stickers.forEach(s => {
          stickersHtml += `
            <div style="border: 2px dashed #f59e0b; border-radius: 12px; padding: 12px; text-align: center; background: #fffbeb; page-break-inside: avoid; display: flex; flex-direction: column; align-items: center; justify-content: center;">
              <span style="font-size: 2.2rem;">${s.icone || '🌟'}</span>
              <strong style="font-size: 0.95rem; color: #b45309; margin-top: 4px;">${escapeHtml(s.titulo)}</strong>
              <div style="font-size: 0.85rem; font-weight: bold; color: #1e293b;">${escapeHtml(s.aluno_nome)}</div>
              <p style="font-size: 0.72rem; color: #64748b; margin: 4px 0 6px 0;">${escapeHtml(s.descricao)}</p>
              ${s.qr_code_url ? `<img src="${s.qr_code_url}" style="width: 60px; height: 60px; border-radius: 4px; border: 1px solid #e2e8f0;">` : ''}
              <div style="font-size: 0.65rem; color: #94a3b8; margin-top: 4px;">Pedagog • Conquista Escolar</div>
            </div>
          `;
        });

        win.document.write(`
          <!DOCTYPE html>
          <html lang="pt-BR">
          <head>
            <meta charset="UTF-8">
            <title>Cartela de Adesivos - Pedagog</title>
            <style>
              body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 25px; margin: 0; }
              .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }
              .btn-p { background: #f59e0b; color: white; border: none; padding: 10px 20px; border-radius: 6px; font-weight: bold; cursor: pointer; float: right; margin-bottom: 15px; }
              @media print { .btn-p { display: none; } body { padding: 0; } }
            </style>
          </head>
          <body>
            <button class="btn-p" onclick="window.print()">🖨️ Imprimir em Papel Adesivo / A4</button>
            <h2 style="margin: 0 0 15px 0; color: #b45309;">🌟 Cartela de Conquistas da Turma</h2>
            <div class="grid">
              ${stickersHtml}
            </div>
          </body>
          </html>
        `);
        win.document.close();
      } catch (e) {
        alert('Erro ao imprimir cartela: ' + e.message);
      }
    });
  }

});

