<?php
declare(strict_types=1);

require_once __DIR__ . '/../pandadoc_integration/db.php';
require_once __DIR__ . '/../pandadoc_integration/pandadoc.php';
require_once __DIR__ . '/../pandadoc_integration/shopify.php';
require_once __DIR__ . '/../pandadoc_integration/hubspot_sync.php';
require_once __DIR__ . '/../pandadoc_integration/orchestrator.php';

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

// PandaDoc signature verification (accept signature from query param OR header so URL can be used without ?signature=).
// Webhook URL to enter in PandaDoc: https://vintage.espirevox.com/php/webhooks/pandadoc_status.php
$sharedKey = (string)pd_env('PANDADOC_WEBHOOK_SHARED_KEY', '');
$receivedSig = (string)($_GET['signature'] ?? $_SERVER['HTTP_X_PANDADOC_SIGNATURE'] ?? '');
$raw = pd_raw_body();
if ($sharedKey === '' || $receivedSig === '') {
    pd_json(403, ['success' => false, 'error' => 'Missing webhook verification']);
}
$expectedSig = hash_hmac('sha256', $raw, $sharedKey);
if (!hash_equals($expectedSig, $receivedSig)) {
    pd_log('PandaDoc webhook signature mismatch', ['expected' => $expectedSig, 'received' => $receivedSig]);
    pd_json(403, ['success' => false, 'error' => 'Invalid signature']);
}

$payload = json_decode($raw, true);
if (!is_array($payload)) {
    pd_json(200, ['success' => true, 'ignored' => true]);
}

pd_db_ensure_tables();

// Payload can be an array of events. We handle document_state_changed.
$events = isset($payload[0]) && is_array($payload[0]) ? $payload : [$payload];

