import { Env } from './env'

type Level = 'debug' | 'info' | 'warn' | 'error'
const order: Record<Level, number> = { debug: 0, info: 1, warn: 2, error: 3 }
const current: Level = Env.LOG_LEVEL ?? 'info'

function shouldLog(level: Level) {
  return order[level] >= order[current]
}

function ts() {
  return new Date().toISOString()
}

function fmt(prefix: string, msg: string, meta?: any) {
  const head = `[${ts()}] [${prefix}] ${msg}`
  if (meta === undefined) return head
  try {
    const m = typeof meta === 'string' ? meta : JSON.stringify(meta)
    return `${head} ${m}`
  } catch {
    return head
  }
}

function maskSensitive(obj: any) {
  try {
    const o = JSON.parse(JSON.stringify(obj))
    const keys = ['card_number', 'cvv', 'token_id']
    const walk = (x: any) => {
      if (!x || typeof x !== 'object') return x
      for (const k of Object.keys(x)) {
        const v = x[k]
        if (keys.includes(k)) x[k] = v ? '***' : v
        else if (typeof v === 'object') x[k] = walk(v)
      }
      return x
    }
    return walk(o)
  } catch {
    return obj
  }
}

export const Logger = {
  debug(msg: string, meta?: any) {
    if (!shouldLog('debug')) return
    console.debug(fmt('debug', msg, meta))
  },
  info(msg: string, meta?: any) {
    if (!shouldLog('info')) return
    console.info(fmt('info', msg, meta))
  },
  warn(msg: string, meta?: any) {
    if (!shouldLog('warn')) return
    console.warn(fmt('warn', msg, meta))
  },
  error(msg: string, meta?: any) {
    if (!shouldLog('error')) return
    console.error(fmt('error', msg, meta))
  },
  mask(meta: any) {
    return maskSensitive(meta)
  },
}