// ============================================================================
// Miku Control Panel — Memory Management Module
// ============================================================================

async function refreshMemoryStats() {
  try {
    // Fetch Cat status
    const statusData = await apiCall('/memory/status');

    const indicator = document.getElementById('cat-status-indicator');
    const toggleBtn = document.getElementById('cat-toggle-btn');

    if (statusData.healthy) {
      indicator.innerHTML = `<span style="color: #6fdc6f;">● Connected</span> — ${statusData.url}`;
    } else {
      indicator.innerHTML = `<span style="color: #ff6b6b;">● Disconnected</span> — ${statusData.url}`;
    }

    if (statusData.circuit_breaker_active) {
      indicator.innerHTML += ` <span style="color: #dcb06f;">(circuit breaker active)</span>`;
    }

    toggleBtn.textContent = statusData.enabled ? '🐱 Cat: ON' : '😿 Cat: OFF';
    toggleBtn.style.background = statusData.enabled ? '#2a7a2a' : '#7a2a2a';
    toggleBtn.style.borderColor = statusData.enabled ? '#4a9a4a' : '#9a4a4a';

    // Fetch memory stats
    const statsData = await apiCall('/memory/stats');

    if (statsData.success && statsData.collections) {
      const collections = {};
      statsData.collections.forEach(c => { collections[c.name] = c.vectors_count; });

      document.getElementById('stat-episodic-count').textContent = collections['episodic'] ?? '—';
      document.getElementById('stat-declarative-count').textContent = collections['declarative'] ?? '—';
      document.getElementById('stat-procedural-count').textContent = collections['procedural'] ?? '—';
    } else {
      document.getElementById('stat-episodic-count').textContent = '—';
      document.getElementById('stat-declarative-count').textContent = '—';
      document.getElementById('stat-procedural-count').textContent = '—';
    }

    // Show consolidation schedule info if available
    const consInfo = document.getElementById('consolidation-schedule-info');
    if (consInfo && statusData.consolidation) {
      let infoHtml = '';
      const cons = statusData.consolidation;
      if (cons.last_run) {
        const lastRun = new Date(cons.last_run).toLocaleString();
        infoHtml += `🕐 Last run: ${lastRun}`;
        if (cons.last_error) {
          infoHtml += ` <span style="color: #ff6b6b;">❌ ${escapeHtml(cons.last_error)}</span>`;
        } else if (cons.last_result) {
          infoHtml += ` <span style="color: #6fdc6f;">✅</span>`;
        }
        infoHtml += `<br>`;
      } else {
        infoHtml += `🕐 Last run: never<br>`;
      }
      infoHtml += `📊 Runs: ${cons.successful_runs}/${cons.total_runs} successful`;
      if (cons.is_running) {
        infoHtml += ` <span style="color: #dcb06f;">⏳ (running now)</span>`;
      }
      consInfo.innerHTML = infoHtml;
    }
  } catch (err) {
    console.error('Error refreshing memory stats:', err);
    document.getElementById('cat-status-indicator').innerHTML = '<span style="color: #ff6b6b;">● Error checking status</span>';
  }
}

async function toggleCatIntegration() {
  try {
    const statusData = await apiCall('/memory/status');
    const newState = !statusData.enabled;

    const formData = new FormData();
    formData.append('enabled', newState);
    const res = await fetch('/memory/toggle', { method: 'POST', body: formData });
    const data = await res.json();

    if (data.success) {
      showNotification(`Cheshire Cat ${newState ? 'enabled' : 'disabled'}`, newState ? 'success' : 'info');
      refreshMemoryStats();
    }
  } catch (err) {
    showNotification('Failed to toggle Cat integration', 'error');
  }
}

