/**
 * Centralized logger for Redlight server.
 *
 * Produces clean, colorized, tagged log lines inspired by Greenlight/Rails lograge style.
 *
 * Format:  TIMESTAMP  LEVEL  [TAG]  message
 * Example: 2026-03-01 12:00:00  INFO  [BBB]  GET getMeetings → 200 SUCCESS (45ms)
 */

// ── ANSI colors ─────────────────────────────────────────────────────────────
const C = {
  reset:   '\x1b[0m',
  bold:    '\x1b[1m',
  dim:     '\x1b[2m',
  red:     '\x1b[31m',
  green:   '\x1b[32m',
  yellow:  '\x1b[33m',
  blue:    '\x1b[34m',
  magenta: '\x1b[35m',
  cyan:    '\x1b[36m',
  white:   '\x1b[37m',
  gray:    '\x1b[90m',
};

const USE_COLOR = process.env.NO_COLOR ? false : true;
const c = (color, text) => USE_COLOR ? `${color}${text}${C.reset}` : text;

// ── Timestamp ───────────────────────────────────────────────────────────────
function ts() {
  const d = new Date();
  const pad = n => String(n).padStart(2, '0');
  const ms = String(d.getMilliseconds()).padStart(3, '0');
  return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}.${ms}`;
}

// ── Level formatting ────────────────────────────────────────────────────────
const LEVEL_STYLE = {
  DEBUG: { color: C.gray,   label: 'DEBUG' },
  INFO:  { color: C.green,  label: ' INFO' },
  WARN:  { color: C.yellow, label: ' WARN' },
  ERROR: { color: C.red,    label: 'ERROR' },
};

// ── Tag colors ──────────────────────────────────────────────────────────────
const TAG_COLORS = {
  BBB:        C.magenta,
  HTTP:       C.cyan,
  Federation: C.blue,
  FedSync:    C.blue,
  DB:         C.yellow,
  Auth:       C.green,
  Server:     C.white,
  Mailer:     C.cyan,
  Redis:      C.magenta,
  Admin:      C.yellow,
  Rooms:      C.green,
  Recordings: C.cyan,
  Branding:   C.white,
};

function formatLine(level, tag, message) {
  const lvl = LEVEL_STYLE[level] || LEVEL_STYLE.INFO;
  const tagColor = TAG_COLORS[tag] || C.white;
  const timestamp = c(C.gray, ts());
  const levelStr = c(lvl.color, lvl.label);
  const tagStr = c(tagColor, `[${tag}]`);
  return `${timestamp}  ${levelStr}  ${tagStr}  ${message}`;
}

// ── Public API ──────────────────────────────────────────────────────────────

/**
 * Create a tagged logger.
 * @param {string} tag - e.g. 'BBB', 'HTTP', 'Federation'
 */
export function createLogger(tag) {
  return {
    debug: (msg, ...args) => console.debug(formatLine('DEBUG', tag, msg), ...args),
    info:  (msg, ...args) => console.info(formatLine('INFO',  tag, msg), ...args),
    warn:  (msg, ...args) => console.warn(formatLine('WARN',  tag, msg), ...args),
    error: (msg, ...args) => console.error(formatLine('ERROR', tag, msg), ...args),
  };
}

// ── Pre-built loggers for common subsystems ─────────────────────────────────
export const log = {
  bbb:        createLogger('BBB'),
  http:       createLogger('HTTP'),
  federation: createLogger('Federation'),
  fedSync:    createLogger('FedSync'),
  db:         createLogger('DB'),
  auth:       createLogger('Auth'),
  server:     createLogger('Server'),
  mailer:     createLogger('Mailer'),
  redis:      createLogger('Redis'),
  admin:      createLogger('Admin'),
  rooms:      createLogger('Rooms'),
  recordings: createLogger('Recordings'),
  branding:   createLogger('Branding'),
};

// ── Helpers ─────────────────────────────────────────────────────────────────

/** Format duration with unit and color. */
export function fmtDuration(ms) {
  const num = Number(ms);
  if (num < 100)  return c(C.green, `${num.toFixed(0)}ms`);
  if (num < 1000) return c(C.yellow, `${num.toFixed(0)}ms`);
  return c(C.red, `${(num / 1000).toFixed(2)}s`);
}

/** Format HTTP status with color. */
export function fmtStatus(status) {
  const s = Number(status);
  if (s < 300) return c(C.green,  String(s));
  if (s < 400) return c(C.cyan,   String(s));
  if (s < 500) return c(C.yellow, String(s));
  return c(C.red, String(s));
}

/** Format HTTP method with color. */
export function fmtMethod(method) {
  const m = String(method).toUpperCase();
  const colors = { GET: C.green, POST: C.cyan, PUT: C.yellow, PATCH: C.yellow, DELETE: C.red };
  return c(colors[m] || C.white, m.padEnd(6));
}

/** Format BBB returncode with color. */
export function fmtReturncode(code) {
  if (code === 'SUCCESS') return c(C.green, code);
  if (code === 'FAILED')  return c(C.red, code);
  return c(C.yellow, code || '-');
}

// ── Sensitive value filtering ───────────────────────────────────────────────
const SENSITIVE_KEYS = [/pass/i, /pwd/i, /password/i, /token/i, /jwt/i, /secret/i, /authorization/i, /api[_-]?key/i];
export function isSensitiveKey(key) {
  return SENSITIVE_KEYS.some(rx => rx.test(key));
}

/**
 * Sanitize BBB params for logging: filter sensitive values, truncate long strings, omit checksum.
 */
export function sanitizeBBBParams(params) {
  const parts = [];
  for (const k of Object.keys(params || {})) {
    if (k.toLowerCase() === 'checksum') continue;
    if (isSensitiveKey(k)) {
      parts.push(`${k}=${c(C.dim, '[FILTERED]')}`);
    } else {
      let v = params[k];
      if (typeof v === 'string' && v.length > 80) v = v.slice(0, 80) + '…';
      parts.push(`${c(C.gray, k)}=${v}`);
    }
  }
  return parts.join(' ') || '-';
}
