<?php
/**
 * PandaDoc + Shopify order-signing integration bootstrap.
 *
 * - Loads the existing project config (PDO + Shopify token constants).
 * - Provides shared helpers for JSON responses, config/env, and logging.
 */
declare(strict_types=1);
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
ini_set('display_errors', '0');

header('Content-Type: application/json');

// Try to load the existing project config (provides $pdo and Shopify constants)
$projectConfig = dirname(__DIR__) . '/admin/config.php';
if (is_file($projectConfig)) {
    require_once $projectConfig;
}

function pd_env(string $key, ?string $default = null): ?string {
    $v = getenv($key);
    if ($v !== false) {
        $v = trim((string)$v);
        if ($v !== '') return $v;
    }
    // Allow config.php constants as fallback so users can paste keys in one file.
    if (defined($key)) {
        $c = trim((string)constant($key));
        if ($c !== '') return $c;
    }
    return $default;
}

function pd_json(int $statusCode, array $payload): void {
    http_response_code($statusCode);
    echo json_encode($payload);
    exit;
}

function pd_raw_body(): string {
    $raw = file_get_contents('php://input');
    return is_string($raw) ? $raw : '';
}

function pd_json_body(): array {
    $raw = pd_raw_body();
    if ($raw === '') return [];
    $ct = (string)($_SERVER['CONTENT_TYPE'] ?? '');
    if (stripos($ct, 'application/json') === false) return [];
    $decoded = json_decode($raw, true);
    return is_array($decoded) ? $decoded : [];
}

function pd_log(string $message, array $context = []): void {
    $line = '[' . date('c') . '] ' . $message;
    if (!empty($context)) {
        $json = @json_encode($context, JSON_UNESCAPED_UNICODE);
        if (is_string($json) && $json !== '') {
            $line .= ' ' . $json;
        } else {
            $line .= ' (context encode failed)';
        }
    }
    $defaultLog = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'pandadoc_integration.log';
    $logFile = pd_env('PANDADOC_INTEGRATION_LOG', $defaultLog);
    if ($logFile === null || $logFile === '') {
        $logFile = $defaultLog;
    }
    $logFile = trim($logFile);
    if ($logFile === '') {
        error_log('pd_log: ' . $line);
        return;
    }
    $dir = dirname($logFile);
    if (!is_dir($dir)) {
        @mkdir($dir, 0777, true);
    }
    $written = @file_put_contents($logFile, $line . PHP_EOL, FILE_APPEND);
    if ($written === false) {
        error_log('pd_log (file write failed for ' . $logFile . '): ' . $line);
    }
}

function pd_backoff_us(int $attempt): int {
    // attempt: 0,1,2,... -> 200ms, 500ms, 1000ms, 2000ms (cap)
    static $map = [200000, 500000, 1000000, 2000000];
    return $map[min($attempt, count($map) - 1)];
}

/**
 * Build a step identifier including caller file and line so DB/logs show exactly where execution reached.
 * Usage: pd_db_update_order($orderId, ['last_api_step' => pd_step_string('fetch_order')]);
 */
function pd_step_string(string $stepName): string {
    $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
    $caller = $bt[1] ?? $bt[0];
    $file = isset($caller['file']) ? basename($caller['file']) : '';
    $line = $caller['line'] ?? 0;
    return $file ? "{$file}:{$line}:{$stepName}" : $stepName;
}

