/**
 * Recurring expense template routes — recurring-expenses (wave-10 leaf3).
 *
 * GET    /api/expenses/recurring            → list templates
 * POST   /api/expenses/recurring            → create template
 * PATCH  /api/expenses/recurring/:id        → update template
 * DELETE /api/expenses/recurring/:id        → deactivate template
 *
 * Auth: authMiddleware + expenses:write (mutations) / expenses:read (list)
 */
import { Hono } from 'hono'
import type { AppEnv } from '../../types'
import { authMiddleware } from '../../middleware/auth'
import { requirePermission } from '../../middleware/guards'
import {
  listRecurringExpenses,
  createRecurringExpense,
  updateRecurringExpense,
  deactivateRecurringExpense,
  createRecurringExpenseSchema,
  updateRecurringExpenseSchema,
} from '@zync/db/queries'

export const recurringExpensesRoute = new Hono<AppEnv>()

recurringExpensesRoute.use('*', authMiddleware)

// ── GET /api/expenses/recurring ───────────────────────────────────────────────

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

  const db = c.get('db')
  const templates = await listRecurringExpenses(db, session.tid)

  return c.json({ templates })
})

// ── POST /api/expenses/recurring ──────────────────────────────────────────────

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

  const body = await c.req.json().catch(() => null)
  if (!body) return c.json({ error: 'Invalid JSON body' }, 400)

  const parsed = createRecurringExpenseSchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Validation failed', details: parsed.error.flatten() }, 400)
  }

  const db = c.get('db')
  const template = await createRecurringExpense(db, session.tid, session.sub, parsed.data)

  return c.json({ template }, 201)
})

// ── PATCH /api/expenses/recurring/:id ────────────────────────────────────────

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

  const id = c.req.param('id')
  const body = await c.req.json().catch(() => null)
  if (!body) return c.json({ error: 'Invalid JSON body' }, 400)

  const parsed = updateRecurringExpenseSchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Validation failed', details: parsed.error.flatten() }, 400)
  }

  const db = c.get('db')
  try {
    const template = await updateRecurringExpense(db, session.tid, session.sub, id, parsed.data)
    return c.json({ template })
  } catch (err) {
    const msg = err instanceof Error ? err.message : 'Unknown error'
    if (msg.includes('not found')) return c.json({ error: 'Template not found' }, 404)
    return c.json({ error: msg }, 500)
  }
})

// ── DELETE /api/expenses/recurring/:id ───────────────────────────────────────

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

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

  try {
    await deactivateRecurringExpense(db, session.tid, session.sub, id)
    return c.body(null, 204)
  } catch (err) {
    const msg = err instanceof Error ? err.message : 'Unknown error'
    if (msg.includes('not found')) return c.json({ error: 'Template not found' }, 404)
    return c.json({ error: msg }, 500)
  }
})
