'use client';
import { useState, useEffect, useRef, useCallback } from 'react';

interface LogEntry {
  time: string;
  level: number;
  levelName: string;
  msg: string;
  err?: Record<string, unknown>;
  raw: string;
}

const LEVEL_STYLES: Record<number, string> = {
  60: 'text-red-400', // fatal
  50: 'text-red-400', // error
  40: 'text-amber-400', // warn
  30: 'text-green-400', // info
  20: 'text-gray-400', // debug
  10: 'text-gray-500', // trace
};

function formatTime(iso: string): string {
  try {
    const d = new Date(iso);
    return d.toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3 });
  } catch {
    return iso;
  }
}

function parseLine(line: string): LogEntry {
  try {
    const obj = JSON.parse(line);
    const level = obj.level ?? 30;
    const LEVEL_NAMES: Record<number, string> = { 10: 'TRACE', 20: 'DEBUG', 30: 'INFO', 40: 'WARN', 50: 'ERROR', 60: 'FATAL' };
    return {
      time: obj.time ?? '',
      level,
      levelName: LEVEL_NAMES[level] ?? 'INFO',
      msg: obj.msg ?? '',
      err: obj.err,
      raw: line,
    };
  } catch {
    return { time: '', level: 30, levelName: 'INFO', msg: line, raw: line };
  }
}

interface ServerLogViewerProps {
  /** Backend URL for SSE stream, e.g. 'http://192.168.18.93:3000' */
  backendUrl?: string;
}

export function ServerLogViewer({ backendUrl = 'http://192.168.18.93:3000' }: ServerLogViewerProps) {
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [status, setStatus] = useState<'connecting' | 'live' | 'reconnecting' | 'error'>('connecting');
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setStatus('connecting');

    // Build the SSE URL with the session cookie forwarded
    // We use a fetch-based approach: open a GET request and read as text/event-stream
    let aborted = false;
    let retryDelay = 1000; // ms — exponential backoff
    const MAX_DELAY = 30_000;

    const connect = async () => {
      if (aborted) return;
      setStatus('connecting');
      try {
        // Use the same-origin proxy so the httpOnly backoffice cookie is forwarded server-side.
        const response = await fetch('/api/admin/logs/stream', {
          credentials: 'include',
        });

        if (!response.ok || aborted) {
          if (!aborted) scheduleRetry();
          return;
        }

        const reader = response.body?.getReader();
        if (!reader) { if (!aborted) scheduleRetry(); return; }

        const decoder = new TextDecoder();
        let buffer = '';

        setStatus('live');
        retryDelay = 1000; // reset backoff on success

        while (true) {
          if (aborted) {
            reader.cancel();
            break;
          }
          const { done, value } = await reader.read();
          if (done) {
            // Stream closed by server — schedule reconnect
            if (!aborted) scheduleRetry();
            break;
          }
          buffer += decoder.decode(value, { stream: true });
          const lines = buffer.split('\n');
          buffer = lines.pop() ?? '';

          for (const raw of lines) {
            if (!raw.trim()) continue;
            if (raw.startsWith('data: ')) {
              const json = raw.slice(6);
              setLogs(prev => {
                const next = [...prev, parseLine(json)];
                // Máximo 200 líneas para no sobrecargar el servidor ni el navegador.
                return next.length > 200 ? next.slice(-200) : next;
              });
            }
          }
        }
      } catch {
        if (!aborted) scheduleRetry();
      }
    };

    const scheduleRetry = () => {
      if (aborted) return;
      setStatus('reconnecting');
      setTimeout(() => {
        retryDelay = Math.min(retryDelay * 2, MAX_DELAY);
        connect();
      }, retryDelay);
    };

    connect();

    return () => {
      aborted = true;
    };
  }, [backendUrl]);

  return (
    <div className="flex flex-col h-full min-h-0">
      {/* Toolbar */}
      <div className="flex items-center justify-between px-4 py-2 bg-gray-900 border-b border-gray-700 flex-shrink-0">
        <div className="flex items-center gap-3">
          {/* Status indicator */}
          {status === 'live' && (
            <span className="flex items-center gap-1.5 text-xs text-green-400 font-medium">
              <span className="w-2 h-2 rounded-full bg-green-400 animate-pulse" />
              EN VIVO
            </span>
          )}
          {status === 'connecting' && (
            <span className="flex items-center gap-1.5 text-xs text-gray-400 font-medium">
              <span className="w-2 h-2 rounded-full bg-gray-500" />
              CONECTANDO...
            </span>
          )}
          {(status === 'reconnecting' || status === 'error') && (
            <span className="flex items-center gap-1.5 text-xs text-amber-400 font-medium">
              <span className="w-2 h-2 rounded-full bg-amber-400" />
              {status === 'reconnecting' ? 'RECONECTANDO...' : 'ERROR DE CONEXIÓN'}
            </span>
          )}
          <span className="text-xs text-gray-500">{logs.length} líneas</span>
        </div>

        <div className="flex items-center gap-2">
          <button
            onClick={() => setLogs([])}
            className="px-2 py-1 text-xs border border-gray-600 text-gray-400 rounded hover:bg-gray-800 hover:text-gray-200 transition-colors"
          >
            Limpiar
          </button>
        </div>
      </div>

      {/* Log content — F-129: flex-col-reverse para mostrar el más reciente arriba */}
      <div
        ref={containerRef}
        className="flex-1 overflow-y-auto bg-[#0d1117] font-mono text-xs leading-relaxed flex flex-col-reverse"
        style={{ minHeight: 0 }}
      >
        <table className="w-full table-fixed">
          <tbody>
            {logs.map((entry, i) => (
              <tr
                key={i}
                className={`border-b border-[#161b22] hover:bg-gray-900/50 ${LEVEL_STYLES[entry.level] ?? 'text-gray-300'}`}
              >
                {/* Timestamp */}
                <td className="px-3 py-0.5 text-gray-500 whitespace-nowrap select-all">
                  {formatTime(entry.time)}
                </td>
                {/* Level badge */}
                <td className="px-2 py-0.5 w-14 text-center font-bold whitespace-nowrap">
                  {entry.level >= 50 ? (
                    <span className="text-red-400">ERR</span>
                  ) : entry.level >= 40 ? (
                    <span className="text-amber-400">WARN</span>
                  ) : entry.level >= 30 ? (
                    <span className="text-green-500">INFO</span>
                  ) : entry.level >= 20 ? (
                    <span className="text-gray-500">DEBG</span>
                  ) : (
                    <span className="text-gray-600">TRCE</span>
                  )}
                </td>
                {/* Message */}
                <td className="px-3 py-0.5 text-gray-300 select-all">
                  {entry.msg}
                  {entry.err && (
                    <span className="ml-2 text-red-400">
                      {String((entry.err as { message?: string }).message ?? entry.err).slice(0, 120)}
                    </span>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
