import { NextRequest, NextResponse } from 'next/server'
import pool from '@/lib/db'
import { generateToken } from '@/lib/auth'
import { requireAdmin, logAdminAudit } from '@/lib/admin-auth'
import { sendMagicLinkEmail } from '@/lib/email'
import { createShortLink } from '@/lib/short-links'
import { checkRateLimit, RATE_LIMITS } from '@/lib/rate-limit'

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

  const body = await request.json().catch(() => ({}))
  const { email, name, company, greeting, message, closing, lang = 'de', send_email = true, version_id } = body

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

  // Rate limit by email (3/hour)
  const rl = checkRateLimit(`magic-link:${email.toLowerCase()}`, RATE_LIMITS.magicLink)
  if (!rl.allowed) {
    return NextResponse.json({ error: 'Too many invites for this email. Try again later.' }, { status: 429 })
  }

  const normalizedEmail = email.toLowerCase().trim()

  const normalizedLang = lang === 'en' ? 'en' : 'de'

  // Validate version if provided
  const normalizedVersionId = version_id || null
  if (normalizedVersionId) {
    const ver = await pool.query(
      `SELECT id, status FROM pitch_versions WHERE id = $1`,
      [normalizedVersionId],
    )
    if (ver.rows.length === 0) {
      return NextResponse.json({ error: 'Version not found' }, { status: 404 })
    }
    if (ver.rows[0].status !== 'committed') {
      return NextResponse.json({ error: 'Can only assign committed versions' }, { status: 400 })
    }
  }

  // Upsert investor
  const { rows } = await pool.query(
    `INSERT INTO pitch_investors (email, name, company, preferred_lang, assigned_version_id)
     VALUES ($1, $2, $3, $4, $5)
     ON CONFLICT (email) DO UPDATE SET
       name = COALESCE(EXCLUDED.name, pitch_investors.name),
       company = COALESCE(EXCLUDED.company, pitch_investors.company),
       preferred_lang = EXCLUDED.preferred_lang,
       assigned_version_id = COALESCE(EXCLUDED.assigned_version_id, pitch_investors.assigned_version_id),
       status = CASE WHEN pitch_investors.status = 'revoked' THEN 'invited' ELSE pitch_investors.status END,
       updated_at = NOW()
     RETURNING id, status`,
    [normalizedEmail, name || null, company || null, normalizedLang, normalizedVersionId],
  )

  const investor = rows[0]

  // Generate magic link
  const token = generateToken()
  const ttlHours = parseInt(process.env.MAGIC_LINK_TTL_HOURS || '72')
  const expiresAt = new Date(Date.now() + ttlHours * 60 * 60 * 1000)

  await pool.query(
    `INSERT INTO pitch_magic_links (investor_id, token, expires_at)
     VALUES ($1, $2, $3)`,
    [investor.id, token, expiresAt],
  )

  const baseUrl = process.env.PITCH_BASE_URL || 'https://pitch.breakpilot.ai'
  const magicLinkUrl = `${baseUrl}/auth/verify?token=${token}`
  const shortUrl = await createShortLink(token)

  if (send_email) {
    await sendMagicLinkEmail(normalizedEmail, name || null, shortUrl, greeting, message, closing, normalizedLang)
  }

  await logAdminAudit(
    adminId,
    'investor_invited',
    {
      email: normalizedEmail,
      name: name || null,
      company: company || null,
      expires_at: expiresAt.toISOString(),
      lang: normalizedLang,
      send_email: !!send_email,
      version_id: normalizedVersionId,
    },
    request,
    investor.id,
  )

  return NextResponse.json({
    success: true,
    investor_id: investor.id,
    email: normalizedEmail,
    expires_at: expiresAt.toISOString(),
    magic_link_url: magicLinkUrl,
    short_url: shortUrl,
  })
}
