import { NextRequest, NextResponse } from 'next/server';
import { eq } from 'drizzle-orm';
import { db } from '@/lib/db/client';
import { recipients, unsubscribes, trackingEvents, campaigns, workspaces } from '@/lib/db/schema';
import { verifyUnsubscribeToken } from '@/modules/sending/lib/footer-urls';

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

/**
 * One-Click Abmelde-Endpoint.
 *
 * URL-Form: `/api/track/unsubscribe?c=CAMPAIGN_ID&r=RECIPIENT_ID&t=HMAC_TOKEN`
 *
 * Workflow:
 * 1. Token gegen HMAC verifizieren (Anti-Tampering — kein Open-Abuse-Vektor)
 * 2. Recipient-Email aus DB ziehen (User soll seine Mail nicht in der URL sehen müssen)
 * 3. Unsubscribe-Row idempotent setzen (UNIQUE(email) → INSERT OR IGNORE-Pattern)
 * 4. Tracking-Event 'unsubscribe' schreiben für Analytics
 * 5. Bestätigungs-HTML rendern
 *
 * One-Click via GET ist von Gmail/Apple Mail akzeptiert. RFC 8058 (List-Unsubscribe-Post)
 * würde POST verlangen — das können wir später als Header zusätzlich setzen, ohne diese
 * Route zu brechen.
 */
export async function GET(req: NextRequest) {
  const { searchParams } = req.nextUrl;
  const campaignId = searchParams.get('c');
  const recipientId = searchParams.get('r');
  const token = searchParams.get('t');

  if (!campaignId || !recipientId || !token) {
    return htmlResponse(renderErrorPage('Ungültiger Abmelde-Link.', 'Bitte verwenden Sie den Link aus unserer letzten E-Mail.'), 400);
  }

  if (!verifyUnsubscribeToken(campaignId, recipientId, token)) {
    return htmlResponse(renderErrorPage('Link nicht gültig.', 'Der Sicherheitstoken stimmt nicht. Bitte verwenden Sie den Original-Link aus Ihrer E-Mail.'), 403);
  }

  const recipient = db.select().from(recipients).where(eq(recipients.id, recipientId)).get();
  if (!recipient) {
    return htmlResponse(renderErrorPage('Empfänger nicht gefunden.', 'Diese Adresse existiert nicht mehr in unseren Listen — Sie sind also bereits abgemeldet.'), 404);
  }

  // Workspace für Bestätigungsseite (Branding) — best-effort, fehlt → generisches Layout
  const campaign = db.select().from(campaigns).where(eq(campaigns.id, campaignId)).get();
  const workspace = campaign ? db.select().from(workspaces).where(eq(workspaces.id, campaign.workspaceId)).get() : undefined;

  // Idempotent: UNIQUE(email) → wenn schon abgemeldet, nichts tun. better-sqlite3 wirft
  // ConstraintError — wir fangen ihn und behandeln als "already done".
  let wasAlreadyUnsubscribed = false;
  try {
    db.insert(unsubscribes).values({
      id: crypto.randomUUID(),
      email: recipient.email,
      campaignId,
      source: 'link',
    }).run();
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    if (msg.includes('UNIQUE') || msg.includes('constraint')) {
      wasAlreadyUnsubscribed = true;
    } else {
      console.error('[/api/track/unsubscribe] insert failed:', msg);
      return htmlResponse(renderErrorPage('Speichern fehlgeschlagen.', 'Bitte versuchen Sie es später erneut oder schreiben Sie uns direkt.'), 500);
    }
  }

  // Tracking-Event nur beim ersten Mal — sonst doppelt für Stats
  if (!wasAlreadyUnsubscribed) {
    try {
      db.insert(trackingEvents).values({
        id: crypto.randomUUID(),
        campaignId,
        variantId: null,
        recipientId,
        messageId: '',
        eventType: 'unsubscribe',
      }).run();
    } catch (e) {
      console.error('[/api/track/unsubscribe] tracking-event-write failed:', e instanceof Error ? e.message : e);
    }
  }

  return htmlResponse(renderSuccessPage(recipient.email, workspace?.name ?? null, wasAlreadyUnsubscribed));
}

function htmlResponse(body: string, status = 200): Response {
  return new NextResponse(body, {
    status,
    headers: { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' },
  });
}

function escapeHtml(s: string): string {
  return s
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function renderSuccessPage(email: string, brandName: string | null, wasAlready: boolean): string {
  const headline = wasAlready ? 'Sie sind bereits abgemeldet.' : 'Sie wurden erfolgreich abgemeldet.';
  const body = wasAlready
    ? `Die Adresse <strong>${escapeHtml(email)}</strong> war bereits in unserer Sperrliste — Sie erhalten von ${brandName ? escapeHtml(brandName) : 'uns'} keine weiteren Marketing-Mails.`
    : `Wir senden in Zukunft keine Marketing-Mails mehr an <strong>${escapeHtml(email)}</strong>. Die Abmeldung gilt sofort — eventuell bereits versandte Mails können wir nicht mehr zurückholen.`;
  return page(headline, body, brandName);
}

function renderErrorPage(headline: string, body: string): string {
  return page(headline, escapeHtml(body), null);
}

function page(headline: string, body: string, brandName: string | null): string {
  const title = brandName ? `Abmeldung – ${escapeHtml(brandName)}` : 'Abmeldung';
  return `<!doctype html>
<html lang="de">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <meta name="robots" content="noindex,nofollow" />
  <title>${title}</title>
  <style>
    *,*::before,*::after { box-sizing: border-box; }
    body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px;
           font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
           background: #f4f4f5; color: #18181b; }
    .card { max-width: 560px; width: 100%; background: #fff; border-radius: 14px; padding: 36px 32px;
            box-shadow: 0 4px 24px rgba(0,0,0,.06); }
    h1 { margin: 0 0 12px; font-size: 22px; font-weight: 600; line-height: 1.3; }
    p  { margin: 0; font-size: 15px; line-height: 1.6; color: #3f3f46; }
    .workspace { margin-top: 24px; font-size: 12px; color: #a1a1aa; }
  </style>
</head>
<body>
  <main class="card" role="main">
    <h1>${escapeHtml(headline)}</h1>
    <p>${body}</p>
    ${brandName ? `<p class="workspace">${escapeHtml(brandName)}</p>` : ''}
  </main>
</body>
</html>`;
}
