<?php
/**
 * سودانا — ServicePaymentEngine v1
 * ═══════════════════════════════════════════════════════════════
 * الحلقة الكاملة: مستخدم → خدمة → مزود → Sudanna Pay
 *
 * كل خدمة في المنصة تمر عبر هذا المحرك:
 * طبي | صيدلية | قانوني | تعليم | حرف | زراعة | نفسي
 * ═══════════════════════════════════════════════════════════════
 */
class ServicePaymentEngine {

    // رسوم المنصة حسب نوع الخدمة
    const PLATFORM_FEES = [
        'medical'      => 0.10,  // 10%
        'pharmacy'     => 0.05,  // 5%
        'legal'        => 0.12,  // 12%
        'consultation' => 0.10,  // 10%
        'education'    => 0.08,  // 8%
        'agriculture'  => 0.06,  // 6%
        'craft'        => 0.08,  // 8%
        'mental'       => 0.10,  // 10%
        'other'        => 0.10,  // 10%
    ];

    // ── payForService(): دفع خدمة ─────────────────────────────
    public static function payForService(
        int    $userId,
        int    $providerUserId,
        float  $amount,
        string $serviceType,
        string $pin,
        int    $bookingId = 0,
        string $description = ''
    ): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        require_once __DIR__ . '/AccountingEngine.php';

        try {
            if ($amount < 100)
                return ['ok'=>false,'error'=>'min_amount','message'=>'الحد الأدنى 100 SDG'];

            // تحقق من PIN
            if (!SudannaPayEngine::verifyPin($userId, $pin))
                return ['ok'=>false,'error'=>'invalid_pin'];

            // تحقق من رصيد المستخدم
            $userAcc = SudannaPayEngine::getAccount($userId);
            if (!$userAcc || (float)$userAcc['balance_sdg'] < $amount)
                return ['ok'=>false,'error'=>'insufficient_balance','available'=>$userAcc['balance_sdg']??0,'required'=>$amount];

            // تحقق من حساب المزود
            $provAcc = SudannaPayEngine::getAccount($providerUserId);
            if (!$provAcc) {
                SudannaPayEngine::createAccount($providerUserId);
                $provAcc = SudannaPayEngine::getAccount($providerUserId);
            }

            // احسب الرسوم
            $feePct     = self::PLATFORM_FEES[$serviceType] ?? 0.10;
            $platformFee = round($amount * $feePct, 2);
            $providerNet = $amount - $platformFee;

            $txnRef = 'SVC' . date('YmdHis') . strtoupper(substr(md5(uniqid()),0,6));

            db()->beginTransaction();
            try {
                // خصم من المستخدم
                db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg-? WHERE user_id=?")->execute([$amount,$userId]);
                // أضف للمزود
                db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg+? WHERE user_id=?")->execute([$providerNet,$providerUserId]);

                // سجّل في sdpay_transactions
                db()->prepare(
                    "INSERT INTO sdpay_transactions
                     (txn_ref,type,from_account,to_account,amount_sdg,fee_sdg,net_sdg,status,channel,narration,metadata)
                     VALUES (?,'merchant',?,?,?,?,?,'completed','app',?,?)"
                )->execute([
                    $txnRef,
                    $userAcc['account_no'],
                    $provAcc['account_no'],
                    $amount, $platformFee, $providerNet,
                    $description ?: "دفع خدمة {$serviceType}",
                    json_encode(['service_type'=>$serviceType,'booking_id'=>$bookingId,'fee_pct'=>$feePct]),
                ]);

                // القيد المحاسبي
                AccountingEngine::recordServicePayment(
                    $txnRef, $userId, $providerUserId,
                    $amount, $platformFee, $providerNet,
                    $serviceType, $bookingId
                );

                // تحديث حالة الحجز إذا وُجد
                if ($bookingId) {
                    db()->prepare("UPDATE bookings SET payment_status='paid', payment_ref=? WHERE id=? AND user_id=?")->execute([$txnRef,$bookingId,$userId]);
                }

                db()->commit();
                return [
                    'ok'           => true,
                    'txn_ref'      => $txnRef,
                    'amount_sdg'   => $amount,
                    'platform_fee' => $platformFee,
                    'provider_net' => $providerNet,
                    'fee_pct'      => $feePct * 100,
                    'message'      => 'تم الدفع بنجاح',
                ];
            } catch (\Throwable $e) {
                db()->rollBack();
                throw $e;
            }
        } catch (\Throwable $e) {
            error_log("[ServicePaymentEngine::payForService] ".$e->getMessage());
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── getUserServiceHistory(): سجل خدمات المستخدم ──────────
    public static function getUserServiceHistory(int $userId, int $limit = 20): array {
        try {
            $st = db()->prepare(
                "SELECT ush.*, sp.gross_sdg, sp.platform_fee_sdg, sp.provider_net_sdg,
                 u.name as provider_name, u.phone as provider_phone
                 FROM user_services_history ush
                 LEFT JOIN service_payments sp ON sp.txn_ref=ush.payment_ref
                 LEFT JOIN users u ON u.id=ush.provider_user_id
                 WHERE ush.user_id=? ORDER BY ush.created_at DESC LIMIT ?"
            );
            $st->execute([$userId,$limit]);
            return $st->fetchAll();
        } catch (\Throwable $e) { return []; }
    }

    // ── getProviderEarnings(): أرباح المزود ──────────────────
    public static function getProviderEarnings(int $providerUserId): array {
        try {
            $st = db()->prepare(
                "SELECT
                 COALESCE(SUM(gross_sdg),0) as total_gross,
                 COALESCE(SUM(platform_fee_sdg),0) as total_fees,
                 COALESCE(SUM(net_sdg),0) as total_net,
                 COUNT(*) as service_count,
                 COALESCE(SUM(CASE WHEN MONTH(created_at)=MONTH(NOW()) THEN net_sdg ELSE 0 END),0) as month_net
                 FROM provider_earnings WHERE provider_user_id=? AND status='paid'"
            );
            $st->execute([$providerUserId]);
            return $st->fetch() ?: [];
        } catch (\Throwable $e) { return []; }
    }
}
