// ========== LOG VIEWERS ==========
(function () {

  // Inject logs-modal HTML
  injectModal('logs-modal', `
  <div id="logs-modal" class="logs-modal">
    <div class="logs-modal-content" style="min-width: 800px; max-width: 1000px;">
      <div class="logs-header">
        <h3 id="logs-title">DNS Logs</h3>
        <div class="logs-controls">
          <label for="log-lines">Show:</label>
          <select id="log-lines">
            <option value="25" selected>25</option>
            <option value="50">50</option>
            <option value="100">100</option>
            <option value="200">200</option>
          </select>
          <button id="logs-stream" class="stream-btn" title="Enable real-time streaming">📡 Live</button>
          <button id="logs-pause" class="pause-btn">⏸️ Pause</button>
          <button id="logs-close" class="close-btn">✕</button>
        </div>
      </div>
      <div class="logs-container scroll-container">
        <div id="logs-content" class="logs-content">
          <div class="logs-loading">Loading logs...</div>
        </div>
      </div>
    </div>
  </div>`);

  // ===== State =====
  let currentDnsService = null;
  let logsInterval = null;
  let logsPaused = false;

  let currentContainerId = null;
  let currentContainerName = null;
  let containerLogsMode = false;

  let currentLogPath = null;
  let currentLogServiceName = null;
  let fileLogsMode = false;

  let logEventSource = null;
  let isStreaming = false;

  // ===== DNS LOGS =====

  async function fetchDnsLogs(dnsId, lines = 25) {
    try {
      const serverIP = getDnsServerAddr(dnsId);
      const response = await fetch(`/api/v1/dns/logs?server=${serverIP}&limit=${lines}`, {
        cache: 'no-store',
        headers: { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }
      });

      if (response.ok) {
        const result = await response.json();
        if (result.success && result.logs) {
          return { logs: result.logs, count: result.count, server: result.server };
        } else {
          return { error: result.error || 'Failed to fetch logs' };
        }
      } else if (response.status === 401) {
        return { error: 'DNS auto-auth failed - check credentials in settings' };
      } else {
        return { error: `HTTP ${response.status}` };
      }
    } catch (error) {
      console.error('DNS logs fetch failed:', error);
      return { error: error.message };
    }
  }

  function getRcodeColor(rcode) {
    const colors = {
      'NoError': 'var(--ok-fg)',
      'NOERROR': 'var(--ok-fg)',
      'NxDomain': 'var(--muted)',
      'NXDOMAIN': 'var(--muted)',
      'Refused': 'var(--bad-fg)',
      'REFUSED': 'var(--bad-fg)',
      'ServerFailure': '#f39c12',
      'SERVFAIL': '#f39c12'
    };
    return colors[rcode] || 'var(--fg)';
  }

  function renderDnsLogEntry(log) {
    const div = document.createElement('div');
    div.className = 'log-entry';
    div.style.cssText = 'display: grid; grid-template-columns: 140px 110px 1fr 70px 80px; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 0.8rem; align-items: center;';

    // If unparsed raw log
    if (log.parsed === false) {
      div.style.gridTemplateColumns = '1fr';
      div.innerHTML = `<span style="color: var(--muted); font-family: monospace; font-size: 0.75rem;">${escapeHtml(log.raw)}</span>`;
      return div;
    }

    const rcodeColor = getRcodeColor(log.rcode);
    const isBlocked = log.rcode === 'Refused' || log.rcode === 'REFUSED';

    div.innerHTML = `
      <span style="color: var(--muted); font-size: 0.75rem;">${escapeHtml(log.timestamp)}</span>
      <span style="color: var(--accent); font-size: 0.75rem;" title="${escapeHtml(log.client)}">${escapeHtml(log.client)}</span>
      <span style="font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; ${isBlocked ? 'text-decoration: line-through; opacity: 0.6;' : ''}" title="${escapeHtml(log.domain)}">${escapeHtml(log.domain)}</span>
      <span style="color: var(--muted); font-size: 0.75rem;">${escapeHtml(log.type)}</span>
      <span style="color: ${rcodeColor}; font-weight: 500; font-size: 0.75rem;">${escapeHtml(log.rcode)}</span>
    `;

    return div;
  }

  async function updateLogsDisplay() {
    // Handle file logs mode
    if (fileLogsMode) {
      await updateFileLogsDisplay();
      return;
    }

    // Handle container logs mode
    if (containerLogsMode) {
      await updateContainerLogsDisplay();
      return;
    }

    // Handle DNS logs mode
    if (logsPaused || !currentDnsService) return;

    const lines = parseInt(document.getElementById('log-lines').value);
    const logsContent = document.getElementById('logs-content');

    try {
      const result = await fetchDnsLogs(currentDnsService, lines);

      if (result.error) {
        logsContent.innerHTML = `
          <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
            <div style="font-size: 1.2rem; margin-bottom: 8px;">⚠️ Error</div>
            <div>${escapeHtml(result.error)}</div>
          </div>`;
        return;
      }

      // Add header row
      logsContent.innerHTML = `
        <div style="display: grid; grid-template-columns: 140px 110px 1fr 70px 80px; gap: 8px; padding: 8px 10px; background: var(--card-base); border-bottom: 2px solid var(--border); font-size: 0.75rem; font-weight: 600; color: var(--muted); position: sticky; top: 0;">
          <span>Time</span>
          <span>Client</span>
          <span>Domain</span>
          <span>Type</span>
          <span>Status</span>
        </div>`;

      if (result.logs && result.logs.length > 0) {
        result.logs.forEach(log => {
          const logElement = renderDnsLogEntry(log);
          logsContent.appendChild(logElement);
        });
      } else {
        logsContent.innerHTML += `
          <div style="padding: 20px; text-align: center; color: var(--muted);">
            No DNS queries logged yet
          </div>`;
      }
    } catch (error) {
      logsContent.innerHTML = `
        <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
          Failed to fetch logs: ${escapeHtml(error.message)}
        </div>`;
    }
  }

  function openLogsModal(dnsId) {
    currentDnsService = dnsId;
    logsPaused = false;
    containerLogsMode = false;

    const modal = document.getElementById('logs-modal');
    const title = document.getElementById('logs-title');
    const pauseBtn = document.getElementById('logs-pause');
    const streamBtn = document.getElementById('logs-stream');

    title.textContent = `${dnsId.toUpperCase()} DNS Logs`;
    pauseBtn.textContent = '⏸️ Pause';
    pauseBtn.classList.remove('paused');

    // Hide stream button for DNS logs (only available for container logs)
    if (streamBtn) {
      streamBtn.style.display = 'none';
    }

    modal.classList.add('show');

    // Initial load
    updateLogsDisplay();

    // Start auto-refresh every 3 seconds
    logsInterval = setInterval(updateLogsDisplay, DC.POLL.LOGS);
  }

  function closeLogsModal() {
    const modal = document.getElementById('logs-modal');
    modal.classList.remove('show');

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

    // Stop SSE streaming if active
    stopLogStreaming();

    // Reset all log modes
    currentDnsService = null;
    containerLogsMode = false;
    currentContainerId = null;
    currentContainerName = null;
    fileLogsMode = false;
    currentLogPath = null;
    currentLogServiceName = null;
    logsPaused = false;
  }

  // ===== SSE LOG STREAMING =====

  function startLogStreaming(containerId) {
    if (logEventSource) {
      stopLogStreaming();
    }

    const streamBtn = document.getElementById('logs-stream');
    const pauseBtn = document.getElementById('logs-pause');
    const logsContent = document.getElementById('logs-content');

    // Stop interval-based refresh
    if (logsInterval) {
      clearInterval(logsInterval);
      logsInterval = null;
    }

    try {
      logEventSource = new EventSource(`/api/v1/logs/stream/${containerId}`);
      isStreaming = true;

      streamBtn.classList.add('active');
      streamBtn.textContent = '🔴 Live';
      streamBtn.title = 'Streaming - click to stop';
      pauseBtn.style.display = 'none';

      // Add streaming indicator to header
      const title = document.getElementById('logs-title');
      if (!title.textContent.includes('🔴')) {
        title.innerHTML = title.textContent.replace('📋', '📋 🔴');
      }

      logEventSource.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data);

          if (data.error) {
            console.error('Stream error:', data.error);
            stopLogStreaming();
            return;
          }

          // Append new log entry
          const entry = document.createElement('div');
          entry.className = 'log-entry';
          entry.style.cssText = 'display: flex; gap: 12px; padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 0.8rem; align-items: flex-start; font-family: monospace;';

          const streamType = data.stream || 'stdout';
          const isError = streamType === 'stderr';
          const levelColor = isError ? 'var(--bad-fg)' : 'var(--fg)';
          const bgColor = isError ? 'var(--bad-bg)' : 'var(--ok-bg)';
          const levelBadge = `<span style="background: ${bgColor}; color: ${levelColor}; padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; min-width: 50px; text-align: center;">${isError ? 'STDERR' : 'STDOUT'}</span>`;

          entry.innerHTML = `
            <div style="flex-shrink: 0;">${levelBadge}</div>
            <div style="flex: 1; color: ${levelColor}; word-break: break-all; white-space: pre-wrap;">${escapeHtml(data.text)}</div>
          `;

          logsContent.appendChild(entry);

          // Auto-scroll to bottom
          logsContent.scrollTop = logsContent.scrollHeight;

          // Limit entries to prevent memory issues (keep last 500)
          while (logsContent.children.length > 500) {
            logsContent.removeChild(logsContent.firstChild);
          }
        } catch (err) {
          console.error('Error parsing stream data:', err);
        }
      };

      logEventSource.onerror = (err) => {
        console.error('EventSource error:', err);
        stopLogStreaming();
      };

    } catch (err) {
      console.error('Failed to start streaming:', err);
      stopLogStreaming();
    }
  }

  function stopLogStreaming() {
    if (logEventSource) {
      logEventSource.close();
      logEventSource = null;
    }
    isStreaming = false;

    const streamBtn = document.getElementById('logs-stream');
    const pauseBtn = document.getElementById('logs-pause');
    const title = document.getElementById('logs-title');

    if (streamBtn) {
      streamBtn.classList.remove('active');
      streamBtn.textContent = '📡 Live';
      streamBtn.title = 'Enable real-time streaming';
    }

    if (pauseBtn) {
      pauseBtn.style.display = '';
    }

    if (title) {
      title.textContent = title.textContent.replace(' 🔴', '');
    }

    // Restart interval-based refresh if container logs modal is open
    if (containerLogsMode && currentContainerId && !logsInterval) {
      logsInterval = setInterval(updateContainerLogsDisplay, DC.POLL.LOGS);
    }
  }

  // ===== CONTAINER LOGS =====

  async function fetchContainerLogs(containerId, lines = 100) {
    try {
      const endpoint = `/api/v1/logs/container/${containerId}?tail=${lines}&timestamps=true`;

      const response = await fetch(endpoint, {
        cache: 'no-store',
        headers: { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }
      });

      if (response.ok) {
        const result = await response.json();
        if (result.success && result.logs) {
          return {
            logs: result.logs,
            count: result.count,
            containerName: result.containerName,
            containerId: result.containerId
          };
        } else {
          return { error: result.error || 'Failed to fetch container logs' };
        }
      } else {
        return { error: `HTTP ${response.status}: ${response.statusText}` };
      }
    } catch (error) {
      console.error('Container logs fetch failed:', error);
      return { error: error.message };
    }
  }

  function renderContainerLogEntry(log) {
    const div = document.createElement('div');
    div.className = 'log-entry';
    div.style.cssText = 'display: flex; gap: 12px; padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 0.8rem; align-items: flex-start; font-family: monospace;';

    const streamColor = log.stream === 'stderr' ? 'var(--bad-fg)' : 'var(--fg)';
    const streamBadge = log.stream === 'stderr' ?
      '<span style="background: var(--bad-bg); color: var(--bad-fg); padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; font-weight: 600;">STDERR</span>' :
      '<span style="background: var(--ok-bg); color: var(--ok-fg); padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; font-weight: 600;">STDOUT</span>';

    div.innerHTML = `
      <div style="flex-shrink: 0;">${streamBadge}</div>
      <div style="flex: 1; color: ${streamColor}; word-break: break-all; white-space: pre-wrap;">${escapeHtml(log.text)}</div>
    `;

    return div;
  }

  async function updateContainerLogsDisplay() {
    if (logsPaused || !currentContainerId || !containerLogsMode) return;

    const lines = parseInt(document.getElementById('log-lines').value);
    const logsContent = document.getElementById('logs-content');

    try {
      const result = await fetchContainerLogs(currentContainerId, lines);

      if (result.error) {
        logsContent.innerHTML = `
          <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
            <div style="font-size: 1.2rem; margin-bottom: 8px;">⚠️ Error</div>
            <div>${escapeHtml(result.error)}</div>
          </div>`;
        return;
      }

      // Add header row
      logsContent.innerHTML = `
        <div style="display: flex; gap: 12px; padding: 8px 10px; background: var(--card-base); border-bottom: 2px solid var(--border); font-size: 0.75rem; font-weight: 600; color: var(--muted); position: sticky; top: 0;">
          <span style="flex-shrink: 0; width: 80px;">Stream</span>
          <span style="flex: 1;">Log Output</span>
        </div>`;

      if (result.logs && result.logs.length > 0) {
        result.logs.forEach(log => {
          const logElement = renderContainerLogEntry(log);
          logsContent.appendChild(logElement);
        });

        // Auto-scroll to bottom
        logsContent.scrollTop = logsContent.scrollHeight;
      } else {
        logsContent.innerHTML += `
          <div style="padding: 20px; text-align: center; color: var(--muted);">
            No logs available for this container
          </div>`;
      }
    } catch (error) {
      logsContent.innerHTML = `
        <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
          Failed to fetch logs: ${escapeHtml(error.message)}
        </div>`;
    }
  }

  function openContainerLogsModal(containerId, containerName) {
    currentContainerId = containerId;
    currentContainerName = containerName;
    containerLogsMode = true;
    fileLogsMode = false;
    logsPaused = false;

    // Stop any existing streaming
    stopLogStreaming();

    const modal = document.getElementById('logs-modal');
    const title = document.getElementById('logs-title');
    const pauseBtn = document.getElementById('logs-pause');
    const streamBtn = document.getElementById('logs-stream');

    title.textContent = `📋 ${containerName} - Container Logs`;
    pauseBtn.textContent = '⏸️ Pause';
    pauseBtn.classList.remove('paused');

    // Show stream button for container logs
    if (streamBtn) {
      streamBtn.style.display = '';
    }

    modal.classList.add('show');

    // Initial load
    updateContainerLogsDisplay();

    // Start auto-refresh every 3 seconds
    logsInterval = setInterval(updateContainerLogsDisplay, DC.POLL.LOGS);
  }

  // ===== FILE-BASED LOGS (for native apps) =====

  async function fetchFileLogs(logPath, lines = 100) {
    try {
      const endpoint = `/api/v1/logs/file?path=${encodeURIComponent(logPath)}&tail=${lines}`;

      const response = await fetch(endpoint, {
        cache: 'no-store',
        headers: { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }
      });

      if (response.ok) {
        const result = await response.json();
        if (result.success && result.logs) {
          return {
            logs: result.logs,
            count: result.count,
            logPath: result.logPath,
            totalLines: result.totalLines
          };
        } else {
          return { error: result.error || 'Failed to fetch file logs' };
        }
      } else {
        const result = await response.json().catch(() => ({}));
        return { error: result.error || `HTTP ${response.status}` };
      }
    } catch (error) {
      console.error('File logs fetch failed:', error);
      return { error: error.message };
    }
  }

  function renderFileLogEntry(log) {
    const div = document.createElement('div');
    div.className = 'log-entry';
    div.style.cssText = 'display: flex; gap: 12px; padding: 6px 10px; border-bottom: 1px solid var(--border); font-size: 0.8rem; align-items: flex-start; font-family: monospace;';

    const text = log.text;
    let logLevel = 'INFO';
    let levelColor = 'var(--fg)';

    if (text.match(/ERROR|FATAL|CRITICAL/i)) {
      logLevel = 'ERROR';
      levelColor = 'var(--bad-fg)';
    } else if (text.match(/WARN|WARNING/i)) {
      logLevel = 'WARN';
      levelColor = '#f39c12';
    } else if (text.match(/DEBUG/i)) {
      logLevel = 'DEBUG';
      levelColor = 'var(--muted)';
    }

    const bgColor = levelColor === 'var(--bad-fg)' ? 'var(--bad-bg)' : 'var(--ok-bg)';
    const levelBadge = `<span style="background: ${bgColor}; color: ${levelColor}; padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; min-width: 50px; text-align: center;">${logLevel}</span>`;

    div.innerHTML = `
      <div style="flex-shrink: 0;">${levelBadge}</div>
      <div style="flex: 1; color: ${levelColor}; word-break: break-all; white-space: pre-wrap;">${escapeHtml(text)}</div>
    `;

    return div;
  }

  async function updateFileLogsDisplay() {
    if (logsPaused || !currentLogPath || !fileLogsMode) return;

    const lines = parseInt(document.getElementById('log-lines').value);
    const logsContent = document.getElementById('logs-content');

    try {
      const result = await fetchFileLogs(currentLogPath, lines);

      if (result.error) {
        logsContent.innerHTML = `
          <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
            <div style="font-size: 1.2rem; margin-bottom: 8px;">⚠️ Error</div>
            <div>${escapeHtml(result.error)}</div>
          </div>`;
        return;
      }

      logsContent.innerHTML = `
        <div style="display: flex; gap: 12px; padding: 8px 10px; background: var(--card-base); border-bottom: 2px solid var(--border); font-size: 0.75rem; font-weight: 600; color: var(--muted); position: sticky; top: 0;">
          <span style="flex: 1;">Log Output (${result.count} of ${result.totalLines} lines)</span>
        </div>`;

      if (result.logs && result.logs.length > 0) {
        result.logs.forEach(log => {
          const logElement = renderFileLogEntry(log);
          logsContent.appendChild(logElement);
        });
        logsContent.scrollTop = logsContent.scrollHeight;
      } else {
        logsContent.innerHTML += `
          <div style="padding: 20px; text-align: center; color: var(--muted);">
            No logs available in this file
          </div>`;
      }
    } catch (error) {
      logsContent.innerHTML = `
        <div style="padding: 20px; text-align: center; color: var(--bad-fg);">
          Failed to fetch logs: ${escapeHtml(error.message)}
        </div>`;
    }
  }

  function openFileLogsModal(logPath, serviceName) {
    currentLogPath = logPath;
    currentLogServiceName = serviceName;
    fileLogsMode = true;
    containerLogsMode = false;
    logsPaused = false;

    const modal = document.getElementById('logs-modal');
    const title = document.getElementById('logs-title');
    const pauseBtn = document.getElementById('logs-pause');
    const streamBtn = document.getElementById('logs-stream');

    title.textContent = `📋 ${serviceName} - Application Logs`;
    pauseBtn.textContent = '⏸️ Pause';
    pauseBtn.classList.remove('paused');

    // Hide stream button for file logs (only available for container logs)
    if (streamBtn) {
      streamBtn.style.display = 'none';
    }

    modal.classList.add('show');

    updateFileLogsDisplay();
    logsInterval = setInterval(updateFileLogsDisplay, DC.POLL.LOGS);
  }

  // ===== EVENT LISTENERS =====

  // DNS log buttons — event delegation for dynamic cards
  document.querySelector('.top')?.addEventListener('click', (e) => {
    const logsBtn = e.target.closest('[id$="-logs"]');
    if (!logsBtn) return;
    const dnsId = logsBtn.id.replace('-logs', '');
    if (!SITE.dnsServers[dnsId]) return;
    openLogsModal(dnsId);
  });

  document.getElementById('logs-close')?.addEventListener('click', closeLogsModal);

  document.getElementById('logs-pause')?.addEventListener('click', () => {
    logsPaused = !logsPaused;
    const pauseBtn = document.getElementById('logs-pause');

    if (logsPaused) {
      pauseBtn.textContent = '▶️ Resume';
      pauseBtn.classList.add('paused');
    } else {
      pauseBtn.textContent = '⏸️ Pause';
      pauseBtn.classList.remove('paused');
      updateLogsDisplay();
    }
  });

  document.getElementById('log-lines')?.addEventListener('change', () => {
    if (!logsPaused) {
      updateLogsDisplay();
    }
  });

  // Stream button for real-time SSE logs (only works with container logs)
  document.getElementById('logs-stream')?.addEventListener('click', () => {
    if (!containerLogsMode || !currentContainerId) {
      // Streaming only available for container logs
      return;
    }

    if (isStreaming) {
      stopLogStreaming();
    } else {
      startLogStreaming(currentContainerId);
    }
  });

  // Close modal on outside click
  document.getElementById('logs-modal')?.addEventListener('click', (e) => {
    if (e.target.id === 'logs-modal') {
      closeLogsModal();
    }
  });

  // Close logs-modal on Escape key
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
      if (document.getElementById('logs-modal')?.classList.contains('show')) {
        closeLogsModal();
      }
    }
  });

  // ===== EXPORTS =====
  window.openContainerLogsModal = openContainerLogsModal;
  window.openFileLogsModal = openFileLogsModal;
  window.openLogsModal = openLogsModal;

})();
