<?php
declare(strict_types=1);

require_once __DIR__ . '/../../../../includes/bootstrap.php';
require_login();

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('X-Content-Type-Options: nosniff');

function rz_json(array $payload, int $status = 200): never
{
    http_response_code($status);
    echo json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    exit;
}

function rz_absolute_url(string $relative): string
{
    if (preg_match('~^https?://~i', $relative)) {
        return $relative;
    }

    $https = !empty($_SERVER['HTTPS']) && strtolower((string)$_SERVER['HTTPS']) !== 'off';
    $scheme = $https ? 'https' : 'http';
    $host = (string)($_SERVER['HTTP_HOST'] ?? '');
    if ($host === '') {
        throw new RuntimeException('Unable to determine the RoomZ host name.');
    }

    $baseDir = rtrim(str_replace('\\', '/', dirname(dirname((string)($_SERVER['SCRIPT_NAME'] ?? '/')))), '/');
    return $scheme . '://' . $host . $baseDir . '/' . ltrim($relative, '/');
}

function rz_fetch_authenticated_pdf(string $url): string
{
    if (!function_exists('curl_init')) {
        throw new RuntimeException('PHP cURL is required.');
    }

    $cookies = [];
    foreach ($_COOKIE as $name => $value) {
        $cookies[] = rawurlencode((string)$name) . '=' . rawurlencode((string)$value);
    }

    /*
     * Avoid a deadlock: the internal PDF request needs the same PHP session.
     * Release the current session lock while cURL retrieves the document.
     */
    $restartSession = false;
    if (session_status() === PHP_SESSION_ACTIVE) {
        session_write_close();
        $restartSession = true;
    }

    try {
        $ch = curl_init($url);
        if ($ch === false) {
            throw new RuntimeException('Could not initialise the PDF request.');
        }

        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 3,
            CURLOPT_CONNECTTIMEOUT => 15,
            CURLOPT_TIMEOUT => 90,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_HTTPHEADER => [
                'Accept: application/pdf',
                'User-Agent: RoomZ-Outlook-Addin/1.0',
                'Cookie: ' . implode('; ', $cookies),
            ],
        ]);

        $body = curl_exec($ch);
        $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $type = strtolower((string)curl_getinfo($ch, CURLINFO_CONTENT_TYPE));
        $error = curl_error($ch);
        curl_close($ch);

        if ($body === false || $error !== '') {
            throw new RuntimeException('PDF generation request failed: ' . $error);
        }
        if ($status < 200 || $status >= 300) {
            throw new RuntimeException('The PDF generator returned HTTP ' . $status . '.');
        }
        if (strncmp((string)$body, '%PDF-', 5) !== 0 && strpos($type, 'application/pdf') === false) {
            $preview = trim(strip_tags(substr((string)$body, 0, 220)));
            throw new RuntimeException('The generator did not return a valid PDF.'
                . ($preview !== '' ? ' Response: ' . $preview : ''));
        }

        return (string)$body;
    } finally {
        if ($restartSession && session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }
}

try {
    $input = [];
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $decoded = json_decode((string)file_get_contents('php://input'), true);
        $input = is_array($decoded) ? $decoded : [];
    }

    $action = strtolower(trim((string)($_GET['action'] ?? $input['action'] ?? 'lookup')));
    $orderId = (int)($_GET['order_id'] ?? $input['order_id'] ?? 0);

    if ($orderId <= 0) {
        rz_json(['ok' => false, 'message' => 'A valid booking ID is required.'], 422);
    }

    $stmt = $pdo->prepare("
        SELECT
            o.id,
            o.order_no,
            o.check_in,
            o.check_out,
            TRIM(CONCAT(COALESCE(g.firstname,''), ' ', COALESCE(g.lastname,''))) AS guest_name,
            TRIM(CONCAT(COALESCE(a.firstname,''), ' ', COALESCE(a.lastname,''))) AS agent_name
        FROM orders o
        LEFT JOIN guests g ON g.id = o.guest_id
        LEFT JOIN agents a ON a.id = o.agent_id
        WHERE o.id = :id
        LIMIT 1
    ");
    $stmt->execute([':id' => $orderId]);
    $booking = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$booking) {
        rz_json(['ok' => false, 'message' => 'Booking not found.'], 404);
    }

    if ($action === 'lookup') {
        rz_json(['ok' => true, 'booking' => $booking]);
    }

    if ($action !== 'document') {
        rz_json(['ok' => false, 'message' => 'Unsupported action.'], 400);
    }

    $type = strtolower(trim((string)($input['document_type'] ?? 'standard')));
    $documents = [
        'standard' => [
            'file' => '../proforma_invoice.php',
            'prefix' => 'Proforma',
        ],
    ];

    if (!isset($documents[$type])) {
        rz_json(['ok' => false, 'message' => 'Unsupported document type.'], 422);
    }

    $pdfUrl = rz_absolute_url(
        $documents[$type]['file'] . '?order_id=' . rawurlencode((string)$orderId)
    );
    $pdfBytes = rz_fetch_authenticated_pdf($pdfUrl);

    /*
     * Outlook attachment APIs have size limits. Keep a conservative 3 MB
     * limit for compatibility with Base64 attachment support.
     */
    if (strlen($pdfBytes) > 3 * 1024 * 1024) {
        rz_json([
            'ok' => false,
            'message' => 'This PDF is larger than 3 MB and cannot be attached by this add-in.',
        ], 413);
    }

    $safeOrderNo = preg_replace('/[^A-Za-z0-9_-]+/', '_', (string)($booking['order_no'] ?: $orderId));
    $filename = $documents[$type]['prefix'] . '_' . $safeOrderNo . '.pdf';

    rz_json([
        'ok' => true,
        'filename' => $filename,
        'mime_type' => 'application/pdf',
        'base64' => base64_encode($pdfBytes),
    ]);
} catch (Throwable $e) {
    error_log('RoomZ Outlook add-in error: ' . $e->getMessage());
    rz_json([
        'ok' => false,
        'message' => $e->getMessage(),
    ], 500);
}