$handled = [];
foreach ($events as $evt) {
    if (!is_array($evt)) continue;
    $eventName = (string)($evt['event'] ?? '');
    $data = $evt['data'] ?? null;
    if ($eventName === '' || !is_array($data)) continue;

    if ($eventName !== 'document_state_changed') continue;

    $docId = (string)($data['id'] ?? '');
    $status = (string)($data['status'] ?? '');
    if ($docId === '' || $status === '') continue;

    $row = pd_db_find_by_pandadoc_document($docId);
    if (!$row) {
        pd_log('PandaDoc webhook: document not mapped', ['docId' => $docId, 'status' => $status]);
        $handled[] = ['docId' => $docId, 'status' => $status, 'mapped' => false];
        continue;
    }

    $entityType = pd_db_row_entity_type($row);
    $isDraft = ($entityType === 'draft_order');
    $orderId = (int)($row['shopify_order_id'] ?? 0);
    $draftOrderId = (int)($row['shopify_draft_order_id'] ?? 0);
    $entityId = $isDraft ? $draftOrderId : $orderId;
    $new = null;
    if ($status === 'document.completed') $new = 'completed';
    elseif ($status === 'document.viewed') $new = 'viewed';
    elseif ($status === 'document.sent') $new = 'sent';
    elseif ($status === 'document.declined' || $status === 'document.cancelled') $new = 'declined';

    if ($new) {
        if ($isDraft) {
            pd_db_update_draft_row($draftOrderId, ['status' => $new, 'last_error' => null]);
        } else {
            pd_db_update_order($orderId, ['status' => $new, 'last_error' => null]);
        }
        $metafields = [
            ['namespace' => 'custom', 'key' => 'document_status', 'type' => 'single_line_text_field', 'value' => $new],
        ];
        if ($new === 'completed') {
            $metafields[] = ['namespace' => 'custom', 'key' => 'document_generate_locked', 'type' => 'boolean', 'value' => true];
            if ($isDraft) {
                $metafields[] = ['namespace' => 'custom', 'key' => 'document_generate', 'type' => 'boolean', 'value' => false];
            } else {
                $metafields[] = ['namespace' => 'custom', 'key' => 'document_generate', 'type' => 'boolean', 'value' => true];
            }
        }
        if ($isDraft) {
            shopify_set_draft_order_metafields($draftOrderId, $metafields);
        } else {
            shopify_set_order_metafields($orderId, $metafields);
        }
        if ($isDraft && $new === 'completed') {
            $linkedOrderId = shopify_draft_order_linked_order_id($draftOrderId);
            if ($linkedOrderId !== null && $linkedOrderId > 0) {
                pd_sync_order_metafields_from_draft_row($linkedOrderId, $row);
            }
        }
    }

    $entry = [
        'entity_type' => $entityType,
        'order_id' => $orderId > 0 ? $orderId : null,
        'draft_order_id' => $draftOrderId > 0 ? $draftOrderId : null,
        'docId' => $docId,
        'status' => $status,
        'mapped' => true,
        'set' => $new,
    ];
    if ($new === 'completed' && !$isDraft) {
        $hs = pd_hubspot_on_pandadoc_completed($orderId, $docId);
        pd_log('HubSpot sync after PandaDoc completed', array_merge(
            ['order_id' => $orderId, 'docId' => $docId],
            $hs
        ));
        $entry['hubspot'] = $hs;

        // PDF via GET .../download (not /download-protected). On by default; set PANDADOC_AUTO_STORE_COMPLETED_PDF=0 to skip.
        $skipPdf = in_array(
            strtolower(trim((string)pd_env('PANDADOC_AUTO_STORE_COMPLETED_PDF', '1'))),
            ['0', 'false', 'no', 'off'],
            true
        );
        if ($skipPdf) {
            $entry['stored_pdf'] = ['skipped' => true, 'reason' => 'PANDADOC_AUTO_STORE_COMPLETED_PDF disabled'];
        } else {
            try {
                $stored = pandadoc_store_document_pdf_clean($docId, $orderId > 0 ? $orderId : null);
            } catch (Throwable $e) {
                $stored = ['success' => false, 'original_path' => null, 'original_bytes' => 0, 'clean_path' => null, 'error' => $e->getMessage()];
                pd_log('PandaDoc webhook: store PDF exception', [
                    'order_id' => $orderId,
                    'docId' => $docId,
                    'error' => $e->getMessage(),
                ]);
            }
            $entry['stored_pdf'] = $stored;
            if (!empty($stored['success']) && !empty($stored['original_path'])) {
                pd_db_update_order($orderId, [
                    'completed_pdf_path' => (string)$stored['original_path'],
                    'completed_pdf_clean_path' => (string)($stored['clean_path'] ?? $stored['original_path']),
                ]);
                pd_log('PandaDoc webhook: completed PDF saved', [
                    'order_id' => $orderId,
                    'docId' => $docId,
                    'path' => $stored['original_path'],
                    'clean_path' => $stored['clean_path'] ?? null,
                    'bytes' => $stored['original_bytes'] ?? 0,
                    'removed_pages' => $stored['removed_pages'] ?? [],
                ]);
                if (!empty($stored['clean_path']) && is_string($stored['clean_path'])) {
                    pd_log('HubSpot clean PDF: starting upload + Order property patch', [
                        'order_id' => $orderId,
                        'docId' => $docId,
                        'clean_path' => $stored['clean_path'],
                        'property' => function_exists('pd_hubspot_order_property_pandadoc_clean_pdf_url')
                            ? pd_hubspot_order_property_pandadoc_clean_pdf_url()
                            : 'pandadoc_clean_pdf_url',
                    ]);
                    $hsPdf = pd_hubspot_on_pandadoc_clean_pdf_ready($orderId, (string)$stored['clean_path']);
                    $entry['hubspot_clean_pdf'] = $hsPdf;
                    pd_log('HubSpot clean PDF: result', [
                        'order_id' => $orderId,
                        'docId' => $docId,
                        'hubspot_clean_pdf' => $hsPdf,
                    ]);
                    if (!empty($hsPdf['ok']) && !empty($hsPdf['clean_pdf_url'])) {
                        pd_db_update_order($orderId, ['completed_pdf_clean_hubspot_url' => (string)$hsPdf['clean_pdf_url']]);
                    }
                } else {
                    pd_log('HubSpot clean PDF: skipped (no clean_path on disk)', [
                        'order_id' => $orderId,
                        'docId' => $docId,
                        'stored_pdf' => $stored,
                    ]);
                }
            } elseif (isset($stored['success']) && !$stored['success']) {
                pd_log('PandaDoc webhook: completed PDF download/store failed', [
                    'order_id' => $orderId,
                    'docId' => $docId,
                    'http' => $stored['http'] ?? null,
                    'error' => $stored['error'] ?? null,
                ]);
            }
        }
    } elseif ($new === 'completed' && $isDraft) {
        $entry['hubspot'] = ['ok' => false, 'skipped' => true, 'reason' => 'draft_order_no_hubspot'];
        $skipPdf = in_array(
            strtolower(trim((string)pd_env('PANDADOC_AUTO_STORE_COMPLETED_PDF', '1'))),
            ['0', 'false', 'no', 'off'],
            true
        );
        if ($skipPdf) {
            $entry['stored_pdf'] = ['skipped' => true, 'reason' => 'PANDADOC_AUTO_STORE_COMPLETED_PDF disabled'];
        } else {
            try {
                $stored = pandadoc_store_document_pdf_clean($docId, null);
            } catch (Throwable $e) {
                $stored = ['success' => false, 'original_path' => null, 'original_bytes' => 0, 'clean_path' => null, 'error' => $e->getMessage()];
                pd_log('PandaDoc webhook: store PDF exception (draft)', [
                    'draft_order_id' => $draftOrderId,
                    'docId' => $docId,
                    'error' => $e->getMessage(),
                ]);
            }
            $entry['stored_pdf'] = $stored;
            if (!empty($stored['success']) && !empty($stored['original_path'])) {
                if ($isDraft) {
                    pd_db_update_draft_row($draftOrderId, [
                        'completed_pdf_path' => (string)$stored['original_path'],
                        'completed_pdf_clean_path' => (string)($stored['clean_path'] ?? $stored['original_path']),
                    ]);
                }
                pd_log('PandaDoc webhook: completed PDF saved (draft)', [
                    'draft_order_id' => $draftOrderId,
                    'docId' => $docId,
                    'path' => $stored['original_path'],
                ]);
            }
        }
    }
    $handled[] = $entry;
}

pd_json(200, ['success' => true, 'handled' => $handled]);