async function triggerConsolidation() {
  const btn = document.getElementById('consolidate-btn');
  const status = document.getElementById('consolidation-status');
  const resultDiv = document.getElementById('consolidation-result');

  btn.disabled = true;
  btn.textContent = '⏳ Running...';
  status.textContent = 'Consolidation in progress (this may take a few minutes)...';
  status.style.color = '#dcb06f';
  resultDiv.style.display = 'none';

  try {
    const data = await apiCall('/memory/consolidate', 'POST');

    if (data.success) {
      status.textContent = '⏳ Consolidation started — waiting for completion...';
      
      // Poll /memory/status until consolidation finishes
      const pollInterval = 5000; // 5 seconds
      const maxPolls = 120; // 10 minutes max
      
      for (let i = 0; i < maxPolls; i++) {
        await new Promise(r => setTimeout(r, pollInterval));
        
        const statusData = await apiCall('/memory/status');
        const cons = statusData.consolidation;
        
        if (!cons.is_running) {
          // Consolidation finished
          if (cons.last_error) {
            status.textContent = '❌ ' + cons.last_error;
            status.style.color = '#ff6b6b';
            resultDiv.textContent = 'Error: ' + cons.last_error;
            resultDiv.style.display = 'block';
            showNotification('Consolidation failed: ' + cons.last_error, 'error');
          } else {
            status.textContent = '✅ Consolidation complete!';
            status.style.color = '#6fdc6f';
            resultDiv.textContent = cons.last_result || 'Consolidation finished successfully.';
            resultDiv.style.display = 'block';
            showNotification('Memory consolidation complete', 'success');
          }
          refreshMemoryStats();
          break;
        } else {
          // Still running — update status message
          status.textContent = `⏳ Consolidation still running... (${Math.round((i + 1) * pollInterval / 1000)}s elapsed)`;
        }
      }
      
      // If we exited the loop without finishing
      const finalStatus = await apiCall('/memory/status');
      if (finalStatus.consolidation?.is_running) {
        status.textContent = '⏳ Consolidation still running — check back later';
        status.style.color = '#dcb06f';
      }
    } else {
      status.textContent = '❌ ' + (data.error || 'Consolidation failed');
      status.style.color = '#ff6b6b';
    }
  } catch (err) {
    status.textContent = '❌ Error: ' + err.message;
    status.style.color = '#ff6b6b';
  } finally {
    btn.disabled = false;
    btn.textContent = '🌙 Run Consolidation';
  }
}

async function loadFacts() {
  const listDiv = document.getElementById('facts-list');
  listDiv.innerHTML = '<div style="text-align: center; color: #888; padding: 1rem;">Loading facts...</div>';

  try {
    const data = await apiCall('/memory/facts');

    if (!data.success || data.count === 0) {
      listDiv.innerHTML = '<div style="text-align: center; color: #666; padding: 2rem;">No declarative facts stored yet.</div>';
      return;
    }

    let html = '';
    data.facts.forEach((fact, i) => {
      const source = fact.metadata?.source || 'unknown';
      const when = fact.metadata?.when ? new Date(fact.metadata.when * 1000).toLocaleString() : 'unknown';
      const persona = fact.metadata?.persona || 'miku';
      const personaBadge = persona === 'evil_miku'
        ? '<span style="background: #7a2a2a; color: #ff9999; font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 3px; margin-left: 0.3rem;">😈 Evil Miku</span>'
        : '<span style="background: #2a5a7a; color: #99ccff; font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 3px; margin-left: 0.3rem;">🎤 Miku</span>';
      const factDataJson = escapeJsonForAttribute(fact);
      html += `
        <div class="memory-item" style="background: #242424; padding: 0.6rem 0.8rem; margin-bottom: 0.4rem; border-radius: 4px; border-left: 3px solid #2a9955; display: flex; justify-content: space-between; align-items: flex-start;">
          <div style="flex: 1;">
            <div style="color: #ddd; font-size: 0.9rem;">${escapeHtml(fact.content)}${personaBadge}</div>
            <div style="color: #666; font-size: 0.75rem; margin-top: 0.3rem;">
              Source: ${escapeHtml(source)} · ${when}
            </div>
          </div>
          <div style="display: flex; gap: 0.3rem; flex-shrink: 0;">
            <button data-memory='${factDataJson}' onclick='showEditMemoryModalFromButton(this, "declarative", "${fact.id}")'
              style="background: none; border: none; color: #5599cc; cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem;"
              title="Edit this fact">✏️</button>
            <button onclick="deleteMemoryPoint('declarative', '${fact.id}', this)"
              style="background: none; border: none; color: #993333; cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem;"
              title="Delete this fact">🗑️</button>
          </div>
        </div>`;
    });

    listDiv.innerHTML = `<div style="color: #888; font-size: 0.8rem; margin-bottom: 0.5rem;">${data.count} facts loaded</div>` + html;
  } catch (err) {
    listDiv.innerHTML = `<div style="color: #ff6b6b; padding: 1rem;">Error loading facts: ${err.message}</div>`;
  }
}

