/**
 * Invoice write-off route — bad-debt-writeoff (wave-12).
 * Mounted under invoice router (BEFORE broad /:id routes).
 *
 * POST /api/invoices/:id/write-off → mark invoice as BAD_DEBT or WRITTEN_OFF
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import {
  createDb,
  writeOffInputSchema,
  performWriteOff,
  WriteOffNotFoundError,
  WriteOffIneligibleError,
  WriteOffThresholdError,
} from '@zync/db/queries'
import { createNotification } from '@zync/db/queries'

export const invoiceWriteOffRoute = new Hono<AppEnv>()

invoiceWriteOffRoute.use('*', authMiddleware)

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

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

    const invoiceId = c.req.param('id')
    const body = await c.req.json().catch(() => null)
    const parsed = writeOffInputSchema.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 performWriteOff(db, session.tid, invoiceId, session.sub, parsed.data)

      // Best-effort: enqueue webhook + notification after commit
      try {
        await c.env.QUEUE.send({
          type: 'webhook.deliver',
          tenantId: session.tid,
          event: 'invoice.written_off',
          payload: { invoiceId, vatReclaimId: result.vatReclaimId },
        })
      } catch {
        // Non-fatal
      }

      // Best-effort notification to session user (OWNER context)
      try {
        await createNotification(db, {
          tenantId: session.tid,
          userId: session.sub,
          type: 'invoice.written_off',
          titleKey: 'Invoice written off as bad debt',
          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)
      }
      if (err instanceof WriteOffThresholdError) {
        return c.json({ error: err.message }, 422)
      }
      throw err
    }
  },
)
