'use server'

import { headers } from 'next/headers'
import { redirect } from 'next/navigation'
import { cms } from '@/lib/site'
import { checkNotABot, HONEYPOT_FIELD, STAMP_FIELD, TURNSTILE_FIELD } from '@/lib/antiSpam'

const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/
const PHONE = /^[+\d][\d\s-]{6,19}$/
const clip = (v: FormDataEntryValue | null, n: number) => String(v ?? '').trim().slice(0, n)

/**
 * «سجّل اهتمامك»: validate, save to the Leads collection, and come back to the form with a message.
 * The address carries no #form anchor: a redirect with both a query and a hash arrives without the query,
 * and the page then has no way to know it should show the confirmation.
 */
export async function submitLead(form: FormData): Promise<void> {
  const locale = form.get('locale') === 'en' ? 'en' : 'ar'
  // the form lives on two pages now; it returns to the one it was sent from, never to an address it is handed
  const page = form.get('from') === 'contact' ? '/contact' : '/pricing'
  const base = locale === 'en' ? `/en${page}` : page
  const slug = clip(form.get('course'), 60)

  // Not a bot: the honeypot, the time trap, and Turnstile once its keys are set (see lib/antiSpam).
  // A caught bot is answered with the same «sent» page a person sees, so a script learns nothing from the
  // reply about which of its attempts got through.
  const head = await headers()
  const verdict = await checkNotABot({
    honeypot: clip(form.get(HONEYPOT_FIELD), 200),
    stamp: clip(form.get(STAMP_FIELD), 20),
    token: clip(form.get(TURNSTILE_FIELD), 3000),
    ip: head.get('cf-connecting-ip') || head.get('x-forwarded-for')?.split(',')[0]?.trim() || undefined,
  })
  if (!verdict.ok) {
    // The honeypot and the time trap only ever catch machines, so those are answered with the same «sent»
    // page a person sees. The other two can happen to a real visitor — one who did not tick the box, or one
    // sharing a school's address with a hundred classmates — so those are told what happened.
    const say = verdict.reason === 'turnstile' ? 'bot' : verdict.reason === 'tooMany' ? 'busy' : ''
    if (say) {
      redirect(`${base}?error=${say}${slug ? `&course=${encodeURIComponent(slug)}` : ''}`)
    }
    redirect(`${base}?sent=1`)
  }

  const name = clip(form.get('name'), 120)
  const email = clip(form.get('email'), 200).toLowerCase()
  const phone = clip(form.get('phone'), 20)
  if (name.length < 2 || !EMAIL.test(email) || (phone && !PHONE.test(phone))) {
    redirect(`${base}?error=1${slug ? `&course=${encodeURIComponent(slug)}` : ''}`)
  }

  const payload = await cms()
  const course = slug
    ? (await payload.find({ collection: 'courses', where: { slug: { equals: slug } }, limit: 1, depth: 0 })).docs[0]
    : undefined
  await payload.create({
    collection: 'leads',
    overrideAccess: true,
    data: {
      name,
      email,
      phone: phone || undefined,
      role: clip(form.get('role'), 80) || undefined,
      course: course?.id,
      courseSlug: slug || undefined,
      note: clip(form.get('note'), 2000) || undefined,
      locale,
      status: 'new',
    },
  })
  redirect(`${base}?sent=1`)
}
