/**
 * Logger Middleware - Request logging
 */

import type { Context, Next } from 'hono';
import { env } from '../config/env';

type LogLevel = 'debug' | 'info' | 'warn' | 'error';

const LOG_LEVELS: Record<LogLevel, number> = {
  debug: 0,
  info: 1,
  warn: 2,
  error: 3,
};

/**
 * Get current log level from env
 */
function shouldLog(level: LogLevel): boolean {
  return LOG_LEVELS[level] >= LOG_LEVELS[env.LOG_LEVEL];
}

/**
 * Format log message
 */
function formatLog(level: LogLevel, message: string, meta?: Record<string, unknown>): string {
  const timestamp = new Date().toISOString();
  const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
  return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
}

/**
 * Logger utility
 */
export const logger = {
  debug(message: string, meta?: Record<string, unknown>): void {
    if (shouldLog('debug')) {
      console.log(formatLog('debug', message, meta));
    }
  },

  info(message: string, meta?: Record<string, unknown>): void {
    if (shouldLog('info')) {
      console.log(formatLog('info', message, meta));
    }
  },

  warn(message: string, meta?: Record<string, unknown>): void {
    if (shouldLog('warn')) {
      console.warn(formatLog('warn', message, meta));
    }
  },

  error(message: string, meta?: Record<string, unknown>): void {
    if (shouldLog('error')) {
      console.error(formatLog('error', message, meta));
    }
  },
};

/**
 * Request logging middleware
 */
export async function loggerMiddleware(c: Context, next: Next): Promise<void> {
  const method = c.req.method;
  const path = c.req.path;
  
  // Skip logging for health check endpoints (UptimeKuma polling)
  const skipLogging = path === '/version' || path === '/api/health';
  
  const start = Date.now();
  const requestId = crypto.randomUUID().slice(0, 8);

  // Attach request ID to context
  c.set('requestId', requestId);

  if (!skipLogging) {
    logger.info(`→ ${method} ${path}`, { requestId });
  }

  await next();

  if (!skipLogging) {
    const duration = Date.now() - start;
    const status = c.res.status;

    const logFn = status >= 500 ? logger.error : status >= 400 ? logger.warn : logger.info;
    logFn(`← ${method} ${path} ${status} ${duration}ms`, { requestId });
  }
}
