/**
 * Expense settings routes — expenses-module.
 * Sole declaration of GET/PATCH /api/settings/expenses.
 * expense-settings-ui (spec 62) consumes this; it does not redeclare it.
 *
 * GET  /api/settings/expenses  → ExpenseSettings (expenses:read)
 * PATCH /api/settings/expenses → ExpenseSettings (settings:write)
 */
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 { getExpenseSettings, updateExpenseSettings } from '@zync/expenses'
import { expenseSettingsSchema, EXPENSE_SETTINGS_DEFAULTS } from '@zync/types'
import { auditLog } from '@zync/db/queries/_audit-forward'

export const expenseSettingsRoute = new Hono<AppEnv>()

expenseSettingsRoute.use('*', authMiddleware)
expenseSettingsRoute.use('*', requireModuleEnabled('expenses'))

// GET /api/settings/expenses
expenseSettingsRoute.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 settings = await getExpenseSettings(db, session.tid)
  return c.json(settings, 200)
})

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

  const parsed = expenseSettingsSchema.safeParse(await c.req.json())
  if (!parsed.success) {
    return c.json({ error: 'Invalid request', issues: parsed.error.issues }, 400)
  }

  let patch = { ...parsed.data }

  // Non-Business/Enterprise tiers: reset approval columns to defaults server-side
  const tier = session.tier ?? 'freelancer'
  if (tier !== 'business' && tier !== 'enterprise' && tier !== 'white_label') {
    patch = {
      ...patch,
      expense_approval_threshold_ils: EXPENSE_SETTINGS_DEFAULTS.expense_approval_threshold_ils,
      expense_approver_role: EXPENSE_SETTINGS_DEFAULTS.expense_approver_role,
    }
  }

  const db = c.get('db')
  const ip = c.req.header('CF-Connecting-IP') ?? null
  const requestId = c.req.header('X-Request-Id') ?? null

  const settings = await db.transaction(async (tx) => {
    const updated = await updateExpenseSettings(tx, tenantId, patch)

    await tx.insert(auditLog).values({
      tenantId,
      actorId: session.sub,
      actorType: 'user',
      entityType: 'expense_settings',
      entityId: tenantId,
      action: 'settings.expenses.update',
      changes: null,
      requestId,
      ip,
    })

    return updated
  })

  return c.json(settings, 200)
})