async function loadEpisodicMemories() {
  const listDiv = document.getElementById('episodic-list');
  listDiv.innerHTML = '<div style="text-align: center; color: #888; padding: 1rem;">Loading memories...</div>';

  try {
    const data = await apiCall('/memory/episodic');

    if (!data.success || data.count === 0) {
      listDiv.innerHTML = '<div style="text-align: center; color: #666; padding: 2rem;">No episodic memories stored yet.</div>';
      return;
    }

    let html = '';
    data.memories.forEach((mem, i) => {
      const source = mem.metadata?.source || 'unknown';
      const when = mem.metadata?.when ? new Date(mem.metadata.when * 1000).toLocaleString() : 'unknown';
      const persona = mem.metadata?.persona || 'miku';
      const personaBadge = persona === 'evil_miku'
        ? '<span style="background: #7a2a2a; color: #ff9999; font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 3px; margin-left: 0.3rem;">😈 Evil Miku</span>'
        : '<span style="background: #2a5a7a; color: #99ccff; font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 3px; margin-left: 0.3rem;">🎤 Miku</span>';
      const memDataJson = escapeJsonForAttribute(mem);
      html += `
        <div class="memory-item" style="background: #242424; padding: 0.6rem 0.8rem; margin-bottom: 0.4rem; border-radius: 4px; border-left: 3px solid #2a5599; display: flex; justify-content: space-between; align-items: flex-start;">
          <div style="flex: 1;">
            <div style="color: #ddd; font-size: 0.9rem;">${escapeHtml(mem.content)}${personaBadge}</div>
            <div style="color: #666; font-size: 0.75rem; margin-top: 0.3rem;">
              Source: ${escapeHtml(source)} · ${when}
            </div>
          </div>
          <div style="display: flex; gap: 0.3rem; flex-shrink: 0;">
            <button data-memory='${memDataJson}' onclick='showEditMemoryModalFromButton(this, "episodic", "${mem.id}")'
              style="background: none; border: none; color: #5599cc; cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem;"
              title="Edit this memory">✏️</button>
            <button onclick="deleteMemoryPoint('episodic', '${mem.id}', this)"
              style="background: none; border: none; color: #993333; cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem;"
              title="Delete this memory">🗑️</button>
          </div>
        </div>`;
    });

    listDiv.innerHTML = `<div style="color: #888; font-size: 0.8rem; margin-bottom: 0.5rem;">${data.count} memories loaded</div>` + html;
  } catch (err) {
    listDiv.innerHTML = `<div style="color: #ff6b6b; padding: 1rem;">Error loading memories: ${err.message}</div>`;
  }
}

async function deleteMemoryPoint(collection, pointId, btnElement) {
  if (!confirm(`Delete this ${collection} memory point?`)) return;

  try {
    const data = await apiCall(`/memory/point/${collection}/${pointId}`, 'DELETE');

    if (data.success) {
      // Remove the row from the UI
      const row = btnElement.closest('div[style*="margin-bottom"]');
      if (row) row.remove();
      showNotification('Memory point deleted', 'success');
      refreshMemoryStats();
    } else {
      showNotification('Failed to delete: ' + (data.error || 'Unknown error'), 'error');
    }
  } catch (err) {
    console.error('Failed to delete memory point:', err);
  }
}

