<?php
/**
 * سودانا — QRPayEngine v1
 * توليد وقراءة QR codes للدفع
 */
class QRPayEngine {

    const QR_EXPIRY_MINUTES = 5;
    const QR_BASE_URL = '/api/pay/qr_scan.php?token=';

    // ── generate(): يُولِّد QR للاستقبال ──────────────────────
    public static function generate(int $userId, ?float $amount = null, string $type = 'dynamic'): array {
        try {
            $acc = SudannaPayEngine::getAccount($userId);
            if (!$acc) return ['ok'=>false,'error'=>'account_not_found'];

            $token = bin2hex(random_bytes(24));
            $expires = $type === 'static' ? null : date('Y-m-d H:i:s', time() + self::QR_EXPIRY_MINUTES * 60);

            db()->prepare(
                "INSERT INTO sdpay_qr_codes
                 (qr_token,account_id,qr_type,amount_sdg,expires_at,status)
                 VALUES (?,?,?,?,?,'active')"
            )->execute([$token, $acc['id'], $type, $amount, $expires]);

            $qrData = json_encode([
                'v'  => 1,
                't'  => $token,
                'a'  => $amount,
                'n'  => $acc['account_no'],
                'ts' => time(),
            ]);

            return ['ok'=>true, 'token'=>$token, 'qr_data'=>$qrData,
                    'qr_url'=>SITE_URL . self::QR_BASE_URL . $token,
                    'expires_at'=>$expires, 'amount'=>$amount];
        } catch (Throwable $e) { return ['ok'=>false,'error'=>$e->getMessage()]; }
    }

    // ── generateMerchantStatic(): QR ثابت للتاجر ─────────────
    public static function generateMerchantStatic(int $userId, string $merchantName): array {
        try {
            $existing = db()->prepare(
                "SELECT qr_token FROM sdpay_merchants WHERE user_id=? AND qr_static_token IS NOT NULL LIMIT 1"
            );
            $existing->execute([$userId]);
            $row = $existing->fetch();
            if ($row) return ['ok'=>true,'token'=>$row['qr_token'],'cached'=>true];

            $result = self::generate($userId, null, 'merchant');
            if (!$result['ok']) return $result;

            db()->prepare(
                "UPDATE sdpay_merchants SET qr_static_token=? WHERE user_id=?"
            )->execute([$result['token'], $userId]);

            return $result;
        } catch (Throwable $e) { return ['ok'=>false,'error'=>$e->getMessage()]; }
    }

    // ── scan(): مسح QR والدفع ─────────────────────────────────
    public static function scan(int $scannerUserId, string $token, ?float $overrideAmount = null, string $pin = ''): array {
        try {
            $qr = db()->prepare(
                "SELECT q.*, a.user_id as owner_user_id
                 FROM sdpay_qr_codes q
                 JOIN sdpay_accounts a ON a.id=q.account_id
                 WHERE q.qr_token=? AND q.status='active' LIMIT 1"
            );
            $qr->execute([$token]);
            $qrRow = $qr->fetch();

            if (!$qrRow) return ['ok'=>false,'error'=>'invalid_qr','message'=>'QR غير صالح أو منتهي'];

            // تحقق من انتهاء الصلاحية
            if ($qrRow['expires_at'] && strtotime($qrRow['expires_at']) < time()) {
                db()->prepare("UPDATE sdpay_qr_codes SET status='expired' WHERE qr_token=?")->execute([$token]);
                return ['ok'=>false,'error'=>'qr_expired','message'=>'انتهت صلاحية QR'];
            }

            $amount = $overrideAmount ?? $qrRow['amount_sdg'];
            if (!$amount || $amount <= 0)
                return ['ok'=>false,'error'=>'amount_required','message'=>'المبلغ مطلوب'];

            // جلب حساب المستلم
            $toAcc = db()->prepare("SELECT account_no FROM sdpay_accounts WHERE user_id=? LIMIT 1");
            $toAcc->execute([$qrRow['owner_user_id']]);
            $toAccRow = $toAcc->fetch();
            if (!$toAccRow) return ['ok'=>false,'error'=>'owner_account_not_found'];

            // تنفيذ الدفع
            $result = SudannaPayEngine::transfer(
                $scannerUserId, $toAccRow['account_no'], $amount,
                'دفع عبر QR', '', $pin
            );

            if ($result['ok'] && $qrRow['qr_type'] !== 'static') {
                db()->prepare("UPDATE sdpay_qr_codes SET status='used',used_at=NOW() WHERE qr_token=?")->execute([$token]);
            }
            if ($result['ok']) {
                db()->prepare("UPDATE sdpay_qr_codes SET scan_count=scan_count+1 WHERE qr_token=?")->execute([$token]);
            }

            return $result;
        } catch (Throwable $e) { return ['ok'=>false,'error'=>$e->getMessage()]; }
    }
}
