/* =====================================================================
   POST /api/orders — legt eine echte Bestellung in D1 an (orders + order_items).

   Wird vom Checkout aufgerufen (siehe src/pages/checkout/index.astro), sobald jemand die
   Bestellung abschickt. BEWUSST nicht dauerhaft hinter dem Zugangscode-Gate (siehe
   functions/_middleware.js) — sobald der Shop öffentlich ist (SITE_PUBLIC=true), müssen auch
   echte Kund:innen hier bestellen können, genau wie sie den Checkout selbst erreichen können.
   Vor dem Live-Gang ist ohnehin die ganze Seite inkl. Checkout hinter dem Gate, d.h. nur
   qciga/VanVan können bis hierhin überhaupt kommen.

   In Phase 1 gibt es kein echtes Zahlungs-Backend — jede vollständig abgeschickte Bestellung
   gilt sofort als "bezahlt" (siehe scripts/account.ts, derselbe Grundsatz). ===================================================================== */

import { json } from "../_shared/http.js";
import { sendeEmail, escapeHtmlFuerEmail } from "../_shared/email.js";
// Gleiche Gutschein-Daten wie im Frontend (src/data/gutscheine.ts) — hier server-seitig erneut
// eingebunden, um das "nur einmal pro Person"-Flag unabhängig vom Browser durchzusetzen (siehe
// unten). Bewusst derselbe JSON-Rohdaten-Import, keine Code-Duplizierung der Inhalte.
// @ts-ignore
import gutscheineRaw from "../../src/content/gutscheine.json";

const ERLAUBTE_LAENDER = ["de", "at", "ch", "lu"];
const gutscheine = (gutscheineRaw && gutscheineRaw.codes) || [];
// VanVans Wunsch-Adresse für Bestellbenachrichtigungen (siehe Anfrage vom 03.08.2026). Fest
// hinterlegt statt als Secret, da es keine geheime Information ist (nur ein Empfänger).
const BENACHRICHTIGUNGS_EMAIL = "vansdiyundbastelbedarf@gmail.com";

const LAND_NAME = { de: "Deutschland", at: "Österreich", ch: "Schweiz", lu: "Luxemburg" };

function formatPreis(n) {
  return `${Number(n).toFixed(2).replace(".", ",")} €`;
}

/** Baut die interne "neue Bestellung eingegangen"-E-Mail an VanVan/qciga — bewusst schlicht
 *  gehalten (kein Marketing-Layout nötig, nur die wichtigsten Infos auf einen Blick + Link zur
 *  Verwaltung). */
function bestellBenachrichtigungHtml({ bestellnummer, name, email, land, artikel, summe }) {
  const artikelZeilen = artikel
    .map((a) => `<li>${a.menge}× ${escapeHtmlFuerEmail(a.name)} — ${formatPreis(a.preis * a.menge)}</li>`)
    .join("");
  return `
    <div style="font-family: sans-serif; color: #1a1a1a; line-height: 1.6;">
      <h2 style="margin: 0 0 0.5em;">🩵 Neue Bestellung ${escapeHtmlFuerEmail(bestellnummer)}</h2>
      <p><strong>Von:</strong> ${escapeHtmlFuerEmail(name)} (${escapeHtmlFuerEmail(email)})<br />
         <strong>Land:</strong> ${escapeHtmlFuerEmail(LAND_NAME[land] || land)}</p>
      <p><strong>Artikel:</strong></p>
      <ul>${artikelZeilen}</ul>
      <p><strong>Summe: ${formatPreis(summe)}</strong></p>
      <p><a href="https://vans-diy-bastelbedarf.pages.dev/verwaltung/">→ Zur Bestellverwaltung</a></p>
    </div>
  `;
}

function findeGutschein(code) {
  const normalisiert = String(code || "").trim().toUpperCase();
  if (!normalisiert) return null;
  return gutscheine.find((g) => String(g.code || "").toUpperCase() === normalisiert) || null;
}