// Delete All Memories — Multi-step confirmation flow
function onDeleteStep1Change() {
  const checked = document.getElementById('delete-checkbox-1').checked;
  document.getElementById('delete-step-2').style.display = checked ? 'block' : 'none';
  if (!checked) {
    document.getElementById('delete-checkbox-2').checked = false;
    document.getElementById('delete-step-3').style.display = 'none';
    document.getElementById('delete-step-final').style.display = 'none';
    document.getElementById('delete-confirmation-input').value = '';
  }
}

function onDeleteStep2Change() {
  const checked = document.getElementById('delete-checkbox-2').checked;
  document.getElementById('delete-step-3').style.display = checked ? 'block' : 'none';
  document.getElementById('delete-step-final').style.display = checked ? 'block' : 'none';
  if (!checked) {
    document.getElementById('delete-confirmation-input').value = '';
    updateDeleteButton();
  }
}

function onDeleteInputChange() {
  updateDeleteButton();
}

function updateDeleteButton() {
  const input = document.getElementById('delete-confirmation-input').value;
  const expected = "Yes, I am deleting Miku's memories fully.";
  const btn = document.getElementById('delete-all-btn');
  const match = input === expected;

  btn.disabled = !match;
  btn.style.cursor = match ? 'pointer' : 'not-allowed';
  btn.style.opacity = match ? '1' : '0.5';
}

async function executeDeleteAllMemories() {
  const input = document.getElementById('delete-confirmation-input').value;
  const expected = "Yes, I am deleting Miku's memories fully.";

  if (input !== expected) {
    showNotification('Confirmation string does not match', 'error');
    return;
  }

  const btn = document.getElementById('delete-all-btn');
  btn.disabled = true;
  btn.textContent = '⏳ Deleting...';

  try {
    const data = await apiCall('/memory/delete', 'POST', { confirmation: input });

    if (data.success) {
      showNotification('All memories have been permanently deleted', 'success');
      resetDeleteFlow();
      refreshMemoryStats();
    } else {
      showNotification('Deletion failed: ' + (data.error || 'Unknown error'), 'error');
    }
  } catch (err) {
    console.error('Failed to delete all memories:', err);
  } finally {
    btn.disabled = false;
    btn.textContent = '🗑️ Permanently Delete All Memories';
  }
}

function resetDeleteFlow() {
  document.getElementById('delete-checkbox-1').checked = false;
  document.getElementById('delete-checkbox-2').checked = false;
  document.getElementById('delete-confirmation-input').value = '';
  document.getElementById('delete-step-2').style.display = 'none';
  document.getElementById('delete-step-3').style.display = 'none';
  document.getElementById('delete-step-final').style.display = 'none';
  updateDeleteButton();
}

// Memory Edit/Create Modal Functions
// currentEditMemory declared in core.js

function showEditMemoryModalFromButton(button, collection, pointId) {
  const memoryJson = button.getAttribute('data-memory');
  // Unescape HTML entities back to JSON
  const unescapedJson = memoryJson
    .replace(/&quot;/g, '"')
    .replace(/&apos;/g, "'")
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&amp;/g, '&');
  const memory = JSON.parse(unescapedJson);
  showEditMemoryModal(collection, pointId, memory);
}

function showEditMemoryModal(collection, pointId, memoryData) {
  const memory = typeof memoryData === 'string' ? JSON.parse(memoryData) : memoryData;
  currentEditMemory = { collection, pointId, memory };

  const modal = document.getElementById('edit-memory-modal');
  const contentField = document.getElementById('edit-memory-content');
  const sourceField = document.getElementById('edit-memory-source');

  contentField.value = memory.content || '';
  sourceField.value = memory.metadata?.source || '';

  modal.style.display = 'flex';
}

function closeEditMemoryModal() {
  document.getElementById('edit-memory-modal').style.display = 'none';
  currentEditMemory = null;
}

