/**
 * LogTerminal — admin-only live view of the backend log relay.
 *
 * Polls GET /api/logs?since=<cursor> with the admin bearer token and
 * renders the captured logger output as a read-only terminal.
 *
 * Architecture: rendered by App.jsx only for authenticated users; toggled
 * by the TERMINAL button in InfoBar.
 *
 * Design: 2s REST polling reuses the existing bearer-token flow instead of
 * adding WebSocket authentication; auto-scroll halts while the pointer is
 * over the terminal so lines can be read mid-stream.
 */

import { useEffect, useRef, useState, useCallback } from "react";
import { useAuth } from "../hooks/useAuth";
import { apiUrl } from "../utils/api";

const POLL_MS = 2000;
const LEVEL_COLORS = {
  DEBUG: "#6b6b78",
  INFO: "#8fbbe8",
  WARNING: "#e7bd70",
  ERROR: "#ff8b8b",
  CRITICAL: "#ff6b6b",
};

export default function LogTerminal({ onClose }) {
  const { token } = useAuth();
  const [lines, setLines] = useState([]);
  const [cursor, setCursor] = useState(0);
  const [error, setError] = useState(null);
  const [paused, setPaused] = useState(false);
  const bodyRef = useRef(null);
  const pausedRef = useRef(false);

  const fetchNew = useCallback(async () => {
    try {
      const res = await fetch(apiUrl(`/api/logs?since=${cursor}`), {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error(`Log fetch failed (${res.status})`);
      const data = await res.json();
      if (data.lines?.length) {
        setLines((previous) => [...previous.slice(-2000), ...data.lines]);
      }
      if (typeof data.next === "number") setCursor(data.next);
      setError(null);
    } catch (err) {
      setError(err.message);
    }
  }, [cursor, token]);

  useEffect(() => {
    fetchNew();
    const timer = setInterval(fetchNew, POLL_MS);
    return () => clearInterval(timer);
  }, [fetchNew]);

  useEffect(() => {
    const el = bodyRef.current;
    if (el && !pausedRef.current) el.scrollTop = el.scrollHeight;
  }, [lines]);

  async function clearLogs() {
    try {
      const res = await fetch(apiUrl("/api/logs/clear"), {
        method: "POST",
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      });
      if (!res.ok) throw new Error(`Clear failed (${res.status})`);
      setLines([]);
    } catch (err) {
      setError(err.message);
    }
  }

  async function copyLogs() {
    try {
      await navigator.clipboard.writeText(lines.map((line) => line.text).join("\n"));
    } catch {
      /* clipboard unavailable — ignore */
    }
  }

  const headerButton = {
    background: "rgba(91,155,213,.08)",
    border: "1px solid rgba(91,155,213,.30)",
    borderRadius: 3,
    color: "#8fbbe8",
    padding: "2px 6px",
    fontFamily: "'Space Mono', monospace",
    fontSize: 8,
    cursor: "pointer",
  };

  return (
    <aside
      style={{
        position: "fixed",
        right: 16,
        top: 66,
        bottom: 96,
        width: 460,
        maxWidth: "calc(100vw - 32px)",
        display: "flex",
        flexDirection: "column",
        background: "rgba(8,10,12,0.95)",
        backdropFilter: "blur(8px)",
        border: "1px solid rgba(91,155,213,0.30)",
        borderRadius: 6,
        boxShadow: "0 14px 44px rgba(0,0,0,0.6)",
        fontFamily: "'Space Mono', monospace",
        zIndex: 1300,
      }}
    >
      <header
        style={{
          display: "flex",
          alignItems: "center",
          gap: 8,
          padding: "8px 12px",
          borderBottom: "1px solid rgba(255,255,255,0.07)",
        }}
      >
        <span style={{ color: "#8fbbe8", fontWeight: 700, fontSize: 10, letterSpacing: "0.14em" }}>
          LOG TERMINAL
        </span>
        <span style={{ fontSize: 9, color: "#6b6b78" }}>{lines.length} lines</span>
        <span style={{ flex: 1 }} />
        <button onClick={copyLogs} style={headerButton} title="Copy all relayed lines to the clipboard">
          COPY
        </button>
        <button onClick={clearLogs} style={headerButton} title="Clear the in-memory relay buffer">
          CLEAR
        </button>
        <button onClick={onClose} style={headerButton} title="Close the log terminal">
          X
        </button>
      </header>

      <div
        ref={bodyRef}
        onMouseEnter={() => {
          pausedRef.current = true;
          setPaused(true);
        }}
        onMouseLeave={() => {
          pausedRef.current = false;
          setPaused(false);
        }}
        style={{
          flex: 1,
          overflowY: "auto",
          padding: "10px 12px",
          fontSize: 9,
          lineHeight: 1.65,
        }}
      >
        {lines.length === 0 && (
          <div style={{ color: "#6b6b78" }}>no lines yet — the relay captures log output once the simulation starts</div>
        )}
        {lines.map((entry) => (
          <div
            key={entry.seq}
            style={{
              color: LEVEL_COLORS[entry.level] || "#d0d0da",
              whiteSpace: "pre-wrap",
              wordBreak: "break-word",
            }}
          >
            {entry.text}
          </div>
        ))}
      </div>

      <footer
        style={{
          padding: "6px 12px",
          borderTop: "1px solid rgba(255,255,255,0.07)",
          fontSize: 9,
          color: error ? "#ff8b8b" : paused ? "#e7bd70" : "#6b6b78",
        }}
      >
        {error ? `ERROR: ${error}` : paused ? "PAUSED — move the pointer away to resume auto-scroll" : "TAILING — 2s poll"}
      </footer>
    </aside>
  );
}