/* =====================================================================
   lib/ticketanizer.js — Bewerbungen als echtes Ticket bei Ticketanizer
   eröffnen (dort in Discord sichtbar, pro Bewerbungsbereich ein eigenes
   Panel/Board).

   API-Doku (aus dem Ticketanizer-Dashboard, "API & Webhooks" → "API-Keys" →
   "So nutzt du sie"):
     Basis-URL: https://api.ticketanizer.com
     POST /v1/tickets
       Header: X-API-Key, Content-Type: application/json
       Body:   { panel_id, visitor_name, first_message }

   Wir nutzen hier bewusst NUR den ersten Schritt (Ticket eröffnen) — es
   ist eine einmalige Bewerbung, kein Live-Chat, deshalb kein Nachladen
   von Staff-Antworten nötig (das würde einen dauerhaft laufenden Prozess
   brauchen, den ein Cloudflare Worker so nicht hat).

   panel_id pro Bewerbungsbereich (aus dem Ticketanizer-Dashboard →
   "Panels", von Dogi am 2026-08-01 abgelesen):
     4 = Modi-Bewerbung
     5 = Kooperationsbewerbung
     6 = Scout-Bewerbung
     7 = Manager-Bewerbung (= unsere "Creator"-Bewerbung: Streamer sucht
         einen Manager bei Spicy Media)

   Rein informativ, kein Ausfallpunkt: Fehlt der API-Key, oder schlägt der
   Versand fehl (Ticketanizer down, falscher Key, ...), wird die Bewerbung
   trotzdem ganz normal in der eigenen Datenbank gespeichert.

   Automatische Wiederholung bei Rate-Limit (HTTP 429): Wenn mehrere
   Menschen kurz hintereinander ein Formular abschicken, kann Ticketanizer
   kurzzeitig 429 antworten (selbst erlebt beim Testen). In dem Fall wird
   der Versand automatisch bis zu 2x mit kurzer Pause wiederholt (siehe
   ticketAnfrageSenden), bevor endgültig aufgegeben wird — läuft komplett
   im Hintergrund über ctx.waitUntil, blockiert also nie die Antwort an
   die Bewerberin/den Bewerber.
   ===================================================================== */

const TICKETANIZER_BASIS_URL = "https://api.ticketanizer.com";

const PANEL_IDS = {
  modi: 4,
  kooperation: 5,
  scout: 6,
  creator: 7, // "Manager-Bewerbung" bei Ticketanizer
};

// Menschlich lesbare Feldbeschriftungen für alle Formularfelder, die aktuell
// auf der Website vorkommen (siehe bewerben-*.html, jeweils name="...").
// Unbekannte Feldnamen (z.B. nach künftigen Formular-Änderungen) werden
// einfach unverändert als Beschriftung übernommen statt zu fehlen.
const FIELD_LABELS = {
  name: "Name",
  email: "E-Mail",
  kontakt: "Kontakt (Discord/TikTok)",
  erfahrung: "Erfahrung",
  verfuegbarkeit: "Verfügbarkeit",
  warum: "Warum möchtest du dabei sein?",
  platform: "Plattform",
  content: "Content-Art",
  firma: "Firma / Projekt",
  idee: "Idee / Anliegen",
};

function ersteNachrichtAufbauen(type, data) {
  const zeilen = Object.entries(data || {})
    .filter(([, v]) => String(v ?? "").trim() !== "")
    .map(([key, value]) => `**${FIELD_LABELS[key] || key}:** ${String(value).trim()}`);

  if (!zeilen.length) zeilen.push("_Keine weiteren Angaben übermittelt._");

  // Ticketanizer-Nachrichten sind vermutlich nicht beliebig lang — sicherheitshalber
  // deckeln, damit ein sehr langer Freitext (z.B. "warum") den Versand nicht sprengt.
  const text = zeilen.join("\n");
  return text.length > 3500 ? text.slice(0, 3500) + "…" : text;
}

const warten = (ms) => new Promise((fertig) => setTimeout(fertig, ms));

// Wenn viele Menschen kurz hintereinander ein Formular abschicken (z.B. weil
// Dogi gerade live "bewerbt euch jetzt!" sagt), kann Ticketanizer mit
// HTTP 429 ("zu viele Anfragen") antworten. Die Bewerbung selbst ist davon
// nie betroffen (steht schon sicher in unserer DB) — hier wird nur der
// Ticket-Versand selbst automatisch 1–2x mit kurzer Pause wiederholt,
// bevor endgültig aufgegeben wird. Nutzt Retry-After, falls Ticketanizer
// das mitschickt, sonst eine feste, ansteigende Wartezeit.
const MAX_VERSUCHE = 3;
const STANDARD_WARTEZEITEN_MS = [2000, 5000];

async function ticketAnfrageSenden(apiKey, panelId, visitorName, firstMessage) {
  for (let versuch = 1; versuch <= MAX_VERSUCHE; versuch++) {
    const antwort = await fetch(`${TICKETANIZER_BASIS_URL}/v1/tickets`, {
      method: "POST",
      headers: {
        "X-API-Key": apiKey,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        panel_id: panelId,
        visitor_name: visitorName,
        first_message: firstMessage,
      }),
    });

    if (antwort.status !== 429 || versuch === MAX_VERSUCHE) {
      return antwort;
    }

    const retryAfterHeader = Number(antwort.headers.get("Retry-After"));
    const wartezeit = Number.isFinite(retryAfterHeader) && retryAfterHeader > 0
      ? retryAfterHeader * 1000
      : STANDARD_WARTEZEITEN_MS[versuch - 1] || 5000;

    console.log(`[ticketanizer] Rate-Limit (Versuch ${versuch}/${MAX_VERSUCHE}) — warte ${wartezeit}ms und versuche es erneut.`);
    await warten(wartezeit);
  }
}

export async function bewerbungAlsTicketAnlegen(env, type, data) {
  const apiKey = env.TICKETANIZER_API_KEY;
  const panelId = PANEL_IDS[type];
  if (!apiKey) {
    console.error(`[ticketanizer] TICKETANIZER_API_KEY fehlt — Ticket für "${type}" übersprungen.`);
    return;
  }
  if (!panelId) {
    console.error(`[ticketanizer] Kein panel_id für Bewerbungstyp "${type}" hinterlegt — übersprungen.`);
    return;
  }

  const visitorName = String(data?.name || data?.firma || "Unbekannt").trim().slice(0, 80) || "Unbekannt";
  const firstMessage = ersteNachrichtAufbauen(type, data);

  try {
    const antwort = await ticketAnfrageSenden(apiKey, panelId, visitorName, firstMessage);
    const antwortText = await antwort.text().catch(() => "");
    if (!antwort.ok) {
      console.error(`[ticketanizer] Fehler beim Ticket-Anlegen (${type}, panel ${panelId}): HTTP ${antwort.status} — ${antwortText}`);
    } else {
      console.log(`[ticketanizer] Ticket angelegt (${type}, panel ${panelId}): ${antwortText}`);
    }
  } catch (fehler) {
    // Ticketanizer nicht erreichbar o.ä. — die Bewerbung selbst ist trotzdem
    // sicher in der eigenen Datenbank gelandet, das darf hier nicht scheitern.
    console.error(`[ticketanizer] Ausnahme beim Ticket-Anlegen (${type}, panel ${panelId}):`, fehler && fehler.message);
  }
}
