import { NextRequest, NextResponse } from 'next/server'
import pool from '@/lib/db'
import { requireAdmin, logAdminAudit } from '@/lib/admin-auth'

interface RouteContext {
  params: Promise<{ id: string }>
}

export async function PATCH(request: NextRequest, ctx: RouteContext) {
  const guard = await requireAdmin(request)
  if (guard.kind === 'response') return guard.response
  const adminId = guard.kind === 'admin' ? guard.admin.id : null

  const { id } = await ctx.params
  const body = await request.json().catch(() => ({}))
  const { value, min_value, max_value, step_size, label_de, label_en } = body

  const before = await pool.query(
    `SELECT scenario_id, key, label_de, label_en, value, min_value, max_value, step_size
     FROM pitch_fm_assumptions WHERE id = $1`,
    [id],
  )
  if (before.rows.length === 0) {
    return NextResponse.json({ error: 'Assumption not found' }, { status: 404 })
  }

  const updates: string[] = []
  const params: unknown[] = []
  let p = 1

  if (value !== undefined) {
    updates.push(`value = $${p++}`)
    params.push(JSON.stringify(value))
  }
  if (min_value !== undefined) {
    updates.push(`min_value = $${p++}`)
    params.push(min_value)
  }
  if (max_value !== undefined) {
    updates.push(`max_value = $${p++}`)
    params.push(max_value)
  }
  if (step_size !== undefined) {
    updates.push(`step_size = $${p++}`)
    params.push(step_size)
  }
  if (typeof label_de === 'string') {
    updates.push(`label_de = $${p++}`)
    params.push(label_de)
  }
  if (typeof label_en === 'string') {
    updates.push(`label_en = $${p++}`)
    params.push(label_en)
  }

  if (updates.length === 0) {
    return NextResponse.json({ error: 'no fields to update' }, { status: 400 })
  }

  params.push(id)
  const { rows } = await pool.query(
    `UPDATE pitch_fm_assumptions SET ${updates.join(', ')} WHERE id = $${p} RETURNING *`,
    params,
  )

  // Invalidate cached results for this scenario so the next compute uses the new value
  await pool.query(`DELETE FROM pitch_fm_results WHERE scenario_id = $1`, [before.rows[0].scenario_id])

  await logAdminAudit(
    adminId,
    'assumption_edited',
    {
      assumption_id: id,
      scenario_id: before.rows[0].scenario_id,
      key: before.rows[0].key,
      before: {
        value: typeof before.rows[0].value === 'string' ? JSON.parse(before.rows[0].value) : before.rows[0].value,
        min_value: before.rows[0].min_value,
        max_value: before.rows[0].max_value,
        step_size: before.rows[0].step_size,
      },
      after: {
        value: typeof rows[0].value === 'string' ? JSON.parse(rows[0].value) : rows[0].value,
        min_value: rows[0].min_value,
        max_value: rows[0].max_value,
        step_size: rows[0].step_size,
      },
    },
    request,
  )

  return NextResponse.json({ assumption: rows[0] })
}
