// Dual-transport logger: writes to the console AND to a log file.
// Levels: error | warn | info | debug.
//   LOG_LEVEL       console verbosity   (default info)
//   FILE_LOG_LEVEL  file verbosity      (default debug — keep a full record on disk)
//   LOG_TO_FILE     enable file logging (default true)
//   LOG_DIR         log directory       (default <bot>/logs)
//   LOG_FILE        log file name       (default bot.log)
//
// Copied from server/src/utils/logger.js rather than shared — the bot is an
// independently deployable process with its own package.json/Dockerfile.
const fs = require('fs')
const path = require('path')

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

const consoleThreshold = LEVELS[(process.env.LOG_LEVEL || 'info').toLowerCase()] ?? LEVELS.info
const fileThreshold = LEVELS[(process.env.FILE_LOG_LEVEL || 'debug').toLowerCase()] ?? LEVELS.debug

// Color only on an interactive TTY — never in files or Docker logs.
const useColor = Boolean(process.stdout.isTTY) && process.env.NO_COLOR == null
const COLOR = { error: '\x1b[31m', warn: '\x1b[33m', info: '\x1b[36m', debug: '\x1b[90m' }
const RESET = '\x1b[0m'

// ── File transport ────────────────────────────────────────────────────
const fileEnabled = (process.env.LOG_TO_FILE || 'true').toLowerCase() !== 'false'
let fileStream = null
let logFilePath = null

if (fileEnabled) {
  try {
    const dir = process.env.LOG_DIR || path.join(__dirname, '..', '..', 'logs')
    fs.mkdirSync(dir, { recursive: true })
    logFilePath = path.join(dir, process.env.LOG_FILE || 'bot.log')
    fileStream = fs.createWriteStream(logFilePath, { flags: 'a' })
    fileStream.on('error', (err) => {
      process.stderr.write(`[logger] file logging disabled: ${err.message}\n`)
      fileStream = null
    })
  } catch (err) {
    process.stderr.write(`[logger] could not open log file: ${err.message}\n`)
    fileStream = null
  }
}

function fmt(meta) {
  if (meta == null) return ''
  if (typeof meta === 'string') return meta
  if (meta instanceof Error) return JSON.stringify({ message: meta.message, stack: meta.stack })
  try {
    return JSON.stringify(meta)
  } catch {
    return String(meta)
  }
}

function emit(level, tag, msg, meta) {
  const levelNum = LEVELS[level]
  if (levelNum === undefined) return

  const ts = new Date().toISOString()
  const lvl = level.toUpperCase().padEnd(5)
  const label = tag ? ` [${tag}]` : ''
  const metaStr = meta === undefined ? '' : ` ${fmt(meta)}`
  const plain = `${ts} ${lvl}${label} ${msg}${metaStr}`

  // Console transport
  if (levelNum <= consoleThreshold) {
    const line = useColor ? `${COLOR[level] || ''}${plain}${RESET}` : plain
    const stream = level === 'error' || level === 'warn' ? process.stderr : process.stdout
    stream.write(`${line}\n`)
  }

  // File transport (plain text, no color)
  if (fileStream && levelNum <= fileThreshold) {
    fileStream.write(`${plain}\n`)
  }
}

function createLogger(tag) {
  return {
    error: (msg, meta) => emit('error', tag, msg, meta),
    warn: (msg, meta) => emit('warn', tag, msg, meta),
    info: (msg, meta) => emit('info', tag, msg, meta),
    debug: (msg, meta) => emit('debug', tag, msg, meta),
  }
}

// Flush and close the file stream (called on graceful shutdown).
createLogger.close = () =>
  new Promise((resolve) => {
    if (fileStream) fileStream.end(resolve)
    else resolve()
  })

createLogger.emit = emit
createLogger.logFilePath = logFilePath
module.exports = createLogger
