import { NextRequest, NextResponse } from 'next/server';
import { recordConversion } from '@/lib/db/campaign-repo';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

/**
 * Conversion-Tracking-Pixel (Phase 3a).
 *
 * URL-Form: `GET /api/track/conversion?r=RECIPIENT_ID&part=hp&kind=form_submit&value=99`
 *
 * Response: 1×1 transparent PNG mit aggressivem No-Cache, gleiche Pattern wie Open-Pixel.
 *
 * Integration auf der Ziel-CMS-Seite (z.B. kompass-versicherung.de Thank-You-Page):
 * ```html
 * <script>
 *   const u = new URL(location.href);
 *   const r = u.searchParams.get('id');
 *   const part = u.searchParams.get('part') || '';
 *   if (r) {
 *     const img = new Image();
 *     img.src = `https://mailforge.example.de/api/track/conversion?r=${encodeURIComponent(r)}&part=${encodeURIComponent(part)}&kind=form_submit`;
 *   }
 * </script>
 * ```
 *
 * Sicherheits-/Robustheits-Designentscheidungen:
 *  - Kein DB-Lookup vor dem Insert für `r` — Best-Effort, Phantom-IDs kosten nur einen
 *    DB-Insert. Rate-Limit kommt später bei Bedarf.
 *  - Bei missing/invalid params trotzdem PNG zurückgeben — kein 4xx an den Browser
 *    (sonst broken-image-Icon). Tracking-Failure ist silent.
 *  - `value` parsed als Integer, ungültige Werte → null statt Error.
 *  - `kind` und `part` landen IN `metaJson` — frei wählbar vom Caller, kein Enum-Lock-in.
 */

const TRANSPARENT_PNG = Buffer.from(
  'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
  'base64',
);

function pngResponse(): NextResponse {
  return new NextResponse(new Uint8Array(TRANSPARENT_PNG) as unknown as BodyInit, {
    status: 200,
    headers: {
      'Content-Type': 'image/png',
      'Content-Length': TRANSPARENT_PNG.byteLength.toString(),
      // Aggressive No-Cache damit Browser/Image-Proxies jedes Page-Reload durchlassen
      'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0, private',
      Pragma: 'no-cache',
      Expires: '0',
      // CORS: Pixel kann von beliebiger Origin geladen werden (kommt von Drittseiten wie kompass-versicherung.de)
      'Access-Control-Allow-Origin': '*',
    },
  });
}

export async function GET(req: NextRequest) {
  try {
    const { searchParams } = req.nextUrl;
    const recipientId = searchParams.get('r');
    if (!recipientId) {
      // Fehlt der wichtigste Param → trotzdem Pixel, nur kein Insert
      return pngResponse();
    }

    // Optional: value als Integer parsen, ungültiges Format → null
    const valueRaw = searchParams.get('value');
    const value = valueRaw ? Number.parseInt(valueRaw, 10) : undefined;
    const validValue = value !== undefined && Number.isFinite(value) ? value : undefined;

    // Sammle alle "Bonus"-Query-Params (kind, part, etc.) als meta-JSON
    // Reservierte: r, value (gehen in eigene Spalten)
    const meta: Record<string, string> = {};
    searchParams.forEach((v, k) => {
      if (k !== 'r' && k !== 'value') meta[k] = v;
    });

    const result = recordConversion({
      recipientId,
      value: validValue,
      meta: Object.keys(meta).length > 0 ? meta : undefined,
      source: 'pixel',
    });

    if (!result.ok) {
      // Silent log — kein 4xx an den Browser
      console.warn(`[/api/track/conversion] skipped: ${result.reason} (r=${recipientId})`);
    }
  } catch (e) {
    console.error('[/api/track/conversion] error:', e instanceof Error ? e.message : e);
  }
  return pngResponse();
}

// CORS-Preflight — manche Browser senden OPTIONS für cross-origin <img> nicht, aber
// für `fetch()` mit credentials oder custom headers schon. Best-effort kompatibel.
export async function OPTIONS() {
  return new NextResponse(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
      'Access-Control-Max-Age': '86400',
    },
  });
}
