import { NextRequest, NextResponse } from 'next/server'
import pool from '@/lib/db'
import { createSession, setSessionCookie, getClientIp, logAudit, hashToken } from '@/lib/auth'
import { checkRateLimit, RATE_LIMITS } from '@/lib/rate-limit'

export async function POST(request: NextRequest) {
  const ip = getClientIp(request) || 'unknown'

  // Rate limit by IP
  const rl = checkRateLimit(`auth-verify:${ip}`, RATE_LIMITS.authVerify)
  if (!rl.allowed) {
    return NextResponse.json({ error: 'Too many attempts. Try again later.' }, { status: 429 })
  }

  const body = await request.json()
  const { token } = body

  if (!token || typeof token !== 'string') {
    return NextResponse.json({ error: 'Token required' }, { status: 400 })
  }

  // Find the magic link
  const { rows } = await pool.query(
    `SELECT ml.id, ml.investor_id, ml.expires_at, ml.used_at,
            i.email, i.status as investor_status,
            i.first_activity_at, i.data_masked_at
     FROM pitch_magic_links ml
     JOIN pitch_investors i ON i.id = ml.investor_id
     WHERE ml.token = $1`,
    [token]
  )

  if (rows.length === 0) {
    await logAudit(null, 'login_failed', { reason: 'invalid_token' }, request)
    return NextResponse.json({ error: 'Invalid link' }, { status: 401 })
  }

  const link = rows[0]

  if (link.used_at) {
    await logAudit(link.investor_id, 'login_failed', { reason: 'token_already_used' }, request)
    return NextResponse.json({ error: 'This link has already been used. Please request a new one.' }, { status: 401 })
  }

  if (new Date(link.expires_at) < new Date()) {
    await logAudit(link.investor_id, 'login_failed', { reason: 'token_expired' }, request)
    return NextResponse.json({ error: 'This link has expired. Please request a new one.' }, { status: 401 })
  }

  if (link.data_masked_at) {
    return NextResponse.json({ error: 'This access period has ended and data has been anonymized.' }, { status: 410 })
  }

  if (link.investor_status === 'revoked') {
    await logAudit(link.investor_id, 'login_failed', { reason: 'investor_revoked' }, request)
    return NextResponse.json({ error: 'Access has been revoked.' }, { status: 403 })
  }

  const ua = request.headers.get('user-agent')

  // Mark token as used
  await pool.query(
    `UPDATE pitch_magic_links SET used_at = NOW(), ip_address = $1, user_agent = $2 WHERE id = $3`,
    [ip, ua, link.id]
  )

  // Activate investor if first login; record first_activity_at once
  await pool.query(
    `UPDATE pitch_investors
     SET status = 'active',
         last_login_at = NOW(),
         login_count = login_count + 1,
         first_activity_at = COALESCE(first_activity_at, NOW()),
         updated_at = NOW()
     WHERE id = $1`,
    [link.investor_id]
  )

  // Create session and set cookie
  const { sessionId, jwt } = await createSession(link.investor_id, ip, ua)
  await setSessionCookie(jwt)

  // Check for new IP
  const { rows: prevSessions } = await pool.query(
    `SELECT DISTINCT ip_address FROM pitch_sessions WHERE investor_id = $1 AND id != $2 AND ip_address IS NOT NULL`,
    [link.investor_id, sessionId]
  )
  const knownIps = prevSessions.map((r: { ip_address: string }) => r.ip_address)
  if (knownIps.length > 0 && !knownIps.includes(ip)) {
    await logAudit(link.investor_id, 'new_ip_detected', { ip, known_ips: knownIps }, request, undefined, sessionId)
  }

  await logAudit(link.investor_id, 'login_success', { email: link.email }, request, undefined, sessionId)

  return NextResponse.json({ success: true, redirect: '/' })
}
