<?php
declare(strict_types=1);

/**
 * POST /c2c/payments/create-order.php
 *
 * Erstellt eine PayPal Order und legt einen pending-Eintrag in `payments` an.
 *
 * Robust gegenüber Teilfehlern:
 *   - Alle DB-Schreibzugriffe in einer Transaktion
 *   - Wenn DB-Insert nach erfolgreicher PayPal-Order-Erstellung scheitert:
 *     ROLLBACK + Log mit der orphaned Order-ID. Die Order verfällt bei
 *     PayPal automatisch nach 3 Stunden, kein manueller Cleanup nötig.
 *
 * Request (JSON):
 *   {
 *     "client_uuid":  "uuid-des-klienten",
 *     "service_type": "portfolio" | "family"
 *   }
 *
 * Response (JSON):
 *   { "order_id": "5O190127TN364715T", "payment_id": 42 }
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: https://come2canada.life');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-C2C-Token');
header('Vary: Origin');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

require_once __DIR__ . '/paypal-client.php';
$config = require __DIR__ . '/_config.php';

$pdo = null;
$paypalOrderId = null;

try {
    $body        = json_decode(file_get_contents('php://input'), true) ?: [];
    $clientUuid  = (string)($body['client_uuid']  ?? '');
    $serviceType = (string)($body['service_type'] ?? '');

    if (!preg_match('/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', $clientUuid)) {
        throw new InvalidArgumentException('Ungültige client_uuid');
    }

    if (!in_array($serviceType, ['portfolio', 'family'], true)) {
        throw new InvalidArgumentException('service_type muss "portfolio" oder "family" sein');
    }

    $amount = $config['pricing'][$serviceType] ?? 0;
    if ($amount <= 0) {
        throw new RuntimeException('Preis nicht konfiguriert für ' . $serviceType);
    }

    $pdo = new PDO(
        "mysql:host={$config['db']['host']};dbname={$config['db']['name']};charset=utf8mb4",
        $config['db']['user'],
        $config['db']['password'],
        [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );

    // Klienten finden — vor PayPal-Call, damit wir keine Order erstellen
    // ohne gültigen Kontext
    $stmt = $pdo->prepare('SELECT id, vorname, nachname, email, status FROM clients WHERE uuid = ? LIMIT 1');
    $stmt->execute([$clientUuid]);
    $client = $stmt->fetch();

    if (!$client) {
        http_response_code(404);
        echo json_encode(['error' => 'Klient nicht gefunden']);
        exit;
    }

    if (in_array($client['status'], ['paid', 'delivered'], true)) {
        http_response_code(409);
        echo json_encode(['error' => 'Es liegt bereits eine bezahlte Bestellung vor']);
        exit;
    }

    $clientId = (int)$client['id'];

    $description = $serviceType === 'portfolio'
        ? 'come2canada.life — Vollständiges Portfolio'
        : 'come2canada.life — Familien-Geschichte';

    // ---------- PayPal Order erstellen ----------
    // Passiert VOR der DB-Transaktion. Falls hier was schiefgeht,
    // ist nichts in der DB zu rollbacken.
    $sandbox = (bool)$config['paypal']['sandbox'];
    $paypal  = new PayPalClient(
        $sandbox ? $config['paypal']['sandbox_client_id']     : $config['paypal']['live_client_id'],
        $sandbox ? $config['paypal']['sandbox_client_secret'] : $config['paypal']['live_client_secret'],
        $sandbox
    );

    $customId = "client_{$clientId}_{$serviceType}_" . bin2hex(random_bytes(4));
    $order    = $paypal->createOrder((float)$amount, 'CHF', $description, $customId);

    if (empty($order['id'])) {
        throw new RuntimeException('PayPal Order ohne ID zurückgegeben');
    }

    $paypalOrderId = $order['id'];

    // ---------- DB-Transaktion ----------
    // Alle DB-Schreibzugriffe atomisch. Falls einer fehlschlägt:
    // ROLLBACK + die PayPal-Order verfällt nach 3h von selbst.
    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        'INSERT INTO payments
           (client_id, amount_chf, currency, service_type, method, status, paypal_order_id, raw_response, created_at)
         VALUES (?, ?, "CHF", ?, "paypal", "pending", ?, ?, NOW())'
    );
    $stmt->execute([
        $clientId,
        $amount,
        $serviceType,
        $paypalOrderId,
        json_encode($order, JSON_UNESCAPED_UNICODE),
    ]);

    $paymentId = (int)$pdo->lastInsertId();

    $pdo->prepare('INSERT INTO aktivitaeten (klient_id, aktion, beschreibung, erstellt_am) VALUES (?, ?, ?, NOW())')
        ->execute([
            $clientId,
            'paypal_order_erstellt',
            "Order {$paypalOrderId} · CHF " . number_format((float)$amount, 2) . " · {$serviceType}",
        ]);

    $pdo->commit();

    echo json_encode([
        'order_id'   => $paypalOrderId,
        'payment_id' => $paymentId,
    ]);

} catch (Throwable $e) {
    if ($pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    // Falls eine PayPal-Order schon erstellt war, aber die DB scheiterte:
    // im Log markieren, damit Christian sie kennt (verfällt sonst still).
    if ($paypalOrderId !== null) {
        error_log("[c2c create-order] ORPHANED PayPal Order $paypalOrderId — Klient-UUID $clientUuid — Fehler: " . $e->getMessage());
    } else {
        error_log('[c2c create-order] ' . $e->getMessage());
    }

    http_response_code(400);
    echo json_encode(['error' => $e->getMessage()]);
}
