/**
 * Smoke-Test für den Order-Webhook-Endpoint.
 *
 * Lokal: `npm run dev` läuft, dann `npx tsx scripts/test-webhook.ts`.
 * Setzt MAILFORGE_WEBHOOK_SECRET=test-secret und feuert verschiedene Requests.
 *
 * Tests:
 *  - Korrekte HMAC → 200 (mit recipient_not_found, weil DB leer in dev)
 *  - Falsche Signatur → 401
 *  - Zu alter Timestamp → 401
 *  - Schema-Verletzung → 400
 *  - Replay desselben Body 2× → beide 200 (Idempotenz liegt auf DB-Constraint-Ebene)
 */
import { createHmac } from 'node:crypto';

const BASE = process.env.MAILFORGE_BASE_URL ?? 'http://localhost:3000';
const SECRET = process.env.MAILFORGE_WEBHOOK_SECRET ?? 'test-secret';

let failed = 0;
let passed = 0;
function check(name: string, cond: boolean, detail?: string) {
  if (cond) { passed++; console.log(`  ✓ ${name}`); }
  else { failed++; console.log(`  ✗ ${name}${detail ? ` — ${detail}` : ''}`); }
}

async function postWebhook(body: object, opts: { signature?: string; timestamp?: string } = {}): Promise<Response> {
  const json = JSON.stringify(body);
  const ts = opts.timestamp ?? String(Date.now());
  const sig = opts.signature ?? createHmac('sha256', SECRET).update(`${ts}.${json}`).digest('hex');
  return fetch(`${BASE}/api/track/order-webhook`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-MF-Signature': sig,
      'X-MF-Timestamp': ts,
    },
    body: json,
  });
}

async function run() {
  console.log(`\nTesting ${BASE}/api/track/order-webhook (secret=${SECRET})`);

  // 1. Korrekte Signatur, recipient existiert nicht (dev-DB) → 200 mit skipped
  {
    const res = await postWebhook({
      recipientId: 'rec-nonexistent-' + Date.now(),
      kind: 'order',
      value: 9900,
      orderId: 'ORD-test-1',
    });
    const body = await res.json() as { ok?: boolean; skipped?: string };
    check('Korrekte HMAC → 200', res.status === 200, `got ${res.status}`);
    check('Body { ok: true, skipped: "recipient_not_found" }',
      body.ok === true && body.skipped === 'recipient_not_found',
      JSON.stringify(body));
  }

  // 2. Falsche Signatur → 401
  {
    const res = await postWebhook(
      { recipientId: 'rec-1', kind: 'order' },
      { signature: 'deadbeef' },
    );
    check('Falsche Signatur → 401', res.status === 401, `got ${res.status}`);
  }

  // 3. Zu alter Timestamp → 401
  {
    const res = await postWebhook(
      { recipientId: 'rec-1', kind: 'order' },
      { timestamp: String(Date.now() - 10 * 60 * 1000) }, // 10min alt
    );
    check('Alter Timestamp (10min) → 401', res.status === 401, `got ${res.status}`);
  }

  // 4. Schema-Verletzung: unbekannter `kind` → 400
  {
    const res = await postWebhook({ recipientId: 'rec-1', kind: 'unknown_event' });
    check('Unbekannter kind → 400', res.status === 400, `got ${res.status}`);
  }

  // 5. Fehlende Required → 400
  {
    const res = await postWebhook({ kind: 'order' });
    check('Fehlende recipientId → 400', res.status === 400, `got ${res.status}`);
  }

  // 6. Fehlende Header → 401
  {
    const res = await fetch(`${BASE}/api/track/order-webhook`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ recipientId: 'rec-1', kind: 'order' }),
    });
    check('Fehlende Headers → 401', res.status === 401, `got ${res.status}`);
  }

  console.log(`\n${passed} passed, ${failed} failed`);
  if (failed > 0) process.exit(1);
}

run().catch((e) => {
  console.error('Test runner crashed:', e);
  process.exit(1);
});