export async function onRequestPost(context) {
  const { request, env } = context;

  if (!env.DB) {
    return json(500, { ok: false, error: "Datenbank nicht verbunden." });
  }

  let body;
  try {
    body = await request.json();
  } catch {
    return json(400, { ok: false, error: "Ungültige Anfrage." });
  }

  // ── Validierung: lieber eine klare Fehlermeldung im Checkout als eine kaputte/leere
  //    Bestellung in der Datenbank. ──
  const land = String(body.land || "").toLowerCase();
  if (!ERLAUBTE_LAENDER.includes(land)) {
    return json(400, { ok: false, error: "Ungültiges Land." });
  }

  const kunde = body.kunde && typeof body.kunde === "object" ? body.kunde : {};
  const name = String(kunde.name || "").trim();
  const email = String(kunde.email || "").trim();
  if (!name || !email || !email.includes("@")) {
    return json(400, { ok: false, error: "Ungültige Kundendaten." });
  }

  const artikel = Array.isArray(body.artikel) ? body.artikel : [];
  if (artikel.length === 0) {
    return json(400, { ok: false, error: "Die Bestellung enthält keine Artikel." });
  }
  for (const a of artikel) {
    if (!a || typeof a.slug !== "string" || !a.slug.trim() || typeof a.name !== "string" || !a.name.trim()) {
      return json(400, { ok: false, error: "Ungültige Artikeldaten." });
    }
    if (!Number.isFinite(a.menge) || a.menge <= 0) {
      return json(400, { ok: false, error: "Ungültige Artikelmenge." });
    }
    if (!Number.isFinite(a.preis) || a.preis < 0) {
      return json(400, { ok: false, error: "Ungültiger Artikelpreis." });
    }
  }

  const summe = Number(body.summe);
  if (!Number.isFinite(summe) || summe < 0) {
    return json(400, { ok: false, error: "Ungültige Bestellsumme." });
  }
  const zwischensumme = Number.isFinite(Number(body.zwischensumme)) ? Number(body.zwischensumme) : 0;
  const versandkosten = Number.isFinite(Number(body.versandkosten)) ? Number(body.versandkosten) : 0;
  const rabattGesamt = Number.isFinite(Number(body.rabattGesamt)) ? Number(body.rabattGesamt) : 0;

  // ── "Nur einmal pro Person" durchsetzen — unabhängig vom Browser/Gerät, da hier gegen die
  //    echten, gespeicherten Bestellungen geprüft wird (siehe d1/schema.sql, Spalte
  //    "gutschein_code"). Stornierte Bestellungen zählen NICHT als "schon benutzt" — wurde ja
  //    letztlich nicht wirksam eingelöst. ──
  const gutscheinCodeRoh = typeof body.gutscheinCode === "string" ? body.gutscheinCode.trim() : "";
  let gutscheinCodeNormalisiert = null;
  if (gutscheinCodeRoh) {
    const gutschein = findeGutschein(gutscheinCodeRoh);
    gutscheinCodeNormalisiert = gutscheinCodeRoh.toUpperCase();
    if (gutschein && gutschein.einmaligProPerson) {
      const { results } = await env.DB.prepare(
        `SELECT COUNT(*) as anzahl FROM orders WHERE gutschein_code = ? AND LOWER(kunde_email) = LOWER(?) AND status != 'storniert'`
      )
        .bind(gutscheinCodeNormalisiert, email)
        .all();
      if ((results?.[0]?.anzahl ?? 0) > 0) {
        return json(400, {
          ok: false,
          error: "Dieser Gutscheincode wurde bereits mit dieser E-Mail-Adresse eingelöst und gilt nur einmal pro Person.",
        });
      }
    }
  }

  const now = new Date().toISOString();

  try {
    const insertOrder = await env.DB.prepare(
      `INSERT INTO orders
         (created_at, updated_at, status, kunde_name, kunde_email, land, strasse, plz, ort,
          zahlungsart, zwischensumme, versandkosten, rabatt_gesamt, summe,
          treuebonus_verwendet, abo_rabatt_verwendet, gutschein_code)
       VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
    )
      .bind(
        now,
        now,
        "bezahlt",
        name,
        email,
        land,
        String(kunde.strasse || ""),
        String(kunde.plz || ""),
        String(kunde.ort || ""),
        String(body.zahlungsart || ""),
        zwischensumme,
        versandkosten,
        rabattGesamt,
        summe,
        body.treuebonusVerwendet ? 1 : 0,
        body.aboRabattVerwendet ? 1 : 0,
        gutscheinCodeNormalisiert
      )
      .run();

    const orderId = insertOrder.meta.last_row_id;
    // Menschenlesbare Bestellnummer wird ERST NACH dem Insert aus der autoinkrementierten,
    // garantiert eindeutigen ID abgeleitet — keine Race Condition bei zwei gleichzeitigen
    // Bestellungen (anders als z.B. "COUNT(*) + 1" vorher zu berechnen).
    const jahr = new Date().getFullYear();
    const bestellnummer = `VDB-${jahr}-${String(orderId).padStart(4, "0")}`;
    await env.DB.prepare(`UPDATE orders SET bestellnummer = ? WHERE id = ?`).bind(bestellnummer, orderId).run();

    const itemStmts = artikel.map((a) =>
      env.DB.prepare(
        `INSERT INTO order_items (order_id, produkt_slug, name, kategorie_slug, menge, preis, gratis)
         VALUES (?,?,?,?,?,?,?)`
      ).bind(orderId, a.slug, a.name, a.kategorie || null, Math.round(a.menge), a.preis, a.gratis ? 1 : 0)
    );
    await env.DB.batch(itemStmts);

    // E-Mail-Benachrichtigung an VanVan/qciga — bewusst NICHT abgewartet (context.waitUntil
    // lässt den Versand im Hintergrund fertig laufen, ohne die Antwort an die Kundschaft zu
    // verzögern) und bewusst NICHT fehlerkritisch: schlägt der Versand fehl (z.B. weil noch kein
    // RESEND_API_KEY hinterlegt ist), bleibt die Bestellung trotzdem ganz normal gespeichert und
    // in /verwaltung/ sichtbar — nur die Benachrichtigung fehlt dann eben.
    context.waitUntil(
      sendeEmail(env, {
        to: BENACHRICHTIGUNGS_EMAIL,
        subject: `🩵 Neue Bestellung ${bestellnummer}`,
        html: bestellBenachrichtigungHtml({ bestellnummer, name, email, land, artikel, summe }),
        text: `Neue Bestellung ${bestellnummer} von ${name} (${email}), ${artikel.length} Artikel, Summe ${formatPreis(summe)}. Details: https://vans-diy-bastelbedarf.pages.dev/verwaltung/`,
      })
    );

    return json(201, { ok: true, id: orderId, bestellnummer });
  } catch (err) {
    return json(500, { ok: false, error: "Bestellung konnte nicht gespeichert werden." });
  }
}
