import { NextResponse } from 'next/server';
import { parseLeadInput } from '@/lib/leads/validate';
import { rateLimitOrThrow, RateLimitError } from '@/lib/leads/rateLimit';
import { appendLeadRow } from '@/lib/google/sheets';

export const runtime = 'nodejs';

function formatTimestampForSheets(date: Date) {
  // "YYYY-MM-DD HH:mm:ss" (UTC) – reliably parsed/displayed by Google Sheets.
  return date.toISOString().replace('T', ' ').replace('Z', '').split('.')[0] ?? date.toISOString();
}

function getClientIp(req: Request): string {
  // In production behind a proxy/CDN, x-forwarded-for is typically set.
  const xff = req.headers.get('x-forwarded-for');
  if (xff) return xff.split(',')[0]?.trim() || 'unknown';
  return (
    req.headers.get('x-real-ip') ??
    req.headers.get('cf-connecting-ip') ??
    req.headers.get('x-client-ip') ??
    req.headers.get('x-forwarded') ??
    req.headers.get('x-cluster-client-ip') ??
    'unknown'
  );
}

function normalizeIp(ip: string) {
  const trimmed = ip.trim();
  if (!trimmed || trimmed === 'unknown') return '';
  // Localhost IPv6 loopback -> IPv4 loopback (more recognizable in Sheets).
  if (trimmed === '::1') return '127.0.0.1';
  // IPv4-mapped IPv6 addresses like "::ffff:127.0.0.1"
  if (trimmed.toLowerCase().startsWith('::ffff:')) return trimmed.slice('::ffff:'.length);
  return trimmed;
}

function langToAbbr(lang?: string) {
  const l = (lang ?? '').toLowerCase();
  if (l.startsWith('fr')) return 'FR';
  if (l.startsWith('en')) return 'EN';
  if (l.startsWith('ar')) return 'AR';
  return l ? l.toUpperCase() : '';
}

function businessTypeToFr(value: string) {
  switch (value) {
    case 'ecommerce':
      return 'E-commerce';
    case 'reseller':
      return 'Revendeur';
    case 'beginner':
      return 'Débutant';
    default:
      return value;
  }
}

function volumeToFr(value: string) {
  switch (value) {
    case '<50':
      return 'Moins de 50 commandes/mois';
    case '50-200':
      return '50–200 commandes/mois';
    case '200-500':
      return '200–500 commandes/mois';
    case '>500':
      return 'Plus de 500 commandes/mois';
    default:
      return value;
  }
}

function serviceToFr(value: string) {
  switch (value) {
    case 'ramassage':
      return 'Ramassage';
    case 'stockage':
      return 'Stockage';
    case 'affiliate':
      return 'Affiliate';
    default:
      return value;
  }
}

function originAllowed(req: Request) {
  const origin = req.headers.get('origin');
  if (!origin) return true;

  const host = req.headers.get('host');
  if (!host) return false;

  const expectedHttp = `http://${host}`;
  const expectedHttps = `https://${host}`;
  return origin === expectedHttp || origin === expectedHttps;
}

export async function POST(req: Request) {
  try {
    if (!originAllowed(req)) {
      return NextResponse.json({ ok: false, error: 'forbidden' }, { status: 403 });
    }

    const ip = getClientIp(req);
    rateLimitOrThrow(ip);

    const body = await req.json().catch(() => null);
    const lead = parseLeadInput(body);
    if (!lead) {
      return NextResponse.json(
        { ok: false, error: 'invalid_request' },
        { status: 400 }
      );
    }

    // Honeypot: treat as success (don’t reveal) but do nothing.
    if (lead.company && lead.company.length > 0) {
      return NextResponse.json({ ok: true });
    }

    const now = formatTimestampForSheets(new Date());
    const services = (lead.services ?? []).map(serviceToFr).join(', ');

    const storeIp = (process.env.LEADS_STORE_IP ?? 'true').toLowerCase() === 'true';
    const userAgent = req.headers.get('user-agent') ?? '';
    const normalizedIp = normalizeIp(ip);
    const lang = langToAbbr(lead.lang);

    // Row schema (recommended header in sheet):
    // timestamp, name, phone, city, businessType, volume, website, services, [status], lang, ip, userAgent
    const row: string[] = [
      now,
      lead.name,
      lead.phone,
      lead.city,
      businessTypeToFr(lead.businessType),
      volumeToFr(lead.volume),
      lead.website ?? '',
      services,
      '', // reserved for manual status (data validation in Sheets)
      lang,
      storeIp ? normalizedIp : '',
      userAgent,
    ];

    await appendLeadRow(row);

    return NextResponse.json({ ok: true });
  } catch (err: unknown) {
    if (err instanceof RateLimitError) {
      const retryAfterSeconds = err.retryAfterSeconds;
      return NextResponse.json(
        { ok: false, error: 'rate_limited', retryAfterSeconds },
        {
          status: 429,
          headers: {
            'Retry-After': String(retryAfterSeconds),
          },
        }
      );
    }

    // Don’t leak internal details
    return NextResponse.json({ ok: false, error: 'server_error' }, { status: 500 });
  }
}
