'use strict'
/**
 * email-queue.js — admin view of ERPNext's outbound Email Queue.
 *
 * During the migration, ERPNext email is globally muted (mute_emails=1) and the
 * scheduler is paused, so nothing flushes. This gives ops a window to SEE what
 * is queued (sender, recipients, reference doc, status, error) and DELETE/PURGE
 * stale entries — without opening the ERPNext desk.
 *
 * Backed by the ERPNext REST API (same token the hub already uses).
 *
 * Routes:
 *   GET    /email-queue?status=Not%20Sent&limit=200   → { rows, count }
 *   DELETE /email-queue/:name                          → { ok, deleted }
 *   POST   /email-queue/purge { status }               → { ok, deleted }
 */
const { json, parseBody, erpFetch } = require('./helpers')

async function listQueue (status, limit) {
  const params = new URLSearchParams({
    fields: JSON.stringify(['name', 'status', 'sender', 'reference_doctype', 'reference_name', 'creation', 'error', 'retry']),
    order_by: 'creation desc',
    limit_page_length: String(Math.min(500, limit || 200)),
  })
  if (status) params.set('filters', JSON.stringify([['status', '=', status]]))
  const res = await erpFetch('/api/resource/Email Queue?' + params)
  if (res.status !== 200) throw new Error('ERP list failed: ' + res.status)
  const rows = res.data?.data || []
  // ERPNext ignores `fields` when listing a child doctype via REST (returns
  // only `name`), so read each row's recipients from its full doc instead.
  // Capped to keep the call snappy on a large queue.
  const CAP = 60
  await Promise.all(rows.slice(0, CAP).map(async (r) => {
    try {
      const d = await erpFetch('/api/resource/Email Queue/' + encodeURIComponent(r.name))
      r.recipients = (d.data?.data?.recipients || []).map(x => x.recipient).filter(Boolean)
    } catch { r.recipients = [] }
  }))
  return rows
}

async function deleteOne (name) {
  const r = await erpFetch('/api/resource/Email Queue/' + encodeURIComponent(name), { method: 'DELETE' })
  return r.status === 202 || r.status === 200
}

async function handle (req, res, method, path, url) {
  // GET /email-queue
  if (path === '/email-queue' && method === 'GET') {
    const rows = await listQueue(url.searchParams.get('status') || '', parseInt(url.searchParams.get('limit') || '200', 10))
    const byStatus = {}
    for (const r of rows) byStatus[r.status] = (byStatus[r.status] || 0) + 1
    return json(res, 200, { rows, count: rows.length, by_status: byStatus })
  }
  // POST /email-queue/purge { status } — checked before the generic :name route
  if (path === '/email-queue/purge' && method === 'POST') {
    const body = await parseBody(req)
    const status = body.status || 'Not Sent'
    const rows = await listQueue(status, 500)
    let deleted = 0
    for (const r of rows) { if (await deleteOne(r.name)) deleted++ }
    return json(res, 200, { ok: true, deleted, status })
  }
  // DELETE /email-queue/:name
  const m = path.match(/^\/email-queue\/(.+)$/)
  if (m && method === 'DELETE') {
    const name = decodeURIComponent(m[1])
    if (await deleteOne(name)) return json(res, 200, { ok: true, deleted: name })
    return json(res, 500, { error: 'delete failed', name })
  }
  return json(res, 404, { error: 'Not found' })
}

module.exports = { handle }
