<?php
require_once __DIR__ . '/bootstrap_api.php';

try {
    api_install_schema($pdo);

    $input = api_input();

    /*
     * Accept both names because the original add-in sends "token" while
     * the newer task pane sends "code".
     */
    $plainToken = strtoupper(trim((string)(
        $input['token']
        ?? $input['code']
        ?? ''
    )));

    $plainToken = preg_replace('/[^A-Z0-9]/', '', $plainToken);

    if ($plainToken === '') {
        api_json([
            'ok' => false,
            'message' => 'Enter the one-time code shown in RoomZ.',
        ], 422);
    }

    if (!$pdo->inTransaction()) {
        $pdo->beginTransaction();
    }

    $stmt = $pdo->prepare("
        SELECT *
        FROM communication_outlook_tokens
        WHERE token_hash = :token_hash
          AND used_at IS NULL
          AND expires_at > NOW()
        LIMIT 1
        FOR UPDATE
    ");
    $stmt->execute([
        ':token_hash' => comm_hash_token($plainToken),
    ]);

    $handoff = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$handoff) {
        $pdo->rollBack();

        api_json([
            'ok' => false,
            'message' => 'This RoomZ code is invalid, expired, or already used. Prepare a new Outlook Reply code in RoomZ.',
        ], 401);
    }

    $booking = comm_booking($pdo, (int)$handoff['order_id']);

    $sessionToken = comm_random_token();

    $stmt = $pdo->prepare("
        INSERT INTO communication_addin_sessions
        (
            session_hash,
            user_id,
            order_id,
            expires_at
        )
        VALUES
        (
            :session_hash,
            :user_id,
            :order_id,
            DATE_ADD(NOW(), INTERVAL 30 MINUTE)
        )
    ");
    $stmt->execute([
        ':session_hash' => comm_hash_token($sessionToken),
        ':user_id'      => (int)$handoff['user_id'],
        ':order_id'     => (int)$handoff['order_id'],
    ]);

    $pdo->prepare("
        UPDATE communication_outlook_tokens
        SET used_at = NOW()
        WHERE id = :id
    ")->execute([
        ':id' => (int)$handoff['id'],
    ]);

    $pdo->commit();

    api_json([
        'ok'            => true,
        'session_token' => $sessionToken,
        'booking'       => $booking,
    ]);
} catch (Throwable $exception) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    error_log(
        'RoomZ Outlook token exchange error: ' .
        $exception->getMessage() .
        ' in ' . $exception->getFile() .
        ':' . $exception->getLine()
    );

    api_json([
        'ok' => false,
        'message' => 'Could not load the prepared booking: ' . $exception->getMessage(),
    ], 500);
}
