import { useRef, useEffect, useState, forwardRef } from 'react';

export interface LogRendererEntry {
  id: string;
  timestamp: Date;
  level: string;
  component: string;
  message: string;
  metadata?: unknown;
}

interface LogRendererProps {
  logs: LogRendererEntry[];
  maxEntries?: number;
  containerClassName?: string;
}

const levelColors: Record<string, string> = {
  debug: 'text-gray-500',
  info: 'text-green-400',
  warn: 'text-yellow-400',
  alert: 'text-red-400',
  error: 'bg-red-800 text-white',
  crit: 'bg-red-800 text-yellow-300',
  fatal: 'bg-red-800 text-gray-400',
};

function formatTimestamp(date: Date): string {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  const hh = String(date.getHours()).padStart(2, '0');
  const mm = String(date.getMinutes()).padStart(2, '0');
  const ss = String(date.getSeconds()).padStart(2, '0');
  const ms = String(date.getMilliseconds()).padStart(3, '0');
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}.${ms}`;
}

const LogRenderer = forwardRef<HTMLDivElement, LogRendererProps>(
  ({ logs, containerClassName }, ref) => {
    const scrollRef = useRef<HTMLDivElement>(null);
    const [expandedMetadata, setExpandedMetadata] = useState<Set<string>>(new Set());

    useEffect(() => {
      const target = ref && 'current' in ref ? ref : scrollRef;
      if (target.current) {
        target.current.scrollTop = target.current.scrollHeight;
      }
    }, [logs, ref]);

    const toggleMetadata = (id: string) => {
      setExpandedMetadata(prev => {
        const next = new Set(prev);
        if (next.has(id)) {
          next.delete(id);
        } else {
          next.add(id);
        }
        return next;
      });
    };

    return (
      <div
        ref={ref || scrollRef}
        className={`flex-1 overflow-y-auto p-2 font-mono text-xs leading-relaxed ${containerClassName ?? ''}`}
      >
        {logs.length === 0 ? (
          <div className="text-text-muted">No log entries</div>
        ) : (
          logs.map((entry) => {
            const levelClass = levelColors[entry.level] || 'text-text-secondary';
            return (
              <div key={entry.id} className="flex gap-2 py-0.5 hover:bg-bg-elevated/50">
                <span className="text-gray-600 shrink-0 select-none">
                  {formatTimestamp(entry.timestamp)}
                </span>
                <span className={`shrink-0 font-bold ${levelClass}`}>
                  {entry.level.toUpperCase().padEnd(5)}
                </span>
                <span className="text-cyan-400 shrink-0">
                  {entry.component}
                </span>
                <span className="text-text-secondary break-all min-w-0">
                  {entry.message}
                </span>
                {entry.metadata != null && (
                  <button
                    onClick={() => toggleMetadata(entry.id)}
                    className="shrink-0 text-text-muted hover:text-text-secondary transition-colors"
                    title={expandedMetadata.has(entry.id) ? 'Hide metadata' : 'Show metadata'}
                  >
                    {expandedMetadata.has(entry.id) ? '⊟' : '⊞'}
                  </button>
                )}
                {entry.metadata != null && expandedMetadata.has(entry.id) && (
                  <div className="w-full text-text-muted pl-[1em] border-l border-border-subtle mt-0.5 mb-1">
                    <pre className="whitespace-pre-wrap break-all">
                      {JSON.stringify(entry.metadata, null, 2)}
                    </pre>
                  </div>
                )}
              </div>
            );
          })
        )}
      </div>
    );
  },
);

LogRenderer.displayName = 'LogRenderer';

export default LogRenderer;
