type LogLevel = 'info' | 'error' | 'contract';

interface LogEntry {
  level: LogLevel;
  message: string;
  data?: unknown;
  timestamp: string;
}

const isBrowser = typeof window !== 'undefined';
const MAX_BUFFER = 50;
const buffer: LogEntry[] = [];

function emit(entry: LogEntry) {
  buffer.push(entry);
  if (buffer.length > MAX_BUFFER) {
    buffer.shift();
  }

  if (isBrowser && import.meta.env.DEV) {
    window.dispatchEvent(
      new CustomEvent('kraiken:log', {
        detail: entry,
      })
    );
  }
}

function buildEntry(level: LogLevel, message: string, data?: unknown): LogEntry {
  return {
    level,
    message,
    data,
    timestamp: new Date().toISOString(),
  };
}

export function info(message: string, data?: unknown) {
  emit(buildEntry('info', message, data));
}

export function contract(message: string, data?: unknown) {
  emit(buildEntry('contract', message, data));
}

export function error(message: string, data?: unknown) {
  emit(buildEntry('error', message, data));
}

export function getBufferedLogs(): LogEntry[] {
  return [...buffer];
}

export default {
  info,
  contract,
  error,
  getBufferedLogs,
};
