/**
 * Request Logger Middleware
 * Logs all incoming requests with timing information
 */

// ANSI color codes for terminal output
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  dim: '\x1b[2m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
}

/**
 * Get color based on status code
 */
function getStatusColor(status) {
  if (status >= 500) return colors.red
  if (status >= 400) return colors.yellow
  if (status >= 300) return colors.cyan
  if (status >= 200) return colors.green
  return colors.reset
}

/**
 * Get color based on HTTP method
 */
function getMethodColor(method) {
  const methodColors = {
    GET: colors.green,
    POST: colors.blue,
    PUT: colors.yellow,
    PATCH: colors.yellow,
    DELETE: colors.red,
  }
  return methodColors[method] || colors.reset
}

/**
 * Format duration for display
 */
function formatDuration(ms) {
  if (ms < 1) return `${(ms * 1000).toFixed(0)}µs`
  if (ms < 1000) return `${ms.toFixed(0)}ms`
  return `${(ms / 1000).toFixed(2)}s`
}

/**
 * Logger middleware
 */
export function logger(options = {}) {
  const {
    skip = () => false,
    format = 'dev',
  } = options

  return (req, res, next) => {
    if (skip(req, res)) {
      return next()
    }

    const startTime = process.hrtime.bigint()
    const timestamp = new Date().toISOString()

    // Capture response
    const originalSend = res.send
    res.send = function (body) {
      const endTime = process.hrtime.bigint()
      const duration = Number(endTime - startTime) / 1e6 // Convert to ms

      const statusColor = getStatusColor(res.statusCode)
      const methodColor = getMethodColor(req.method)

      // Log format
      const logLine = [
        `${colors.dim}[${timestamp}]${colors.reset}`,
        `${methodColor}${req.method.padEnd(7)}${colors.reset}`,
        `${req.originalUrl}`,
        `${statusColor}${res.statusCode}${colors.reset}`,
        `${colors.dim}${formatDuration(duration)}${colors.reset}`,
      ].join(' ')

      console.log(logLine)

      // Log errors in detail
      if (res.statusCode >= 400 && body) {
        try {
          const parsed = typeof body === 'string' ? JSON.parse(body) : body
          if (parsed.error) {
            console.log(`  ${colors.red}→ ${parsed.error.message}${colors.reset}`)
          }
        } catch (e) {
          // Body is not JSON
        }
      }

      return originalSend.call(this, body)
    }

    next()
  }
}

/**
 * Log levels
 */
export const log = {
  info: (message, data = {}) => {
    console.log(`${colors.blue}[INFO]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
  },

  warn: (message, data = {}) => {
    console.log(`${colors.yellow}[WARN]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
  },

  error: (message, data = {}) => {
    console.error(`${colors.red}[ERROR]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
  },

  debug: (message, data = {}) => {
    if (process.env.NODE_ENV === 'development') {
      console.log(`${colors.magenta}[DEBUG]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
    }
  },

  success: (message, data = {}) => {
    console.log(`${colors.green}[OK]${colors.reset} ${message}`, Object.keys(data).length ? data : '')
  },
}
