<?php
/**
 * سودانا — IntegrationEngine v1
 * ═══════════════════════════════════════════════════════════════
 * Sudanna Pay Payment Gateway — للبنوك والمزودين والمؤسسات
 * ═══════════════════════════════════════════════════════════════
 *
 * يتيح لأي جهة خارجية ربط Sudanna Pay كـ Payment Gateway
 * داخل نظامها الخاص — بدون ترك المنصة
 *
 * Integration Types:
 * 1. HOSTED  — توجيه العميل لصفحة دفع سودانا
 * 2. INLINE  — widget مضمَّن في الموقع
 * 3. API     — REST API مباشر
 * 4. WEBHOOK — إشعارات فورية عند الدفع
 */
class IntegrationEngine {

    const VERSION = '1.0';
    const WEBHOOK_TIMEOUT_SECS = 30;
    const SIGNATURE_ALGO = 'sha256';

    // ── createPartner(): تسجيل شريك جديد ──────────────────────
    public static function createPartner(int $userId, array $data): array {
        try {
            $existing = db()->prepare("SELECT id FROM sdpay_partners WHERE user_id=? LIMIT 1");
            $existing->execute([$userId]);
            if ($existing->fetch()) return ['ok'=>false,'error'=>'already_registered'];

            $apiKey    = self::generateApiKey();
            $apiSecret = self::generateApiSecret();
            $partnerId = 'PRT' . strtoupper(substr(md5(uniqid()),0,8));

            db()->prepare(
                "INSERT INTO sdpay_partners
                 (user_id,partner_id,partner_name,partner_type,website_url,
                  api_key,api_secret_hash,webhook_url,status)
                 VALUES (?,?,?,?,?,?,?,?,'pending')"
            )->execute([
                $userId, $partnerId,
                trim($data['partner_name'] ?? ''),
                in_array($data['partner_type']??'',['bank','provider','institution','merchant','fintech','gov'])?$data['partner_type']:'merchant',
                $data['website_url'] ?? null,
                $apiKey,
                hash(self::SIGNATURE_ALGO, $apiSecret),
                $data['webhook_url'] ?? null,
            ]);

            return [
                'ok'         => true,
                'partner_id' => $partnerId,
                'api_key'    => $apiKey,
                'api_secret' => $apiSecret,  // يُظهَر مرة واحدة فقط!
                'message'    => 'احفظ الـ API Secret الآن — لن يُظهَر مرة أخرى',
            ];
        } catch (\Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── authenticatePartner(): التحقق من هوية الشريك ──────────
    public static function authenticatePartner(string $apiKey, string $timestamp, string $signature, string $payload): ?array {
        try {
            $st = db()->prepare("SELECT * FROM sdpay_partners WHERE api_key=? AND status='active' LIMIT 1");
            $st->execute([$apiKey]);
            $partner = $st->fetch();
            if (!$partner) return null;

            // Replay attack prevention (5 min window)
            if (abs(time() - (int)$timestamp) > 300) return null;

            // Signature verification: HMAC-SHA256(timestamp + payload, api_secret)
            $expected = hash_hmac(self::SIGNATURE_ALGO, $timestamp . $payload, $partner['api_secret_hash']);
            if (!hash_equals($expected, $signature)) return null;

            return $partner;
        } catch (\Throwable $e) { return null; }
    }

    // ── initiatePayment(): بدء معاملة دفع ──────────────────────
    public static function initiatePayment(array $partner, array $data): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $amount      = (float)($data['amount_sdg'] ?? 0);
            $reference   = trim($data['partner_reference'] ?? '');
            $description = mb_substr(trim($data['description'] ?? ''), 0, 100);
            $callbackUrl = trim($data['callback_url'] ?? $partner['webhook_url'] ?? '');
            $type        = $data['integration_type'] ?? 'hosted'; // hosted|inline|api

            if ($amount < 10) return ['ok'=>false,'error'=>'amount_too_small'];
            if (!$reference) return ['ok'=>false,'error'=>'partner_reference_required'];

            // Check idempotency
            $existing = db()->prepare("SELECT * FROM sdpay_partner_transactions WHERE partner_id=? AND partner_reference=? LIMIT 1");
            $existing->execute([$partner['id'], $reference]);
            if ($ex = $existing->fetch()) return ['ok'=>true,'existing'=>true,'payment_id'=>$ex['payment_id'],'status'=>$ex['status']];

            // Create payment session
            $paymentId  = 'PAY' . date('Ymd') . strtoupper(substr(md5(uniqid()),0,10));
            $sessionToken = bin2hex(random_bytes(32));
            $expiresAt  = date('Y-m-d H:i:s', time() + 3600); // 1 ساعة

            db()->prepare(
                "INSERT INTO sdpay_partner_transactions
                 (partner_id,payment_id,session_token,partner_reference,amount_sdg,
                  description,integration_type,callback_url,status,expires_at)
                 VALUES (?,?,?,?,?,?,?,?,'pending',?)"
            )->execute([
                $partner['id'], $paymentId, $sessionToken, $reference,
                $amount, $description, $type, $callbackUrl, $expiresAt
            ]);

            $baseUrl = 'https://sudanna.ai/s26';
            return [
                'ok'           => true,
                'payment_id'   => $paymentId,
                'amount_sdg'   => $amount,
                'description'  => $description,
                'expires_at'   => $expiresAt,
                'payment_url'  => "{$baseUrl}/pay/checkout.php?session={$sessionToken}",
                'widget_url'   => "{$baseUrl}/api/partners/widget.php?session={$sessionToken}",
                'qr_url'       => "{$baseUrl}/api/partners/qr.php?session={$sessionToken}",
                'session_token'=> $sessionToken,
            ];
        } catch (\Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── verifyPayment(): التحقق من حالة الدفع ──────────────────
    public static function verifyPayment(array $partner, string $paymentId): array {
        try {
            $st = db()->prepare(
                "SELECT spt.*, st.txn_ref, st.completed_at
                 FROM sdpay_partner_transactions spt
                 LEFT JOIN sdpay_transactions st ON st.metadata->>'$.payment_id' = spt.payment_id
                 WHERE spt.partner_id=? AND spt.payment_id=? LIMIT 1"
            );
            $st->execute([$partner['id'], $paymentId]);
            $txn = $st->fetch();
            if (!$txn) return ['ok'=>false,'error'=>'payment_not_found'];

            return [
                'ok'                => true,
                'payment_id'        => $paymentId,
                'partner_reference' => $txn['partner_reference'],
                'amount_sdg'        => $txn['amount_sdg'],
                'status'            => $txn['status'],
                'txn_ref'           => $txn['txn_ref'] ?? null,
                'completed_at'      => $txn['completed_at'] ?? null,
            ];
        } catch (\Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── sendWebhook(): إرسال إشعار للشريك ──────────────────────
    public static function sendWebhook(string $webhookUrl, array $payload, string $apiSecretHash): bool {
        if (!$webhookUrl) return false;
        try {
            $body      = json_encode($payload);
            $timestamp = time();
            $signature = hash_hmac(self::SIGNATURE_ALGO, $timestamp . $body, $apiSecretHash);

            $ctx = stream_context_create(['http'=>[
                'method'  => 'POST',
                'header'  => implode("\r\n",[
                    'Content-Type: application/json',
                    'X-Sudanna-Timestamp: '.$timestamp,
                    'X-Sudanna-Signature: '.$signature,
                    'X-Sudanna-Version: '.self::VERSION,
                    'User-Agent: SudannaPay-Webhook/1.0',
                ]),
                'content' => $body,
                'timeout' => self::WEBHOOK_TIMEOUT_SECS,
            ]]);

            $response = @file_get_contents($webhookUrl, false, $ctx);
            return $response !== false;
        } catch (\Throwable $e) {
            error_log("[IntegrationEngine::sendWebhook] ".$e->getMessage());
            return false;
        }
    }

    // ── processCompletedPayment(): عند اكتمال الدفع ────────────
    public static function processCompletedPayment(string $paymentId, string $txnRef): void {
        try {
            // تحديث حالة المعاملة
            db()->prepare(
                "UPDATE sdpay_partner_transactions SET status='completed', completed_at=NOW()
                 WHERE payment_id=?"
            )->execute([$paymentId]);

            // جلب بيانات الشريك
            $st = db()->prepare(
                "SELECT spt.*, sp.webhook_url, sp.api_secret_hash, sp.partner_name
                 FROM sdpay_partner_transactions spt
                 JOIN sdpay_partners sp ON sp.id=spt.partner_id
                 WHERE spt.payment_id=? LIMIT 1"
            );
            $st->execute([$paymentId]);
            $txn = $st->fetch();
            if (!$txn) return;

            // أرسل webhook
            if ($txn['webhook_url']) {
                self::sendWebhook($txn['webhook_url'], [
                    'event'             => 'payment.completed',
                    'payment_id'        => $paymentId,
                    'partner_reference' => $txn['partner_reference'],
                    'amount_sdg'        => $txn['amount_sdg'],
                    'txn_ref'           => $txnRef,
                    'completed_at'      => date('c'),
                    'partner'           => $txn['partner_name'],
                ], $txn['api_secret_hash']);
            }

            // سجّل في الـ log
            db()->prepare(
                "INSERT INTO sdpay_webhook_logs (partner_id,payment_id,event,status)
                 VALUES (?,?,'payment.completed','sent')"
            )->execute([$txn['partner_id'], $paymentId]);

        } catch (\Throwable $e) {
            error_log("[IntegrationEngine::processCompletedPayment] ".$e->getMessage());
        }
    }

    // ── getDocumentation(): وثائق الربط ─────────────────────────
    public static function getDocumentation(string $type = 'overview'): array {
        return [
            'overview' => [
                'title' => 'Sudanna Pay Integration Guide',
                'types' => [
                    'hosted' => [
                        'name'  => 'Hosted Payment Page',
                        'desc'  => 'وجّه العميل لصفحة دفع سودانا — الأسهل والأسرع',
                        'steps' => ['اتصل بـ /api/partners/init.php','احصل على payment_url','وجّه العميل للرابط','استقبل webhook عند الدفع'],
                    ],
                    'inline' => [
                        'name'  => 'Inline Widget',
                        'desc'  => 'ضمِّن نموذج الدفع داخل موقعك/تطبيقك',
                        'steps' => ['أضف script SDK','اتصل بـ SudannaPay.init()','استقبل callback عند الدفع'],
                    ],
                    'api' => [
                        'name'  => 'Direct API',
                        'desc'  => 'تحكم كامل عبر REST API',
                        'steps' => ['POST /api/partners/init.php','GET /api/partners/verify.php','استقبل webhook'],
                    ],
                ],
                'authentication' => 'HMAC-SHA256(timestamp + payload, api_secret)',
                'base_url'       => 'https://sudanna.ai/s26',
                'version'        => self::VERSION,
            ],
            'endpoints' => [
                ['method'=>'POST','url'=>'/api/partners/register.php',  'desc'=>'تسجيل شريك جديد'],
                ['method'=>'POST','url'=>'/api/partners/init.php',      'desc'=>'بدء معاملة دفع'],
                ['method'=>'GET', 'url'=>'/api/partners/verify.php',    'desc'=>'التحقق من حالة الدفع'],
                ['method'=>'POST','url'=>'/api/partners/refund.php',    'desc'=>'استرداد مبلغ'],
                ['method'=>'GET', 'url'=>'/api/partners/transactions.php','desc'=>'سجل المعاملات'],
                ['method'=>'GET', 'url'=>'/api/partners/balance.php',   'desc'=>'رصيد الشريك'],
                ['method'=>'GET', 'url'=>'/api/partners/widget.php',    'desc'=>'Inline widget embed'],
            ],
            'webhook_events' => [
                'payment.completed',
                'payment.failed',
                'payment.expired',
                'payment.refunded',
            ],
        ];
    }

    // ── generateApiKey() / generateApiSecret() ───────────────────
    private static function generateApiKey(): string {
        return 'sk_live_' . bin2hex(random_bytes(20));
    }
    private static function generateApiSecret(): string {
        return bin2hex(random_bytes(32));
    }
}
