import { NextRequest, NextResponse } from 'next/server';
import { getUserFromRequest, jsonError } from '@/lib/auth-helpers';
import { getServiceRoleSupabase } from '@/lib/supabase';
import { sendWelcomeEmail } from '@/services/email';

export const dynamic = 'force-dynamic';

/**
 * Welcome email trigger (Session 10).
 *
 * POST /api/welcome-email
 * Bearer auth required.
 *
 * Idempotent. The send-once flag lives on Supabase auth user_metadata
 * (`welcome_email_sent`) — no migration needed; user_metadata is a
 * JSONB field Supabase exposes by default. We read it via the
 * service-role admin API so the user can't spoof it from the browser.
 *
 * Response codes:
 *   200 { sent: true, id }      — email sent successfully
 *   200 { sent: false, reason } — skipped (already sent, missing
 *                                  RESEND_API_KEY, etc.)
 *   401                          — auth missing
 *   500                          — unexpected server error
 *
 * The page that calls this (web/src/app/welcome/page.tsx) treats any
 * 200 response as success regardless of `sent`. Errors are surfaced
 * to Sentry, not to the user — a missed welcome email never blocks
 * onboarding.
 */
export async function POST(req: NextRequest) {
  const user = await getUserFromRequest(req);
  if (!user) return jsonError(401, 'Authentication required');
  if (!user.email) {
    return NextResponse.json({ sent: false, reason: 'no_email_on_account' });
  }

  const sb = getServiceRoleSupabase();
  if (!sb) {
    // Without service-role we can't read/write user_metadata; bail
    // softly so the welcome page render isn't blocked.
    return NextResponse.json({ sent: false, reason: 'no_service_role' });
  }

  // Read the auth user via the admin API to inspect user_metadata.
  let metadata: Record<string, unknown> = {};
  try {
    const { data, error } = await sb.auth.admin.getUserById(user.id);
    if (error || !data?.user) {
      return NextResponse.json({ sent: false, reason: 'user_not_found' });
    }
    metadata = (data.user.user_metadata as Record<string, unknown>) || {};
  } catch {
    return NextResponse.json({ sent: false, reason: 'metadata_read_failed' });
  }

  if (metadata.welcome_email_sent === true) {
    return NextResponse.json({ sent: false, reason: 'already_sent' });
  }

  // Send + flag. We flag REGARDLESS of send outcome — a Resend
  // outage shouldn't queue infinite retries from the welcome page.
  // Operators can manually clear the flag if a batch needs to be
  // re-sent.
  const result = await sendWelcomeEmail(user.email);

  try {
    await sb.auth.admin.updateUserById(user.id, {
      user_metadata: { ...metadata, welcome_email_sent: true, welcome_email_sent_at: new Date().toISOString() },
    });
  } catch {
    // Flag write failed — log via Sentry if wired; the duplicate-
    // suppression layer below will eventually catch up.
  }

  if (!result.ok) {
    return NextResponse.json({ sent: false, reason: result.error || 'send_failed' });
  }
  return NextResponse.json({ sent: true, id: result.id });
}
