import { CURRENT_ART9_MAIL_VERSION } from "../../utils/consent-texts";
import {
  writeConsentGrant,
  setMailConnectionConsent,
  getMailConnectionWithConsent,
} from "../../db/consent";

/**
 * POST /api/mail-connections/consent
 *
 * Erteilt Art. 9-Einwilligung für eine oder mehrere bestehende MailConnections.
 * Schreibt pro Connection:
 *   1. Eintrag in consent_logs (append-only Beweislog, Art. 7 Abs. 1 DSGVO)
 *   2. consent_at + consent_version + consent_ip_address auf mail_connections
 *
 * Body: { mailConnectionId: string | string[], consentVersion: string }
 *
 * Response:
 *   200: { success: true, consentAt: ISO-string, updated: number }
 *   400: { error: 'invalid_body' }
 *   404: { error: 'connection_not_found' }   — wenn eine ID nicht zum User gehört
 *   409: { error: 'consent_version_mismatch', expected: string }
 */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);

  const body = await readBody(event).catch(() => null);
  const rawId = body?.mailConnectionId as string | string[] | undefined;
  const consentVersion = body?.consentVersion as string | undefined;

  if (!rawId || !consentVersion) {
    throw createError({
      statusCode: 400,
      data: { error: "invalid_body" },
    });
  }

  // Nur die aktuelle Version ist akzeptabel.
  if (consentVersion !== CURRENT_ART9_MAIL_VERSION) {
    throw createError({
      statusCode: 409,
      data: {
        error: "consent_version_mismatch",
        expected: CURRENT_ART9_MAIL_VERSION,
        received: consentVersion,
      },
    });
  }

  // Normalisieren auf Array — erlaubt single-string und bulk-array
  const ids = Array.isArray(rawId) ? rawId : [rawId];

  if (ids.length === 0) {
    throw createError({
      statusCode: 400,
      data: { error: "invalid_body" },
    });
  }

  const now = new Date();
  const ipAddress =
    getHeader(event, "x-forwarded-for")?.split(",")[0]?.trim() ??
    getHeader(event, "x-real-ip") ??
    null;
  const userAgent = getHeader(event, "user-agent") ?? null;

  // Alle Connections validieren (müssen dem User gehören) — dann in Serie verarbeiten.
  // Serie statt Promise.all: vermeidet Race-Conditions auf consent_logs primary key.
  for (const mailConnectionId of ids) {
    const connection = await getMailConnectionWithConsent(
      mailConnectionId,
      user.id,
    );
    if (!connection) {
      throw createError({
        statusCode: 404,
        data: { error: "connection_not_found", mailConnectionId },
      });
    }

    // 1. Append-only Audit-Log
    await writeConsentGrant({
      userId: user.id,
      consentType: "art9-mail",
      consentVersion,
      consentAt: now,
      ipAddress,
      userAgent,
      mailConnectionId,
    });

    // 2. MailConnection-Row updaten
    await setMailConnectionConsent({
      connectionId: mailConnectionId,
      userId: user.id,
      consentAt: now,
      consentVersion,
      consentIpAddress: ipAddress,
    });
  }

  return { success: true, consentAt: now.toISOString(), updated: ids.length };
});
