// ========== CONTAINER LOG VIEWER ==========
(function() {
  // Inject modal HTML
  injectModal('container-logs-modal', `<div id="container-logs-modal" class="weather-modal" style="z-index: 1001;">
    <div class="weather-modal-content" style="min-width: 900px; max-width: 95vw; height: 80vh; display: flex; flex-direction: column;">
      <div class="logs-header" style="display: flex; justify-content: space-between; align-items: center; padding-bottom: 12px; border-bottom: 1px solid var(--border); margin-bottom: 12px;">
        <div>
          <h3 style="margin: 0;">📜 Container Logs</h3>
          <p class="modal-subtitle" style="margin: 4px 0 0 0; font-size: 0.85rem; opacity: 0.7;">View and stream Docker container logs</p>
        </div>
        <div class="logs-controls" style="display: flex; gap: 8px; align-items: center;">
          <select id="cl-container-select" style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); min-width: 200px;">
            <option value="">Select a container...</option>
          </select>
          <input type="text" id="cl-log-search" placeholder="Search logs..." style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg); width: 150px;" />
          <select id="cl-log-tail" style="padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); color: var(--fg);">
            <option value="50">Last 50 lines</option>
            <option value="100" selected>Last 100 lines</option>
            <option value="500">Last 500 lines</option>
            <option value="1000">Last 1000 lines</option>
            <option value="all">All logs</option>
          </select>
          <button id="cl-refresh" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.85rem;">🔄 Refresh</button>
          <button id="cl-stream" class="btn-accent-solid" style="padding: 6px 14px; font-size: 0.85rem;">▶ Stream</button>
          <button id="cl-download" style="padding: 6px 14px; font-size: 0.85rem;">💾 Download</button>
          <button id="cl-clear-search" style="padding: 6px 10px; font-size: 0.85rem;" title="Clear search">✕</button>
          <button id="cl-close" class="close-btn" style="padding: 6px 10px;">✕</button>
        </div>
      </div>
      
      <div id="cl-container-info" style="display: flex; gap: 16px; margin-bottom: 12px; padding: 8px 12px; background: var(--bg-secondary, var(--bg)); border-radius: 6px; font-size: 0.82rem;">
        <span><strong>Image:</strong> <span id="cl-image">-</span></span>
        <span><strong>Status:</strong> <span id="cl-status">-</span></span>
        <span><strong>Created:</strong> <span id="cl-created">-</span></span>
      </div>
      
      <div id="cl-log-content" class="logs-content scroll-container" style="flex: 1; min-height: 0; background: #1a1a1a; border-radius: 6px; padding: 12px; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.78rem; overflow: auto;">
        <div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>
      </div>
      
      <div id="cl-stream-status" style="display: none; padding: 8px 12px; background: var(--ok-bg, #1a3a1a); color: var(--ok-fg, #4ade80); border-radius: 6px; margin-top: 8px; font-size: 0.82rem;">
        <span id="cl-stream-indicator">🔴</span> <span id="cl-stream-text">Disconnected</span>
      </div>
      
      <div class="weather-modal-buttons modal-footer-bar" style="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
        <div style="display: flex; gap: 8px; font-size: 0.78rem; color: var(--muted);">
          <span id="cl-line-count">0 lines</span>
          <span>|</span>
          <span id="cl-filter-count">0 filtered</span>
        </div>
        <button id="cl-close-btn" class="btn-secondary">Close</button>
      </div>
    </div>
  </div>`);

  const modal = document.getElementById('container-logs-modal');
  const containerSelect = document.getElementById('cl-container-select');
  const logContent = document.getElementById('cl-log-content');
  const logSearch = document.getElementById('cl-log-search');
  const logTail = document.getElementById('cl-log-tail');
  const refreshBtn = document.getElementById('cl-refresh');
  const streamBtn = document.getElementById('cl-stream');
  const downloadBtn = document.getElementById('cl-download');
  const clearSearchBtn = document.getElementById('cl-clear-search');
  const closeBtn = document.getElementById('cl-close');
  const closeBtn2 = document.getElementById('cl-close-btn');
  const streamStatus = document.getElementById('cl-stream-status');
  const streamIndicator = document.getElementById('cl-stream-indicator');
  const streamText = document.getElementById('cl-stream-text');
  const lineCount = document.getElementById('cl-line-count');
  const filterCount = document.getElementById('cl-filter-count');
  
  // Container info elements
  const imageEl = document.getElementById('cl-image');
  const statusEl = document.getElementById('cl-status');
  const createdEl = document.getElementById('cl-created');

  let currentContainerId = null;
  let currentLogs = [];
  let filteredLogs = [];
  let eventSource = null;
  let isStreaming = false;
  let searchTimeout = null;

  // Format date
  function formatDate(dateStr) {
    if (!dateStr) return '-';
    const d = new Date(dateStr);
    if (isNaN(d.getTime())) return dateStr;
    return d.toLocaleString();
  }

  // Escape HTML
  function escapeHtml(str) {
    if (!str) return '';
    const div = document.createElement('div');
    div.textContent = str;
    return div.innerHTML;
  }

  // Format log entry for display
  function formatLogEntry(log, index) {
    const streamClass = log.stream === 'stderr' ? 'log-stderr' : 'log-stdout';
    const streamIcon = log.stream === 'stderr' ? '⚠️' : '📤';
    return `
      <div class="log-entry ${streamClass}" data-index="${index}" style="padding: 4px 8px; border-bottom: 1px solid #333; display: flex; gap: 8px;">
        <span class="log-line-num" style="color: #666; min-width: 40px; text-align: right; user-select: none;">${index + 1}</span>
        <span class="log-stream-icon" style="color: ${log.stream === 'stderr' ? '#f59e0b' : '#22c55e'};">${streamIcon}</span>
        <span class="log-text" style="flex: 1; white-space: pre-wrap; word-break: break-all; color: #e5e5e5;">${escapeHtml(log.text)}</span>
      </div>
    `;
  }

  // Render logs to the content area
  function renderLogs(logs, searchTerm = '') {
    if (!logs || logs.length === 0) {
      logContent.innerHTML = '<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs available</div>';
      lineCount.textContent = '0 lines';
      filterCount.textContent = '0 filtered';
      return;
    }

    currentLogs = logs;
    filteredLogs = searchTerm ? logs.filter(log => 
      log.text && log.text.toLowerCase().includes(searchTerm.toLowerCase())
    ) : logs;

    lineCount.textContent = `${logs.length} lines`;
    filterCount.textContent = searchTerm ? `${filteredLogs.length} of ${logs.length} shown` : `${logs.length} shown`;

    if (filteredLogs.length === 0) {
      logContent.innerHTML = `<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs match "${escapeHtml(searchTerm)}"</div>`;
      return;
    }

    logContent.innerHTML = filteredLogs.map((log, i) => formatLogEntry(log, i)).join('');
    
    // Scroll to bottom
    logContent.scrollTop = logContent.scrollHeight;
  }

  // Load container list
  async function loadContainers() {
    try {
      const data = await getJSON('/api/v1/logs/containers');
      const containers = data.containers || [];
      
      // Store current selection
      const currentVal = containerSelect.value;
      
      containerSelect.innerHTML = '<option value="">Select a container...</option>';
      
      containers.forEach(c => {
        const option = document.createElement('option');
        option.value = c.id;
        option.textContent = `${c.name} (${c.image.split(':')[0]}) - ${c.status}`;
        option.dataset.name = c.name;
        option.dataset.image = c.image;
        option.dataset.status = c.status;
        option.dataset.created = c.created;
        containerSelect.appendChild(option);
      });
      
      // Restore selection if still valid
      if (currentVal && containerSelect.querySelector(`option[value="${currentVal}"]`)) {
        containerSelect.value = currentVal;
        loadContainerInfo(currentVal);
      }
    } catch (err) {
      console.error('Failed to load containers:', err);
    }
  }

  // Load container info
  function loadContainerInfo(containerId) {
    const option = containerSelect.querySelector(`option[value="${containerId}"]`);
    if (option) {
      imageEl.textContent = option.dataset.image || '-';
      statusEl.textContent = option.dataset.status || '-';
      statusEl.style.color = option.dataset.status === 'running' ? 'var(--ok-fg, #4ade80)' : 'var(--bad-fg, #ef4444)';
      createdEl.textContent = formatDate(option.dataset.created);
    }
  }

  // Load logs for selected container
  async function loadLogs() {
    const containerId = containerSelect.value;
    if (!containerId) {
      logContent.innerHTML = '<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>';
      return;
    }

    // Stop any existing stream
    stopStream();

    currentContainerId = containerId;
    loadContainerInfo(containerId);

    const tail = logTail.value;
    const searchTerm = logSearch.value.trim();

    logContent.innerHTML = '<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Loading logs...</div>';

    try {
      const url = `/api/v1/logs/container/${containerId}${tail !== 'all' ? `?tail=${tail}` : ''}`;
      const data = await getJSON(url);

      if (data.logs && data.logs.length > 0) {
        renderLogs(data.logs, searchTerm);
      } else {
        logContent.innerHTML = '<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">No logs found for this container</div>';
        lineCount.textContent = '0 lines';
        filterCount.textContent = '0 filtered';
      }
    } catch (err) {
      logContent.innerHTML = `<div class="logs-loading" style="color: var(--bad-fg, #ef4444); text-align: center; padding: 40px;">Error loading logs: ${escapeHtml(err.message)}</div>`;
    }
  }

  // Start streaming logs
  function startStream() {
    const containerId = containerSelect.value;
    if (!containerId) return;

    // Stop any existing stream
    stopStream();

    isStreaming = true;
    streamBtn.textContent = '⏹ Stop';
    streamStatus.style.display = 'flex';
    streamIndicator.textContent = '🟢';
    streamText.textContent = 'Connecting...';

    const url = `/api/v1/logs/stream/${containerId}`;
    eventSource = new EventSource(url);

    eventSource.onopen = () => {
      streamIndicator.textContent = '🟢';
      streamText.textContent = 'Connected - streaming logs';
    };

    eventSource.onmessage = (event) => {
      try {
        const log = JSON.parse(event.data);
        
        if (log.error) {
          streamIndicator.textContent = '🔴';
          streamText.textContent = `Error: ${log.error}`;
          return;
        }

        // Add to current logs
        currentLogs.push(log);
        filteredLogs.push(log);
        
        // Update counts
        lineCount.textContent = `${currentLogs.length} lines`;
        filterCount.textContent = `${filteredLogs.length} shown`;
        
        // Append new log entry
        const searchTerm = logSearch.value.trim();
        if (!searchTerm || (log.text && log.text.toLowerCase().includes(searchTerm.toLowerCase()))) {
          const entry = document.createElement('div');
          entry.innerHTML = formatLogEntry(log, filteredLogs.length - 1);
          const entryDiv = entry.firstElementChild;
          entryDiv.style.background = '#1a3a1a';
          logContent.appendChild(entryDiv);
          
          // Auto-scroll to bottom
          logContent.scrollTop = logContent.scrollHeight;
        }
      } catch (e) {
        console.error('Error parsing log:', e);
      }
    };

    eventSource.onerror = () => {
      streamIndicator.textContent = '🔴';
      streamText.textContent = 'Disconnected';
      isStreaming = false;
      streamBtn.textContent = '▶ Stream';
    };

    // Store the EventSource for cleanup
    modal._eventSource = eventSource;
  }

  // Stop streaming logs
  function stopStream() {
    if (eventSource) {
      eventSource.close();
      eventSource = null;
    }
    if (modal._eventSource) {
      modal._eventSource.close();
      modal._eventSource = null;
    }
    isStreaming = false;
    streamBtn.textContent = '▶ Stream';
    streamStatus.style.display = 'none';
  }

  // Download logs as file
  function downloadLogs() {
    if (!currentLogs || currentLogs.length === 0) {
      showNotification('No logs to download', 'error');
      return;
    }

    const containerName = containerSelect.querySelector(`option[value="${currentContainerId}"]`)?.dataset.name || currentContainerId;
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const filename = `${containerName}-logs-${timestamp}.txt`;

    const content = currentLogs.map(log => {
      const timestamp = log.timestamp || '';
      const stream = log.stream === 'stderr' ? '[ERR]' : '[OUT]';
      return `${timestamp ? timestamp + ' ' : ''}${stream} ${log.text}`;
    }).join('\n');

    const blob = new Blob([content], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);

    showNotification(`Downloaded ${currentLogs.length} log lines`, 'success');
  }

  // Event listeners
  containerSelect?.addEventListener('change', () => {
    loadLogs();
  });

  logTail?.addEventListener('change', () => {
    loadLogs();
  });

  refreshBtn?.addEventListener('click', () => {
    loadLogs();
  });

  streamBtn?.addEventListener('click', () => {
    if (isStreaming) {
      stopStream();
    } else {
      startStream();
    }
  });

  downloadBtn?.addEventListener('click', () => {
    downloadLogs();
  });

  clearSearchBtn?.addEventListener('click', () => {
    logSearch.value = '';
    renderLogs(currentLogs, '');
  });

  logSearch?.addEventListener('input', () => {
    // Debounce search
    clearTimeout(searchTimeout);
    searchTimeout = setTimeout(() => {
      renderLogs(currentLogs, logSearch.value.trim());
    }, 300);
  });

  logSearch?.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
      logSearch.value = '';
      renderLogs(currentLogs, '');
    }
  });

  // Open modal
  const openBtn = document.getElementById('view-container-logs');
  openBtn?.addEventListener('click', () => {
    modal.classList.add('show');
    loadContainers();
  });

  // Close modal handlers
  function closeModal() {
    stopStream();
    modal.classList.remove('show');
  }

  closeBtn?.addEventListener('click', closeModal);
  closeBtn2?.addEventListener('click', closeModal);

  // Close on escape key
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && modal.classList.contains('show')) {
      closeModal();
    }
  });

  // Wire backdrop click to closeModal so the log stream stops too.
  // (Can't use wireModal here — it only does modal.classList.remove('show')
  // on backdrop click, which would leak the SSE/stream connection.)
  modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });

  // Expose for use by service card buttons (grid.js calls openContainerLogsModal)
  window.openContainerLogsModal = function(containerId, containerName) {
    modal.classList.add('show');
    loadContainers().then(() => {
      // Try to find and select the container
      const option = Array.from(containerSelect.options).find(opt => 
        opt.value === containerId || opt.dataset.name === containerName
      );
      if (option) {
        containerSelect.value = option.value;
        loadContainerInfo(option.value);
        loadLogs();
      } else if (containerId) {
        // If container not found in list but we have an ID, try loading directly
        currentContainerId = containerId;
        imageEl.textContent = containerName || containerId;
        statusEl.textContent = '-';
        createdEl.textContent = '-';
        loadLogs();
      } else {
        // No container ID, just show modal with container list
        logContent.innerHTML = '<div class="logs-loading" style="color: var(--muted); text-align: center; padding: 40px;">Select a container to view logs</div>';
      }
    });
  };
})();