async function saveMemoryEdit() {
  if (!currentEditMemory) return;

  const content = document.getElementById('edit-memory-content').value.trim();
  const source = document.getElementById('edit-memory-source').value.trim();

  if (!content) {
    showNotification('Content cannot be empty', 'error');
    return;
  }

  const { collection, pointId } = currentEditMemory;
  const saveBtn = document.querySelector('#edit-memory-modal button[onclick="saveMemoryEdit()"]');
  saveBtn.disabled = true;
  saveBtn.textContent = 'Saving...';

  try {
    const data = await apiCall(`/memory/point/${collection}/${pointId}`, 'PUT', {
      content: content,
      metadata: { source: source || 'manual_edit' }
    });

    if (data.success) {
      showNotification('Memory updated successfully', 'success');
      closeEditMemoryModal();
      // Reload the appropriate list
      if (collection === 'declarative') {
        loadFacts();
      } else if (collection === 'episodic') {
        loadEpisodicMemories();
      }
    } else {
      showNotification('Failed to update: ' + (data.error || 'Unknown error'), 'error');
    }
  } catch (err) {
    console.error('Failed to save memory edit:', err);
  } finally {
    saveBtn.disabled = false;
    saveBtn.textContent = 'Save Changes';
  }
}

function showCreateMemoryModal(collection) {
  const modal = document.getElementById('create-memory-modal');
  document.getElementById('create-memory-collection').value = collection;
  document.getElementById('create-memory-content').value = '';
  document.getElementById('create-memory-user-id').value = '';
  document.getElementById('create-memory-source').value = 'manual';

  // Update modal title based on collection type
  const title = collection === 'declarative' ? 'Add New Fact' : 'Add New Memory';
  document.querySelector('#create-memory-modal h3').textContent = title;

  modal.style.display = 'flex';
}

function closeCreateMemoryModal() {
  document.getElementById('create-memory-modal').style.display = 'none';
}

// Modal keyboard and backdrop close handlers
document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape') {
    const editModal = document.getElementById('edit-memory-modal');
    const createModal = document.getElementById('create-memory-modal');
    if (editModal && editModal.style.display !== 'none') closeEditMemoryModal();
    if (createModal && createModal.style.display !== 'none') closeCreateMemoryModal();
  }
});

async function saveNewMemory() {
  const collection = document.getElementById('create-memory-collection').value;
  const content = document.getElementById('create-memory-content').value.trim();
  const userId = document.getElementById('create-memory-user-id').value.trim();
  const source = document.getElementById('create-memory-source').value.trim();

  if (!content) {
    showNotification('Content cannot be empty', 'error');
    return;
  }

  const createBtn = document.querySelector('#create-memory-modal button[onclick="saveNewMemory()"]');
  createBtn.disabled = true;
  createBtn.textContent = 'Creating...';

  try {
    const data = await apiCall('/memory/create', 'POST', {
      collection: collection,
      content: content,
      user_id: userId || null,
      source: source || 'manual',
      metadata: {}
    });

    if (data.success) {
      showNotification(`${collection === 'declarative' ? 'Fact' : 'Memory'} created successfully`, 'success');
      closeCreateMemoryModal();
      // Reload the appropriate list
      if (collection === 'declarative') {
        loadFacts();
      } else if (collection === 'episodic') {
        loadEpisodicMemories();
      }
      refreshMemoryStats();
    } else {
      showNotification('Failed to create: ' + (data.error || 'Unknown error'), 'error');
    }
  } catch (err) {
    console.error('Failed to save new memory:', err);
  } finally {
    createBtn.disabled = false;
    createBtn.textContent = 'Create Memory';
  }
}

// Search/Filter Function
function filterMemories(listId, searchTerm) {
  const listDiv = document.getElementById(listId);
  const items = listDiv.querySelectorAll('.memory-item');
  const term = searchTerm.toLowerCase().trim();

  items.forEach(item => {
    const content = item.textContent.toLowerCase();
    if (term === '' || content.includes(term)) {
      item.style.display = 'flex';
    } else {
      item.style.display = 'none';
    }
  });
}
