<?php

namespace App\Core;

use PDO;
use Throwable;

/**
 * إرسال webhook لعيادة عند اكتمال الطلب (عند ربط lab_orders.clinic_api_key_id)
 */
class ClinicWebhookDispatcher
{
    public static function dispatchOrderCompleted(PDO $db, int $tenantId, int $orderId, array $config = []): void
    {
        try {
            $stmt = $db->prepare('SELECT o.id, o.order_number, o.status, o.patient_id, o.clinic_api_key_id, o.order_date, p.full_name AS patient_name
                FROM lab_orders o
                JOIN patients p ON p.id = o.patient_id
                WHERE o.id = ? AND o.tenant_id = ?');
            $stmt->execute([$orderId, $tenantId]);
            $order = $stmt->fetch();
            if (!$order || empty($order['clinic_api_key_id'])) {
                return;
            }
            $keyId = (int)$order['clinic_api_key_id'];
            $ks = $db->prepare('SELECT id, webhook_url, webhook_secret, clinic_name, is_active FROM clinic_api_keys WHERE id = ? AND tenant_id = ? LIMIT 1');
            $ks->execute([$keyId, $tenantId]);
            $keyRow = $ks->fetch();
            if (!$keyRow || empty($keyRow['webhook_url']) || !(int)($keyRow['is_active'] ?? 1)) {
                return;
            }
            $url = trim((string)$keyRow['webhook_url']);
            if ($url === '' || !filter_var($url, FILTER_VALIDATE_URL)) {
                return;
            }

            $stmt = $db->prepare(
                'SELECT t.name AS test_name, r.result_value, r.unit, r.flag
                 FROM order_items oi
                 JOIN tests t ON t.id = oi.test_id
                 LEFT JOIN results r ON r.order_item_id = oi.id
                 WHERE oi.order_id = ?'
            );
            $stmt->execute([$orderId]);
            $lines = $stmt->fetchAll();

            $payload = [
                'resourceType' => 'Bundle',
                'type' => 'collection',
                'event' => 'order.completed',
                'timestamp' => gmdate('c'),
                'order' => [
                    'id' => (int)$order['id'],
                    'order_number' => $order['order_number'],
                    'status' => $order['status'],
                    'order_date' => $order['order_date'],
                ],
                'patient' => [
                    'id' => (int)$order['patient_id'],
                    'name' => $order['patient_name'],
                ],
                'results' => array_map(static function ($row) {
                    return [
                        'test' => $row['test_name'],
                        'value' => $row['result_value'],
                        'unit' => $row['unit'],
                        'flag' => $row['flag'],
                    ];
                }, $lines ?: []),
            ];
            $body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            if ($body === false) {
                return;
            }

            $secret = trim((string)($keyRow['webhook_secret'] ?? ''));
            $sig = $secret !== '' ? hash_hmac('sha256', $body, $secret) : '';

            $ch = curl_init($url);
            curl_setopt_array($ch, [
                CURLOPT_POST => true,
                CURLOPT_HTTPHEADER => array_filter([
                    'Content-Type: application/json; charset=UTF-8',
                    'X-Webhook-Event: order.completed',
                    $sig !== '' ? 'X-Webhook-Signature: sha256=' . $sig : null,
                ]),
                CURLOPT_POSTFIELDS => $body,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 15,
                CURLOPT_CONNECTTIMEOUT => 5,
            ]);
            $resp = curl_exec($ch);
            $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $err = curl_error($ch);
            curl_close($ch);

            try {
                $db->query('SELECT id FROM clinic_api_logs LIMIT 1');
                $log = $db->prepare('INSERT INTO clinic_api_logs (api_key_id, clinic_name, request_method, request_url, request_params, response_status, response_data, ip_address, execution_time_ms, error_message) VALUES (?,?,?,?,?,?,?,?,?,?)');
                $log->execute([
                    $keyId,
                    (string)$keyRow['clinic_name'],
                    'POST',
                    $url,
                    $body,
                    $code > 0 ? $code : null,
                    is_string($resp) ? mb_substr($resp, 0, 4000) : null,
                    $_SERVER['SERVER_ADDR'] ?? null,
                    null,
                    $err !== '' ? $err : null,
                ]);
            } catch (Throwable $e) {
            }
        } catch (Throwable $e) {
            error_log('ClinicWebhookDispatcher: ' . $e->getMessage());
        }
    }
}
