import QRCode from 'qrcode'
import { getSession } from '@/lib/session'
import { authenticate } from '@/lib/auth'
import { checkSecurityToken } from '@/lib/security-token'
import { getRealmName } from '@/lib/realm'
import {
  base32Encode,
  otpauthUrl,
  generateSecret,
  validateToken,
  is2faEnabled,
  setAccountTotpSecret,
  clearAccountTotpSecret,
  getAccountTotpSecret,
} from '@/lib/two-factor'

// "15#1" -> "WOW1" (índice tras '#'); si no hay índice, usa el username tal cual.
function wowLabel(username: string): string {
  const idx = username.split('#')[1]
  return idx ? `WOW${idx}` : username
}

export async function POST(request: Request) {
  const session = await getSession()
  if (!session.bnetId || !session.accountId || !session.bnetEmail || !session.username) {
    return Response.json({ success: false, message: 'Tu sesión ha expirado. Inicia sesión de nuevo.' }, { status: 401 })
  }
  const accountId = session.accountId

  let body: Record<string, unknown> = {}
  try {
    body = await request.json()
  } catch {
    return Response.json({ success: false, message: 'Solicitud no válida.' }, { status: 400 })
  }
  const action = String(body.action ?? '')

  /* ------------------------------- Activar 2FA ------------------------------ */
  if (action === 'activate') {
    if (await is2faEnabled(accountId)) {
      return Response.json({ success: false, message: 'La verificación en 2 pasos ya está activada en esta cuenta.' })
    }
    const password = String(body.password ?? '')
    const securityToken = String(body.securityToken ?? '')
    if (!password || !securityToken) {
      return Response.json({ success: false, message: 'Introduce tu contraseña y tu token de seguridad.' })
    }
    const bnet = await authenticate(session.bnetEmail, password)
    if (!bnet) return Response.json({ success: false, message: 'Contraseña incorrecta.' })
    if (!(await checkSecurityToken(accountId, securityToken))) {
      return Response.json({ success: false, message: 'Token de seguridad incorrecto. Puedes solicitar uno nuevo.' })
    }

    const secret = generateSecret()
    const secretBase32 = base32Encode(secret)
    const realm = await getRealmName()
    const url = otpauthUrl(realm, wowLabel(session.username), secretBase32)
    const qrCodeUrl = await QRCode.toDataURL(url, { margin: 1, width: 220 })

    // Guardamos el secreto como PENDIENTE (no se escribe en la cuenta hasta que
    // el usuario confirme un código válido; así se evita cualquier bloqueo).
    session.pending2fa = secret.toString('hex')
    session.pending2faFor = accountId
    await session.save()

    return Response.json({
      success: true,
      message: 'Escanea el código QR con tu aplicación de autenticación y confirma un código para activar 2FA.',
      qrCodeUrl,
      secretKey: secretBase32,
    })
  }

  /* ------------------------------- Verificar -------------------------------- */
  if (action === 'verify') {
    if (!session.pending2fa || session.pending2faFor !== accountId) {
      return Response.json({ success: false, message: 'No hay una activación pendiente. Vuelve a empezar.' })
    }
    const code = String(body.code ?? '').replace(/\D/g, '')
    if (code.length !== 6) return Response.json({ success: false, message: 'Introduce el código de 6 dígitos.' })

    const secret = Buffer.from(session.pending2fa, 'hex')
    if (!validateToken(secret, Number(code))) {
      return Response.json({ success: false, message: 'Código incorrecto. Comprueba la hora de tu dispositivo e inténtalo de nuevo.' })
    }

    await setAccountTotpSecret(accountId, secret)
    session.pending2fa = undefined
    session.pending2faFor = undefined
    await session.save()

    return Response.json({ success: true, message: '¡Verificación en 2 pasos activada! A partir de ahora se pedirá el código al iniciar sesión en el juego.' })
  }

  /* ------------------------------- Desactivar ------------------------------- */
  if (action === 'disable') {
    const secret = await getAccountTotpSecret(accountId)
    if (!secret) return Response.json({ success: false, message: 'La verificación en 2 pasos no está activada.' })
    const code = String(body.code ?? '').replace(/\D/g, '')
    if (code.length !== 6) return Response.json({ success: false, message: 'Introduce el código de 6 dígitos de tu aplicación.' })
    if (!validateToken(secret, Number(code))) {
      return Response.json({ success: false, message: 'Código incorrecto. No se ha desactivado 2FA.' })
    }
    await clearAccountTotpSecret(accountId)
    return Response.json({ success: true, message: 'Verificación en 2 pasos desactivada.' })
  }

  return Response.json({ success: false, message: 'Acción no válida.' }, { status: 400 })
}
