<?php
/**
 * سودانا — MerchantEngine v2
 * إدارة التجار والمزودين التجاريين
 * صيدليات — سوبرماركت — عيادات — مطاعم — مدارس
 */
require_once __DIR__ . '/AccountingEngine.php';
require_once __DIR__ . '/BankAdapter.php';

class MerchantEngine {

    const COMMISSION_BASIC    = 0.015; // 1.5%
    const COMMISSION_SILVER   = 0.012; // 1.2%
    const COMMISSION_GOLD     = 0.010; // 1.0%
    const COMMISSION_PLATINUM = 0.008; // 0.8%

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

            $code = self::generateMerchantCode();
            db()->prepare(
                "INSERT INTO sdpay_merchants
                 (user_id,merchant_code,business_name,business_type,license_no,
                  tax_id,address,governorate,city,gps_lat,gps_lng,status)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,'pending')"
            )->execute([
                $userId, $code,
                trim($data['business_name'] ?? ''),
                $data['business_type'] ?? 'other',
                $data['license_no'] ?? null,
                $data['tax_id'] ?? null,
                $data['address'] ?? null,
                $data['governorate'] ?? null,
                $data['city'] ?? null,
                $data['gps_lat'] ?? null,
                $data['gps_lng'] ?? null,
            ]);

            // أنشئ QR ثابت للتاجر
            require_once __DIR__ . '/QRPayEngine.php';
            $qr = QRPayEngine::generateMerchantStatic($userId, $data['business_name'] ?? '');

            return ['ok'=>true, 'merchant_code'=>$code, 'qr_token'=>$qr['qr_token'] ?? null];
        } catch (Throwable $e) {
            error_log("[MerchantEngine::register] ".$e->getMessage());
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── approve(): موافقة الإدارة على التاجر ─────────────────
    public static function approve(int $merchantId): array {
        try {
            db()->prepare(
                "UPDATE sdpay_merchants SET status='active', approved_at=NOW() WHERE id=?"
            )->execute([$merchantId]);
            return ['ok'=>true];
        } catch (Throwable $e) { return ['ok'=>false,'error'=>$e->getMessage()]; }
    }

    // ── getMerchant(): جلب بيانات التاجر ─────────────────────
    public static function getMerchant(int $userId): ?array {
        try {
            $st = db()->prepare("SELECT * FROM sdpay_merchants WHERE user_id=? LIMIT 1");
            $st->execute([$userId]);
            return $st->fetch() ?: null;
        } catch (Throwable $e) { return null; }
    }

    // ── processPayment(): استقبال دفعة ───────────────────────
    public static function processPayment(int $fromUserId, int $merchantId, float $amount, string $pin): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $merchant = db()->prepare("SELECT * FROM sdpay_merchants WHERE id=? AND status='active' LIMIT 1");
            $merchant->execute([$merchantId]);
            $m = $merchant->fetch();
            if (!$m) return ['ok'=>false,'error'=>'merchant_not_found'];

            // التاجر له حساب Pay
            $mAccount = SudannaPayEngine::getAccount($m['user_id']);
            if (!$mAccount) {
                SudannaPayEngine::createAccount($m['user_id']);
                $mAccount = SudannaPayEngine::getAccount($m['user_id']);
            }

            $result = SudannaPayEngine::transfer(
                $fromUserId,
                $mAccount['account_no'],
                $amount,
                'دفع لـ ' . $m['business_name'],
                uniqid('mpe_', true),
                $pin
            );

            if ($result['ok'] ?? false) {
                // عمولة سودانا
                $commission = $amount * ($m['commission_rate'] ?? self::COMMISSION_BASIC);
                try {
                    db()->prepare(
                        "INSERT INTO sdpay_merchant_settlements
                         (merchant_id, period_date, txn_count, gross_sdg, commission_sdg, net_sdg, status)
                         VALUES (?, CURDATE(), 1, ?, ?, ?, 'pending')
                         ON DUPLICATE KEY UPDATE
                           txn_count=txn_count+1,
                           gross_sdg=gross_sdg+VALUES(gross_sdg),
                           commission_sdg=commission_sdg+VALUES(commission_sdg),
                           net_sdg=net_sdg+VALUES(net_sdg)"
                    )->execute([$merchantId, $amount, $commission, $amount - $commission]);
                } catch (Throwable $ignored) {}

                // نقاط ولاء للمشتري
                self::awardLoyaltyPoints($fromUserId, $merchantId, $amount);
                
                // تحديث حجم المبيعات
                db()->prepare("UPDATE sdpay_merchants SET monthly_volume_sdg=monthly_volume_sdg+? WHERE id=?")
                   ->execute([$amount, $merchantId]);

                self::checkTierUpgrade($merchantId);
            }

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

    // ── getDashboard(): لوحة تحكم التاجر ─────────────────────
    public static function getDashboard(int $userId): array {
        try {
            $m = self::getMerchant($userId);
            if (!$m) return ['merchant'=>null];

            // إحصاءات اليوم
            $st = db()->prepare(
                "SELECT COALESCE(SUM(gross_sdg),0) as today_gross,
                        COALESCE(SUM(net_sdg),0) as today_net,
                        COALESCE(SUM(txn_count),0) as today_count
                 FROM sdpay_merchant_settlements
                 WHERE merchant_id=? AND period_date=CURDATE()"
            );
            $st->execute([$m['id']]);
            $today = $st->fetch();

            // إحصاءات الشهر
            $st2 = db()->prepare(
                "SELECT COALESCE(SUM(gross_sdg),0) as month_gross,
                        COALESCE(SUM(txn_count),0) as month_count
                 FROM sdpay_merchant_settlements
                 WHERE merchant_id=? AND MONTH(period_date)=MONTH(NOW())"
            );
            $st2->execute([$m['id']]);
            $month = $st2->fetch();

            return [
                'merchant'    => $m,
                'today_gross' => (float)($today['today_gross'] ?? 0),
                'today_net'   => (float)($today['today_net'] ?? 0),
                'today_count' => (int)($today['today_count'] ?? 0),
                'month_gross' => (float)($month['month_gross'] ?? 0),
                'month_count' => (int)($month['month_count'] ?? 0),
            ];
        } catch (Throwable $e) { return ['merchant'=>null]; }
    }

    // ── searchNearby(): بحث عن تجار قريبين ───────────────────
    public static function searchNearby(float $lat, float $lng, string $type='', int $limit=20): array {
        try {
            $where = "status='active'";
            $params = [];
            if ($type) { $where .= " AND business_type=?"; $params[] = $type; }
            $st = db()->prepare(
                "SELECT *,
                 (6371 * acos(cos(radians(?)) * cos(radians(gps_lat)) *
                  cos(radians(gps_lng) - radians(?)) + sin(radians(?)) * sin(radians(gps_lat)))) AS distance_km
                 FROM sdpay_merchants WHERE {$where} AND gps_lat IS NOT NULL
                 HAVING distance_km < 10 ORDER BY distance_km LIMIT ?"
            );
            $st->execute(array_merge([$lat,$lng,$lat], $params, [$limit]));
            return $st->fetchAll();
        } catch (Throwable $e) { return []; }
    }

    // ── listByType(): قائمة بالنوع ────────────────────────────
    public static function listByType(string $type, string $city=''): array {
        try {
            $where = "status='active'";
            $params = [];
            if ($type) { $where .= " AND business_type=?"; $params[] = $type; }
            if ($city) { $where .= " AND city=?"; $params[] = $city; }
            $st = db()->prepare("SELECT * FROM sdpay_merchants WHERE {$where} ORDER BY tier DESC, business_name LIMIT 50");
            $st->execute($params);
            return $st->fetchAll();
        } catch (Throwable $e) { return []; }
    }

    // ── awardLoyaltyPoints() ──────────────────────────────────
    private static function awardLoyaltyPoints(int $userId, int $merchantId, float $amount): void {
        $points = (int)($amount / 100);
        if ($points < 1) return;
        try {
            db()->prepare(
                "INSERT INTO sdpay_loyalty_points (user_id,merchant_id,points_earned,points_spent,txn_ref)
                 VALUES (?,?,?,0,?)"
            )->execute([$userId, $merchantId, $points, uniqid('lp_')]);
        } catch (Throwable $ignored) {}
    }

    // ── checkTierUpgrade() ────────────────────────────────────
    private static function checkTierUpgrade(int $merchantId): void {
        try {
            $st = db()->prepare("SELECT monthly_volume_sdg FROM sdpay_merchants WHERE id=?");
            $st->execute([$merchantId]);
            $vol = (float)($st->fetchColumn() ?? 0);
            $tier = 'basic';
            $rate = self::COMMISSION_BASIC;
            if ($vol >= 10000000) { $tier='platinum'; $rate=self::COMMISSION_PLATINUM; }
            elseif ($vol >= 3000000) { $tier='gold'; $rate=self::COMMISSION_GOLD; }
            elseif ($vol >= 1000000) { $tier='silver'; $rate=self::COMMISSION_SILVER; }
            db()->prepare("UPDATE sdpay_merchants SET tier=?,commission_rate=? WHERE id=?")
               ->execute([$tier,$rate,$merchantId]);
        } catch (Throwable $ignored) {}
    }

    // ── generateMerchantCode() ────────────────────────────────
    private static function generateMerchantCode(): string {
        return 'MRC' . strtoupper(substr(md5(uniqid('',true)),0,8));
    }
}
