import { DB } from '../db.js'

/**
 * 操作日志中间件
 * 路由处理函数通过 c.set('audit', { action, target_type, target_id, target_name, meta })
 * 来声明本次请求要记录的操作；中间件在响应后异步落库。
 */
export async function auditMiddleware(c, next) {
  await next()

  const audit = c.get('audit')
  if (!audit) return

  const id = c.get('identity') || {}
  const ip = c.req.header('X-Forwarded-For') || c.req.header('X-Real-IP') || ''
  const ua = c.req.header('User-Agent') || ''

  const row = {
    action:      audit.action || `${c.req.method} ${c.req.path}`,
    actor_name:  audit.actor_name || '',
    actor_phone: id.phone || '',
    actor_email: id.email || '',
    target_type: audit.target_type || '',
    target_id:   audit.target_id || '',
    target_name: audit.target_name || '',
    ip,
    ua,
    meta: audit.meta ? JSON.stringify(audit.meta) : null,
  }

  // fire-and-forget：try-catch 保证同步/异步错误都能捕获，不影响主请求
  const stmt = DB.prepare(
    `INSERT INTO audit_logs (action, actor_name, actor_phone, actor_email, target_type, target_id, target_name, ip, ua, meta)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
  )
  const bindArgs = [
    row.action, row.actor_name, row.actor_phone, row.actor_email,
    row.target_type, row.target_id, row.target_name, row.ip, row.ua, row.meta
  ]
  try {
    await stmt.bind(...bindArgs).run()
  } catch (err) {
    console.error('[audit-failed] retrying...', err.message)
    try {
      await new Promise(r => setTimeout(r, 100))
      await stmt.bind(...bindArgs).run()
    } catch (err2) {
      console.error('[audit-failed-final]', err2.message, row)
    }
  }
}
