/**
 * Invoice recovery route — bad-debt-writeoff (wave-12).
 * Mounted under invoice router (BEFORE broad /:id routes).
 *
 * POST /api/invoices/:id/record-recovery → record payment against a written-off invoice
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import {
  createDb,
  recordRecoveryInputSchema,
  performRecovery,
  WriteOffNotFoundError,
  WriteOffIneligibleError,
  createNotification,
} from '@zync/db/queries'

export const invoiceRecordRecoveryRoute = new Hono<AppEnv>()

invoiceRecordRecoveryRoute.use('*', authMiddleware)

// POST /api/invoices/:id/record-recovery
invoiceRecordRecoveryRoute.post(
  '/:id/record-recovery',
  requirePermission('invoices:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    // Recovery requires OWNER or ADMIN role
    const role = session.role
    if (!['owner', 'admin'].includes(role?.toLowerCase() ?? '')) {
      return c.json({ error: 'Forbidden: record-recovery requires OWNER or ADMIN role' }, 403)
    }

    const invoiceId = c.req.param('id')
    const body = await c.req.json().catch(() => null)
    const parsed = recordRecoveryInputSchema.safeParse(body)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const db = createDb(c.env)

    try {
      const result = await performRecovery(db, session.tid, invoiceId, session.sub, parsed.data)

      // Best-effort: enqueue webhook
      try {
        await c.env.QUEUE.send({
          type: 'webhook.deliver',
          tenantId: session.tid,
          event: 'invoice.recovered',
          payload: { invoiceId, newStatus: result.status, reclaimStatus: result.reclaimStatus },
        })
      } catch {
        // Non-fatal
      }

      // Best-effort notification
      try {
        await createNotification(db, {
          tenantId: session.tid,
          userId: session.sub,
          type: 'invoice.recovered',
          titleKey: 'Recovery payment recorded',
          entityType: 'invoice',
          entityId: invoiceId,
        })
      } catch {
        // Non-fatal
      }

      return c.json(result, 200)
    } catch (err) {
      if (err instanceof WriteOffNotFoundError) {
        return c.json({ error: 'Invoice not found' }, 404)
      }
      if (err instanceof WriteOffIneligibleError) {
        return c.json({ error: err.message }, 422)
      }
      throw err
    }
  },
)
