import { NextRequest, NextResponse } from 'next/server'
import pool from '@/lib/db'

const TABLE_MAP: Record<string, string> = {
  kunden: 'fp_kunden',
  kunden_summary: 'fp_kunden_summary',
  umsatzerloese: 'fp_umsatzerloese',
  materialaufwand: 'fp_materialaufwand',
  personalkosten: 'fp_personalkosten',
  betriebliche: 'fp_betriebliche_aufwendungen',
  investitionen: 'fp_investitionen',
  sonst_ertraege: 'fp_sonst_ertraege',
  liquiditaet: 'fp_liquiditaet',
  guv: 'fp_guv',
}

// Whitelist of scalar columns that may be edited per table
const SCALAR_COLUMNS_WHITELIST: Record<string, string[]> = {
  fp_personalkosten: ['row_label', 'start_date', 'end_date', 'position', 'sort_order'],
  fp_investitionen: ['row_label', 'sort_order', 'position'],
  fp_betriebliche_aufwendungen: ['row_label', 'sort_order'],
  fp_umsatzerloese: ['row_label', 'sort_order'],
  fp_materialaufwand: ['row_label', 'sort_order'],
  fp_liquiditaet: ['row_label', 'sort_order'],
  fp_kunden: ['row_label', 'sort_order'],
  fp_kunden_summary: ['row_label', 'sort_order'],
  fp_sonst_ertraege: ['row_label', 'sort_order'],
  fp_guv: ['row_label', 'sort_order'],
}

// Valid month key: m1 .. m60
const MONTH_KEY_RE = /^m([1-9]|[1-5][0-9]|60)$/

function validateAdminSecret(request: NextRequest): boolean {
  const secret = process.env.PITCH_ADMIN_SECRET
  if (!secret) return false
  const auth = request.headers.get('authorization') ?? ''
  return auth === `Bearer ${secret}`
}

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ sheetName: string }> }
) {
  const { sheetName } = await params
  const table = TABLE_MAP[sheetName]
  if (!table) {
    return NextResponse.json({ error: `Unknown sheet: ${sheetName}` }, { status: 400 })
  }

  const scenarioId = request.nextUrl.searchParams.get('scenarioId')

  try {
    let query = `SELECT * FROM ${table}`
    const params: string[] = []

    if (scenarioId) {
      query += ' WHERE scenario_id = $1'
      params.push(scenarioId)
    } else {
      query += ' WHERE scenario_id = (SELECT id FROM fp_scenarios WHERE is_default = true LIMIT 1)'
    }
    query += ' ORDER BY sort_order'

    const { rows } = await pool.query(query, params)
    return NextResponse.json({ sheet: sheetName, rows }, {
      headers: { 'Cache-Control': 'no-store' },
    })
  } catch {
    return NextResponse.json({ error: 'Query failed' }, { status: 500 })
  }
}

export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ sheetName: string }> }
) {
  // C2: Admin-only — require PITCH_ADMIN_SECRET bearer token
  if (!validateAdminSecret(request)) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  const { sheetName } = await params
  const table = TABLE_MAP[sheetName]
  if (!table) {
    return NextResponse.json({ error: `Unknown sheet: ${sheetName}` }, { status: 400 })
  }

  try {
    const body = await request.json()
    const { rowId, updates } = body

    if (!rowId || typeof rowId !== 'string') {
      return NextResponse.json({ error: 'rowId required' }, { status: 400 })
    }
    if (!updates || typeof updates !== 'object' || Array.isArray(updates)) {
      return NextResponse.json({ error: 'updates object required' }, { status: 400 })
    }

    // C1: Separate and validate monthly vs scalar keys
    const monthlyKeys = Object.keys(updates).filter(k => MONTH_KEY_RE.test(k))
    const scalarKeys = Object.keys(updates).filter(k => !MONTH_KEY_RE.test(k))

    // Validate monthly values are numbers
    for (const k of monthlyKeys) {
      if (typeof updates[k] !== 'number' && isNaN(Number(updates[k]))) {
        return NextResponse.json({ error: `Invalid value for ${k}` }, { status: 400 })
      }
    }

    if (monthlyKeys.length > 0) {
      const valuesCol = sheetName === 'personalkosten' ? 'values_brutto' : 'values'
      // Build sanitized JSON patch object — no interpolation of user data into SQL
      const patch: Record<string, number> = {}
      for (const k of monthlyKeys) {
        patch[k] = Number(updates[k])
      }
      await pool.query(
        `UPDATE ${table} SET ${valuesCol} = ${valuesCol} || $1::jsonb, updated_at = NOW() WHERE id = $2`,
        [JSON.stringify(patch), rowId]
      )
    }

    if (scalarKeys.length > 0) {
      // C1: Validate scalar keys against whitelist
      const allowed = SCALAR_COLUMNS_WHITELIST[table] ?? []
      for (const k of scalarKeys) {
        if (!allowed.includes(k)) {
          return NextResponse.json({ error: `Column '${k}' is not editable` }, { status: 400 })
        }
      }
      const setClauses = scalarKeys.map((k, i) => `${k} = $${i + 2}`).join(', ')
      await pool.query(
        `UPDATE ${table} SET ${setClauses}, updated_at = NOW() WHERE id = $1`,
        [rowId, ...scalarKeys.map(k => updates[k])]
      )
    }

    const { rows } = await pool.query(`SELECT * FROM ${table} WHERE id = $1`, [rowId])
    return NextResponse.json({ updated: rows[0] })
  } catch {
    return NextResponse.json({ error: 'Update failed' }, { status: 500 })
  }
}
