/**
 * Invoice activity routes — activity-timeline (wave-12).
 *
 * GET    /api/invoices/:id/activity         → paginated feed
 * POST   /api/invoices/:id/activity         → append note
 * DELETE /api/invoices/:id/activity/:actId  → soft-delete own note (15-min window)
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requireModuleEnabled } from '../../middleware/require-module-enabled'
import { requirePermission } from '../../middleware/guards'
import { loadActivityFeed } from '../../lib/activity-feed'
import { validateActivityNote } from '../../lib/activity-note-validation'
import {
  appendInvoiceActivity,
  getInvoiceActivityNote,
  softDeleteInvoiceActivity,
} from '@zync/db/queries'

export const invoiceActivityRoutes = new Hono<AppEnv>()

invoiceActivityRoutes.use('*', authMiddleware)
invoiceActivityRoutes.use('*', requireModuleEnabled('invoices'))

// ── GET /api/invoices/:id/activity ────────────────────────────────────────────

invoiceActivityRoutes.get(
  '/:id/activity',
  requirePermission('invoices:read'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const invoiceId = c.req.param('id')
    const before = c.req.query('before') ?? undefined
    const db = c.get('db')

    const feed = await loadActivityFeed(db, {
      table: 'invoice_activities',
      scopeColumn: 'invoice_id',
      entityId: invoiceId,
      tenantId: session.tid,
      before,
    })

    return c.json(feed, 200)
  },
)

// ── POST /api/invoices/:id/activity ───────────────────────────────────────────

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

    const invoiceId = c.req.param('id')
    const body = await c.req.json().catch(() => null)
    const parsed = validateActivityNote(body)
    if ('error' in parsed) return c.json({ error: parsed.error }, 400)

    const db = c.get('db')
    const result = await db.transaction(async (tx: Parameters<typeof appendInvoiceActivity>[0]) => {
      return appendInvoiceActivity(tx, {
        tenantId: session.tid!,
        invoiceId,
        actorId: session.sub,
        actorType: 'user',
        eventType: 'note_added',
        note: parsed.note,
      })
    })

    return c.json(result, 201)
  },
)

// ── DELETE /api/invoices/:id/activity/:activityId ─────────────────────────────

invoiceActivityRoutes.delete(
  '/:id/activity/:activityId',
  requirePermission('invoices:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    const invoiceId = c.req.param('id')
    const activityId = c.req.param('activityId')
    const db = c.get('db')

    const row = await getInvoiceActivityNote(db, session.tid, invoiceId, activityId)

    if (!row) return c.json({ error: 'Not found' }, 404)
    if (row.deletedAt) return c.json({ error: 'Already deleted' }, 410)
    if (row.eventType !== 'note_added') return c.json({ error: 'Only notes can be deleted' }, 403)
    if (row.actorId !== session.sub) return c.json({ error: 'Forbidden' }, 403)

    const ageMs = Date.now() - new Date(row.createdAt).getTime()
    if (ageMs > 15 * 60 * 1000) {
      return c.json({ error: 'Delete window expired (15 minutes)' }, 403)
    }

    await softDeleteInvoiceActivity(db, session.tid, activityId)

    return new Response(null, { status: 204 })
  },
)
