import { NextRequest, NextResponse } from "next/server"; import { createServiceClient } from "@/lib/supabase"; import { verifyActionToken } from "@/lib/admin-auth"; import { markActionTokenUsed } from "@/lib/token-blacklist"; import { sendeKundenStatusEmail, getKalenderTage } from "@/lib/mailer"; // Verfügbarkeit aktualisieren wenn Status sich ändert async function aktualisiereVerfuegbarkeit( db: ReturnType, anfrageId: string, neuerStatus: string ) { if (neuerStatus === "bestaetigt") { await db .from("verfuegbarkeit") .update({ status: "belegt" }) .eq("anfrage_id", anfrageId); } else if (neuerStatus === "abgelehnt") { await db .from("verfuegbarkeit") .delete() .eq("anfrage_id", anfrageId); } } export async function GET(req: NextRequest) { const token = req.nextUrl.searchParams.get("token"); if (!token) { return NextResponse.json( { error: "Token erforderlich" }, { status: 400 } ); } // Token validieren const actionToken = await verifyActionToken(token); if (!actionToken) { return NextResponse.json( { error: "Token ungültig oder abgelaufen" }, { status: 400 } ); } const { anfrageId, status } = actionToken; const appUrl = process.env.APP_URL ?? "https://www.mietparkhahn.de"; const ipAddr = req.headers.get("x-forwarded-for") || req.headers.get("x-real-ip") || "unknown"; // ✅ Token als verwendet markieren (One-Time-Use) const [, tokenSig] = token.split("."); await markActionTokenUsed(tokenSig, anfrageId, status, ipAddr); try { const db = createServiceClient(); // Aktuellen Status laden (vor dem Update) für Audit Log const { data: currentData } = await db .from("anfragen") .select("status") .eq("id", anfrageId) .single(); const alterStatus = currentData?.status || null; // Status aktualisieren const { error } = await db .from("anfragen") .update({ status }) .eq("id", anfrageId); if (error) { console.error(`[Action] Fehler beim Update von Anfrage ${anfrageId}:`, error); return NextResponse.json( { error: "Statusaktualisierung fehlgeschlagen" }, { status: 500 } ); } // Status-Änderung ins Audit Log schreiben if (alterStatus !== status) { const { error: auditError } = await db .from("anfrage_status_audit") .insert({ anfrage_id: anfrageId, status_von: alterStatus, status_zu: status, bearbeitet_von: "action-link", notizen: null, }); if (auditError) { console.error(`[Action] Fehler beim Schreiben des Status-Audit-Logs für Anfrage ${anfrageId}:`, auditError); } } // Verfügbarkeit aktualisieren await aktualisiereVerfuegbarkeit(db, anfrageId, status); // Anfrage-Daten + Positionen für E-Mail laden const { data: anfrage } = await db .from("anfragen") .select("firma, email, notizen") .eq("id", anfrageId) .single(); if (anfrage?.email) { let positionen: any[] = []; // Positionen laden const { data: posData, error: posError } = await db .from("anfragen_positionen") .select("*") .eq("anfrage_id", anfrageId) .order("mietbeginn"); if (posError) { console.error( `[Action] Fehler beim Laden von Positionen für Anfrage ${anfrageId}:`, posError ); } // Positionen formatieren für Email-Template positionen = (posData ?? []).map((p: any) => ({ maschineName: p.maschine_name || "Unbekannte Maschine", mietbeginn: p.mietbeginn, mietende: p.mietende, gesamtTage: p.gesamt_tage || getKalenderTage(p.mietbeginn, p.mietende), lieferung: p.lieferung || false, lieferadresse: p.lieferadresse || "", anmerkung: p.anmerkung || "", tagessatz: p.tagessatz, preisStufe: null, zubehoer: [], })); console.log( `[Action] Anfrage ${anfrageId}: ${positionen.length} Positionen geladen` ); // Kunden-Status-Email versenden sendeKundenStatusEmail({ anfrageId, firma: anfrage.firma, email: anfrage.email, neuerStatus: status as "bestaetigt" | "abgelehnt" | "abgeschlossen", notizen: anfrage.notizen || undefined, positionen: positionen.length > 0 ? positionen : undefined, }).catch((err) => console.error("[Action] Fehler beim Versand der Status-Email:", err) ); } // Redirect zum Admin-Panel mit Success-Indicator return NextResponse.redirect( `${appUrl}/admin/anfragen/${anfrageId}?action=done` ); } catch (err) { console.error("[Action] Unerwarteter Fehler:", err); return NextResponse.json( { error: "Ein Fehler ist aufgetreten" }, { status: 500 } ); } }