/**
 * Vendor activity routes — activity-timeline (wave-12).
 *
 * GET    /api/vendors/:id/activity         → paginated feed
 * POST   /api/vendors/:id/activity         → append note
 * DELETE /api/vendors/:id/activity/:actId  → soft-delete own note (15-min window)
 *
 * Note: vendor CRUD routes live in routes/vendors.ts (flat file, not a directory).
 * These activity routes are mounted separately in routes/index.ts before the broad
 * /vendors path so /:id sub-routes resolve correctly.
 */
import { Hono } from 'hono'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission } from '../middleware/guards'
import { loadActivityFeed } from '../lib/activity-feed'
import { validateActivityNote } from '../lib/activity-note-validation'
import {
  appendVendorActivity,
  getVendorActivityNote,
  softDeleteVendorActivity,
} from '@zync/db/queries'

export const vendorActivityRoutes = new Hono<AppEnv>()

vendorActivityRoutes.use('*', authMiddleware)

// ── GET /api/vendors/:id/activity ─────────────────────────────────────────────

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

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

    const feed = await loadActivityFeed(db, {
      table: 'vendor_activities',
      scopeColumn: 'vendor_id',
      entityId: vendorId,
      tenantId: session.tid,
      before,
    })

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

// ── POST /api/vendors/:id/activity ────────────────────────────────────────────

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

    const vendorId = 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 appendVendorActivity>[0]) => {
      return appendVendorActivity(tx, {
        tenantId: session.tid!,
        vendorId,
        actorId: session.sub,
        actorType: 'user',
        eventType: 'note_added',
        note: parsed.note,
      })
    })

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

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

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

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

    const row = await getVendorActivityNote(db, session.tid, vendorId, 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 softDeleteVendorActivity(db, session.tid, activityId)

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