'use strict';

/* ── Structured logger — JSON in prod, pretty in dev ──────────────────────
   Usage:  logger.info('msg', { key: val })
           logger.error('msg', { err: e.message })
   ──────────────────────────────────────────────────────────────────────── */

const LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };

const COLORS = {
  error: '\x1b[31m',   // red
  warn:  '\x1b[33m',   // yellow
  info:  '\x1b[36m',   // cyan
  debug: '\x1b[90m',   // gray
};
const RESET = '\x1b[0m';

const isProd = process.env.NODE_ENV === 'production';

function _currentLevel() {
  const env = process.env.LOG_LEVEL;
  if (env && LEVELS[env] !== undefined) return LEVELS[env];
  return isProd ? LEVELS.info : LEVELS.debug;
}

function log(level, msg, meta) {
  if (LEVELS[level] > _currentLevel()) return;

  const ts = new Date().toISOString();

  if (isProd) {
    /* JSON — one line per entry, parseable by log aggregators */
    const entry = { level, ts, msg };
    if (meta && typeof meta === 'object') Object.assign(entry, meta);
    process.stdout.write(JSON.stringify(entry) + '\n');
  } else {
    /* Pretty — coloured label + message + optional meta */
    const color = COLORS[level] || '';
    const label = `[${ts}] ${color}${level.toUpperCase().padEnd(5)}${RESET}`;
    const metaStr = meta && Object.keys(meta).length
      ? ' ' + JSON.stringify(meta, null, 0)
      : '';
    process.stdout.write(`${label} ${msg}${metaStr}\n`);
  }
}

const logger = {
  error: (msg, meta) => log('error', msg, meta),
  warn:  (msg, meta) => log('warn',  msg, meta),
  info:  (msg, meta) => log('info',  msg, meta),
  debug: (msg, meta) => log('debug', msg, meta),

  /* Convenience: log an Error object */
  exception: (msg, err, meta) => log('error', msg, {
    err: err?.message,
    stack: !isProd ? err?.stack : undefined,
    ...meta,
  }),
};

module.exports = logger;
