import { NextRequest, NextResponse } from 'next/server'
import { randomBytes } from 'crypto'
import pool from '@/lib/db'
import { getSessionFromRequest } from '@/lib/session'
import { sendMfaResetEmail } from '@/lib/mailer'

// POST /api/portal-users/:id/reset-mfa
// Apenas admin_global pode chamar. Remove o MFA do usuário, grava token com
// expiração de 24h e envia e-mail com link para cadastrar novo autenticador.
export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  const sessionUser = await getSessionFromRequest(req)
  if (!sessionUser) {
    return NextResponse.json({ error: 'Não autorizado' }, { status: 401 })
  }
  if (sessionUser.role !== 'admin_global') {
    return NextResponse.json({ error: 'Apenas administradores globais podem remover MFA' }, { status: 403 })
  }

  const { id } = await params

  // Busca o usuário alvo
  const [rows] = await pool.execute<any[]>(
    'SELECT id, name, email, mfa_enabled FROM portal_users WHERE id = ?',
    [id],
  )
  const targetUser = rows[0]
  if (!targetUser) {
    return NextResponse.json({ error: 'Usuário não encontrado' }, { status: 404 })
  }
  if (!targetUser.mfa_enabled) {
    return NextResponse.json({ error: 'Este usuário não possui MFA ativo' }, { status: 400 })
  }

  // Gera token único (hex 32 bytes = 64 chars)
  const rawToken = randomBytes(32).toString('hex')
  const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 horas

  const conn = await (pool as any).getConnection()
  try {
    await conn.beginTransaction()

    // 1. Remove MFA e segredo do usuário
    await conn.execute(
      'UPDATE portal_users SET mfa_enabled = 0, mfa_secret = NULL WHERE id = ?',
      [id],
    )

    // 2. Invalida tokens anteriores deste usuário
    await conn.execute(
      "UPDATE mfa_reset_tokens SET used = 1 WHERE user_id = ? AND used = 0",
      [id],
    )

    // 3. Insere novo token de reset
    await conn.execute(
      'INSERT INTO mfa_reset_tokens (user_id, token, expires_at, requested_by) VALUES (?, ?, ?, ?)',
      [id, rawToken, expiresAt, sessionUser.id],
    )

    // 4. Registra na auditoria
    const { body: _body, ...reqClone } = req as any
    const ip = req.headers.get('x-forwarded-for') ?? req.headers.get('x-real-ip') ?? 'unknown'
    await conn.execute(
      `INSERT INTO audit_logs (tenant_id, user_id, action, entity_type, entity_id, details, ip_address, created_at)
       VALUES (?, ?, 'mfa_reset', 'portal_user', ?, ?, ?, NOW())`,
      [
        null,
        sessionUser.id,
        id,
        JSON.stringify({ target_user: targetUser.name, target_email: targetUser.email }),
        ip,
      ],
    )

    await conn.commit()
  } catch (err) {
    await conn.rollback()
    conn.release()
    console.error('[reset-mfa]', err)
    return NextResponse.json({ error: 'Erro interno ao processar reset de MFA' }, { status: 500 })
  }
  conn.release()

  // 5. Envia e-mail (fora da transação para não travar em caso de falha SMTP)
  const baseUrl = process.env.NEXTAUTH_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? 'http://localhost:3000'
  const setupUrl = `${baseUrl}/mfa-setup?token=${rawToken}`

  try {
    await sendMfaResetEmail({
      to: targetUser.email,
      userName: targetUser.name,
      resetByName: sessionUser.name,
      setupUrl,
      expiresInHours: 24,
    })
  } catch (emailErr) {
    console.error('[reset-mfa] Falha ao enviar e-mail:', emailErr)
    // Não retorna erro ao cliente — o reset já foi feito, apenas loga a falha
  }

  return NextResponse.json({
    ok: true,
    message: `MFA removido. Um e-mail foi enviado para ${targetUser.email} com instruções para cadastrar novo autenticador.`,
  })
}
