<?php
namespace DZQCOD;
defined('ABSPATH') || exit;

class Modules {
    /** Check if addon is installed/active */
    public static function is_on(string $slug): bool {
        static $cache=null;
        if($cache===null) $cache=self::installed_addons();
        return !empty($cache[$slug]);
    }

    public function __construct() {
        // Admin AJAX — always available
        add_action('wp_ajax_dzqcod_install_addon', [$this, 'install_addon']);
        add_action('wp_ajax_dzqcod_toggle_addon', [$this, 'toggle_addon']);
        add_action('wp_ajax_dzqcod_upload_addon', [$this, 'upload_addon']);
        add_action('wp_ajax_dzqcod_publish_addon', [$this, 'publish_addon']);
        add_action('wp_ajax_dzqcod_save_role', [$this, 'save_role']);
        add_action('wp_ajax_dzqcod_delete_role', [$this, 'delete_role']);
        add_action('wp_ajax_dzqcod_refresh_remote_addons', [$this, 'refresh_remote_addons']);
        add_action('init', [$this, 'load_textdomain'], 1);

        // Gated features — only fire hooks if addon is active
        // WhatsApp Auto
        if(self::is_on('whatsapp-auto')){
            add_action('dzqcod_order_created', [$this, 'wa_on_order'], 10, 2);
            add_action('woocommerce_order_status_changed', [$this, 'wa_on_status'], 10, 4);
            add_action('wp_ajax_dzqcod_wa_send', [$this, 'wa_send_manual']);
            add_action('wp_ajax_dzqcod_wa_save_templates', [$this, 'wa_save_templates']);
        }
        // Chargily Pay
        if(self::is_on('chargily')){
            add_action('wp_ajax_dzqcod_chargily_settings', [$this, 'chargily_save']);
            add_action('wp_ajax_nopriv_dzqcod_chargily_webhook', [$this, 'chargily_webhook']);
            add_action('wp_ajax_dzqcod_chargily_webhook', [$this, 'chargily_webhook']);
        }
        // Digital Products
        if(self::is_on('digital')){
            add_action('woocommerce_order_status_changed', [$this, 'digital_delivery'], 10, 4);
        }
        // Canva Creative
        // Canva Creative — handled by addon file
        if(self::is_on('canva')){
            // Legacy hook removed — canva.php addon handles all AJAX
        }
        // SMS Auto
        if(self::is_on('sms-auto')){
            add_action('dzqcod_order_created', [$this, 'sms_on_order'], 15, 2);
            add_action('woocommerce_order_status_changed', [$this, 'sms_on_status'], 15, 4);
            add_action('wp_ajax_dzqcod_sms_save_config', [$this, 'sms_save_config']);
            add_action('wp_ajax_dzqcod_sms_test', [$this, 'sms_test']);
        }
        // BaridiMob
        if(self::is_on('baridimob')){
            add_action('wp_ajax_dzqcod_baridimob_save', [$this, 'baridimob_save']);
            add_action('wp_ajax_dzqcod_baridimob_confirm', [$this, 'baridimob_confirm']);
        }
        // Load external addon files from addons/ directory
        $this->load_addon_files();
    }

    /** Load .php files from addons/ directory for active addons */
    private function load_addon_files(): void {
        $dir = DZQCOD_PATH . 'addons/';
        if (!is_dir($dir)) return;
        $inst = self::installed_addons();
        foreach ($inst as $slug => $active) {
            if (!$active) continue;
            // Single file: addons/slug.php
            $file = $dir . $slug . '.php';
            if (is_file($file)) { require_once $file; continue; }
            // Directory: addons/slug/slug.php or addons/slug/init.php
            $dir_file = $dir . $slug . '/' . $slug . '.php';
            if (is_file($dir_file)) { require_once $dir_file; continue; }
            $init_file = $dir . $slug . '/init.php';
            if (is_file($init_file)) { require_once $init_file; }
        }
    }

    /** Upload addon from admin */
    public function upload_addon(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        if(!current_user_can('manage_options'))wp_send_json_error(['message'=>'غير مصرح']);
        if(empty($_FILES['addon_file']))wp_send_json_error(['message'=>'لم يتم رفع ملف']);
        $file=$_FILES['addon_file'];
        $ext=strtolower(pathinfo($file['name'],PATHINFO_EXTENSION));
        if(!in_array($ext,['zip','php']))wp_send_json_error(['message'=>'يجب أن يكون الملف .zip أو .php']);
        $addons_dir=DZQCOD_PATH.'addons/';
        if(!is_dir($addons_dir))wp_mkdir_p($addons_dir);
        global $wpdb; $p=$wpdb->prefix.\DZQCOD_DB.'addons';
        if($ext==='php'){
            $slug=sanitize_file_name(pathinfo($file['name'],PATHINFO_FILENAME));
            move_uploaded_file($file['tmp_name'],$addons_dir.$slug.'.php');
            // Read addon header
            $header=$this->read_addon_header($addons_dir.$slug.'.php');
            $name=$header['name']??$slug;
            $desc=$header['description']??'إضافة مرفوعة يدوياً';
            $wpdb->replace($p,['slug'=>$slug,'name'=>$name,'description'=>$desc,'type'=>'custom','is_installed'=>1]);
            wp_send_json_success(['message'=>"تم رفع وتفعيل: {$name}"]);
        }else{
            // ZIP
            $zip=new \ZipArchive();
            if($zip->open($file['tmp_name'])!==true)wp_send_json_error(['message'=>'ملف ZIP غير صالح']);
            // Determine slug from ZIP contents
            $first=$zip->getNameIndex(0);$slug=trim(explode('/',$first)[0]);
            if(!$slug)$slug=sanitize_file_name(pathinfo($file['name'],PATHINFO_FILENAME));
            $target=$addons_dir.$slug.'/';
            if(!is_dir($target))wp_mkdir_p($target);
            $zip->extractTo($target);$zip->close();
            // Read header from main file
            $main=$target.$slug.'.php';
            if(!is_file($main))$main=$target.'init.php';
            $header=is_file($main)?$this->read_addon_header($main):[];
            $name=$header['name']??$slug;
            $desc=$header['description']??'إضافة مرفوعة يدوياً';
            $wpdb->replace($p,['slug'=>$slug,'name'=>$name,'description'=>$desc,'type'=>'custom','is_installed'=>1]);
            wp_send_json_success(['message'=>"تم رفع وتفعيل: {$name}"]);
        }
    }

    /** Read addon header from PHP file (Plugin Name, Description) */
    private function read_addon_header(string $file): array {
        if(!is_file($file))return [];
        $data=file_get_contents($file,false,null,0,2048);
        $h=[];
        if(preg_match('/Addon Name:\s*(.+)/i',$data,$m))$h['name']=trim($m[1]);
        elseif(preg_match('/Plugin Name:\s*(.+)/i',$data,$m))$h['name']=trim($m[1]);
        if(preg_match('/Description:\s*(.+)/i',$data,$m))$h['description']=trim($m[1]);
        return $h;
    }

    /** Publish addon to NIBRA Cloud for distribution */
    public function publish_addon(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        if(!current_user_can('manage_options'))wp_send_json_error(['message'=>'غير مصرح']);
        $slug=sanitize_text_field($_POST['slug']??'');
        if(!$slug)wp_send_json_error(['message'=>'الإضافة غير محددة']);
        $addons_dir=DZQCOD_PATH.'addons/';
        // Find addon file(s)
        $single=$addons_dir.$slug.'.php';
        $dir_path=$addons_dir.$slug.'/';
        if(!is_file($single)&&!is_dir($dir_path))wp_send_json_error(['message'=>'ملفات الإضافة غير موجودة']);
        // Create temp ZIP
        $tmp=wp_tempnam($slug.'.zip');
        $zip=new \ZipArchive();
        if($zip->open($tmp,\ZipArchive::CREATE|\ZipArchive::OVERWRITE)!==true)wp_send_json_error(['message'=>'فشل إنشاء ZIP']);
        if(is_file($single)){
            $zip->addFile($single,$slug.'.php');
        }elseif(is_dir($dir_path)){
            $files=new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir_path,\RecursiveDirectoryIterator::SKIP_DOTS));
            foreach($files as $f){$rel=$slug.'/'.substr($f->getPathname(),strlen($dir_path));$zip->addFile($f->getPathname(),$rel);}
        }
        $zip->close();
        // Upload to cloud
        $license=Core::opt('license_key','');
        $boundary=wp_generate_password(24,false);
        $body='';
        $body.="--{$boundary}\r\nContent-Disposition: form-data; name=\"slug\"\r\n\r\n{$slug}\r\n";
        $body.="--{$boundary}\r\nContent-Disposition: form-data; name=\"license\"\r\n\r\n{$license}\r\n";
        $body.="--{$boundary}\r\nContent-Disposition: form-data; name=\"site\"\r\n\r\n".home_url()."\r\n";
        $file_data=file_get_contents($tmp);
        $body.="--{$boundary}\r\nContent-Disposition: form-data; name=\"addon_file\"; filename=\"{$slug}.zip\"\r\nContent-Type: application/zip\r\n\r\n{$file_data}\r\n";
        $body.="--{$boundary}--\r\n";
        $resp=wp_remote_post(self::API_BASE.'/addons/publish',[
            'timeout'=>30,'sslverify'=>apply_filters('dzqcod_ssl_verify',true),
            'headers'=>['Content-Type'=>'multipart/form-data; boundary='.$boundary,'X-DZQCOD-Version'=>DZQCOD_VER],
            'body'=>$body
        ]);
        wp_delete_file($tmp);
        if(is_wp_error($resp))wp_send_json_error(['message'=>'خطأ اتصال: '.$resp->get_error_message()]);
        $code=wp_remote_retrieve_response_code($resp);
        $result=json_decode(wp_remote_retrieve_body($resp),true);
        if($code===200&&!empty($result['success'])){
            delete_transient('dzqcod_remote_addons');
            wp_send_json_success(['message'=>$result['message']??'تم نشر الإضافة بنجاح على NIBRA Cloud ☁️']);
        }else{
            wp_send_json_error(['message'=>$result['message']??'فشل النشر — تأكد من صلاحية الترخيص (كود: '.$code.')']);
        }
    }

    // ═══ ADDONS MARKETPLACE ═══
    public static function get_addons(): array {
        // Local built-in addons
        $local = [
            ['slug'=>'yalidine','name'=>'Yalidine Shipping','desc'=>'ربط تلقائي مع Yalidine','icon'=>'🚚','type'=>'free','cat'=>'shipping'],
            ['slug'=>'zr-express','name'=>'ZR Express','desc'=>'ربط مع ZR Express','icon'=>'📦','type'=>'free','cat'=>'shipping'],
            ['slug'=>'ecotrack','name'=>'EcoTrack','desc'=>'شركة EcoTrack للتوصيل','icon'=>'🌿','type'=>'free','cat'=>'shipping'],
            ['slug'=>'noest','name'=>'NOEST Delivery','desc'=>'شركة NOEST للتوصيل — كل ولايات الجزائر مع Stop Desk و التتبع الآلي','icon'=>'🔵','type'=>'free','cat'=>'shipping'],
            ['slug'=>'chargily','name'=>'Chargily Pay','desc'=>'الدفع الإلكتروني CIB/EDAHABIA','icon'=>'💳','type'=>'free','cat'=>'payment'],
            ['slug'=>'baridimob','name'=>'BaridiMob','desc'=>'الدفع عبر بريدي موب','icon'=>'📱','type'=>'pro','cat'=>'payment'],
            ['slug'=>'whatsapp-auto','name'=>'WhatsApp Auto','desc'=>'رسائل واتساب تلقائية','icon'=>'💬','type'=>'free','cat'=>'marketing'],
            ['slug'=>'sms-auto','name'=>'SMS Auto','desc'=>'رسائل SMS تلقائية','icon'=>'📲','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'meta-capi','name'=>'Meta CAPI','desc'=>'Meta Conversions API','icon'=>'📊','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'tiktok-events','name'=>'TikTok Events','desc'=>'TikTok Events API','icon'=>'🎵','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'google-ads','name'=>'Google Ads','desc'=>'Google Ads Conversion','icon'=>'🔍','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'canva','name'=>'Canva Creative','desc'=>'تصاميم إعلانية بالذكاء','icon'=>'🎨','type'=>'enterprise','cat'=>'creative'],
            ['slug'=>'ai-copilot','name'=>'AI Copilot','desc'=>'مساعد كتابة الإعلانات','icon'=>'🤖','type'=>'enterprise','cat'=>'creative'],
            ['slug'=>'ads-manager','name'=>'Ads Manager','desc'=>'نظام إدارة إعلانات المتجر — بانرات ذكية، Pop-ups، شريط عروض، مناطق إعلانية مخصصة مع جدولة واستهداف وتحليلات','icon'=>'📢','type'=>'enterprise','cat'=>'marketing'],
            ['slug'=>'ab-testing','name'=>'A/B Testing','desc'=>'اختبار نسخ مختلفة','icon'=>'🔬','type'=>'pro','cat'=>'optimization'],
            ['slug'=>'retargeting','name'=>'Retargeting','desc'=>'استهداف المرتجعين','icon'=>'🎯','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'multi-store','name'=>'Multi-Store','desc'=>'متاجر متعددة','icon'=>'🏪','type'=>'enterprise','cat'=>'enterprise'],
            ['slug'=>'workflows','name'=>'Workflows','desc'=>'أتمتة سير العمل','icon'=>'⚡','type'=>'enterprise','cat'=>'enterprise'],
            ['slug'=>'digital','name'=>'Digital Products','desc'=>'منتجات رقمية','icon'=>'💾','type'=>'free','cat'=>'products'],
            ['slug'=>'export','name'=>'Export/Import','desc'=>'تصدير CSV/Excel','icon'=>'📤','type'=>'free','cat'=>'tools'],
            ['slug'=>'analytics','name'=>'Analytics Pro','desc'=>'تقارير متقدمة','icon'=>'📈','type'=>'pro','cat'=>'analytics'],
            ['slug'=>'multi-country','name'=>'Multi-Country','desc'=>'تونس،المغرب،ليبيا','icon'=>'🌍','type'=>'pro','cat'=>'international'],
            ['slug'=>'upsell','name'=>'Upsell & Cross-sell','desc'=>'منتجات مكملة لزيادة متوسط السلة','icon'=>'🛍️','type'=>'pro','cat'=>'sales'],
            ['slug'=>'order-bump','name'=>'Order Bump','desc'=>'منتج إضافي بتخفيض قبل الطلب','icon'=>'⚡','type'=>'pro','cat'=>'sales'],
            ['slug'=>'abandoned-cart','name'=>'Abandoned Cart','desc'=>'استرجع من لم يكمل الطلب','icon'=>'🔄','type'=>'pro','cat'=>'sales'],
            ['slug'=>'loyalty','name'=>'Loyalty Points','desc'=>'نقاط ولاء: اطلب واكسب وفّر','icon'=>'🏆','type'=>'pro','cat'=>'sales'],
            ['slug'=>'referral','name'=>'Referral System','desc'=>'إحالة + عمولة لكل طلب','icon'=>'🤝','type'=>'pro','cat'=>'sales'],
            // ═══ SMART OPS (3) ═══
            ['slug'=>'smart-confirm','name'=>'Smart Confirm','desc'=>'تأكيد تلقائي ذكي حسب السجل','icon'=>'🧠','type'=>'pro','cat'=>'automation'],
            ['slug'=>'auto-ship','name'=>'Auto-Shipping','desc'=>'شحن تلقائي بعد التأكيد','icon'=>'🤖','type'=>'pro','cat'=>'automation'],
            ['slug'=>'followup','name'=>'Follow-up Sequences','desc'=>'متابعة: مراجعة+إعادة شراء+استرجاع','icon'=>'📨','type'=>'pro','cat'=>'automation'],
            // ═══ INTELLIGENCE (3) ═══
            ['slug'=>'profit-calc','name'=>'Profit Calculator','desc'=>'حساب الربح الصافي و ROAS','icon'=>'💹','type'=>'free','cat'=>'analytics'],
            ['slug'=>'accounting-pro','name'=>'Accounting Pro','desc'=>'نظام محاسبي شامل — فواتير إدارية، ضرائب، مصاريف، إيرادات، تقارير مالية، TVA/TAP، سجل يومي، ميزان المراجعة','icon'=>'🧾','type'=>'enterprise','cat'=>'analytics'],
            ['slug'=>'cohort','name'=>'Cohort Analysis','desc'=>'تحليل العملاء المتكررين','icon'=>'📊','type'=>'enterprise','cat'=>'analytics'],
            ['slug'=>'heatmap','name'=>'Form Heatmap','desc'=>'تتبع تفاعل الفورم','icon'=>'🔥','type'=>'enterprise','cat'=>'analytics'],
            // ═══ SECURITY (2) ═══
            ['slug'=>'ip-geo','name'=>'IP Geolocation','desc'=>'كشف IP من دولة مختلفة','icon'=>'🌐','type'=>'pro','cat'=>'security'],
            ['slug'=>'phone-otp','name'=>'Phone OTP','desc'=>'رمز تحقق SMS قبل الطلب','icon'=>'🔐','type'=>'pro','cat'=>'security'],
            // ═══ CHANNELS (2) ═══
            ['slug'=>'telegram-bot','name'=>'Telegram Bot','desc'=>'إدارة الطلبات عبر تلجرام','icon'=>'✈️','type'=>'pro','cat'=>'channels'],
            ['slug'=>'instagram-shop','name'=>'Instagram Shop','desc'=>'ربط مع Instagram Shopping','icon'=>'📸','type'=>'enterprise','cat'=>'channels'],
            // ═══ CUSTOM PRODUCTS (1) ═══
            ['slug'=>'custom-products','name'=>'Custom Products','desc'=>'أبعاد مخصصة + خيارات مدفوعة + رفع ملفات','icon'=>'🏭','type'=>'free','cat'=>'products'],
            // ═══ INTEGRATIONS (7) ═══
            ['slug'=>'google-sheets','name'=>'Google Sheets','desc'=>'مزامنة الطلبات مع Google Sheets','icon'=>'📗','type'=>'pro','cat'=>'integrations'],
            ['slug'=>'zapier-make','name'=>'Zapier / Make','desc'=>'Webhook لربط 5000+ خدمة','icon'=>'🔗','type'=>'pro','cat'=>'integrations'],
            ['slug'=>'tracking-page','name'=>'Tracking Page','desc'=>'صفحة تتبع الطلب للعميل','icon'=>'📍','type'=>'free','cat'=>'integrations'],
            ['slug'=>'reviews','name'=>'Reviews & Ratings','desc'=>'تقييمات العملاء بعد التوصيل','icon'=>'⭐','type'=>'free','cat'=>'integrations'],
            ['slug'=>'popup-form','name'=>'Popup Form','desc'=>'نموذج طلب منبثق','icon'=>'💥','type'=>'pro','cat'=>'marketing'],
            ['slug'=>'email-marketing','name'=>'Email Marketing','desc'=>'Mailchimp / Sendinblue ربط','icon'=>'📧','type'=>'enterprise','cat'=>'integrations'],
            ['slug'=>'crm','name'=>'CRM Integration','desc'=>'HubSpot / Zoho CRM','icon'=>'🗂️','type'=>'enterprise','cat'=>'integrations'],
        ];
        // Merge remote addons (fetched from server, no plugin update needed)
        $remote = self::get_remote_addons();
        if ($remote) {
            $local_slugs = array_column($local, 'slug');
            foreach ($remote as $ra) {
                if (!in_array($ra['slug'], $local_slugs)) $local[] = $ra;
            }
        }
        return $local;
    }

    /**
     * Fetch addons from DZQCOD API — adds new addons for ALL users without plugin update
     * Endpoint: https://dzqcd.nibra.cloud/api/v1/addons
     * Cached for 12 hours in transient
     */
    /** @var string API base URL - hidden from users */
    const API_BASE = 'https://dzqcd.nibra.cloud/api/v1';

    public static function get_remote_addons(): array {
        $cached = get_transient('dzqcod_remote_addons');
        if ($cached !== false) return $cached;
        $url = self::API_BASE . '/addons';
        $resp = wp_remote_get($url, ['timeout' => 10, 'sslverify' => apply_filters('dzqcod_ssl_verify', true), 'headers' => [
            'X-DZQCOD-Version' => \DZQCOD_VER,
            'X-DZQCOD-Site' => home_url(),
            'X-DZQCOD-License' => \DZQCOD\Core::opt('license_key', ''),
        ]]);
        if (is_wp_error($resp) || wp_remote_retrieve_response_code($resp) !== 200) {
            set_transient('dzqcod_remote_addons', [], 3600);
            return [];
        }
        $body = json_decode(wp_remote_retrieve_body($resp), true);
        $addons = $body['addons'] ?? [];
        $valid = [];
        foreach ($addons as $a) {
            if (!empty($a['slug']) && !empty($a['name'])) {
                $valid[] = [
                    'slug' => sanitize_text_field($a['slug']),
                    'name' => sanitize_text_field($a['name']),
                    'desc' => sanitize_text_field($a['desc'] ?? ''),
                    'icon' => sanitize_text_field($a['icon'] ?? '🔌'),
                    'type' => in_array($a['type'] ?? '', ['free','pro','enterprise']) ? $a['type'] : 'pro',
                    'cat'  => sanitize_text_field($a['cat'] ?? 'tools'),
                    'version' => sanitize_text_field($a['version'] ?? '1.0.0'),
                    'remote' => true,
                ];
            }
        }
        set_transient('dzqcod_remote_addons', $valid, 43200);
        return $valid;
    }

    /** Force refresh remote addons cache */
    public function refresh_remote_addons(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        delete_transient('dzqcod_remote_addons');
        $addons = self::get_remote_addons();
        wp_send_json_success(['count' => count($addons), 'message' => 'تم تحديث ' . count($addons) . ' إضافة من السيرفر']);
    }

    /** Check for plugin updates from API */
    public static function check_api_updates(): ?array {
        $resp = wp_remote_get(self::API_BASE . '/check-update', ['timeout' => 10, 'sslverify' => apply_filters('dzqcod_ssl_verify', true), 'headers' => [
            'X-DZQCOD-Version' => \DZQCOD_VER,
            'X-DZQCOD-License' => \DZQCOD\Core::opt('license_key', ''),
        ]]);
        if (is_wp_error($resp) || wp_remote_retrieve_response_code($resp) !== 200) return null;
        return json_decode(wp_remote_retrieve_body($resp), true);
    }

    /** Send analytics ping to API */
    public static function api_ping(string $event, array $data = []): void {
        if (\DZQCOD\Core::opt('analytics_optout', 'no') === 'yes') return;
        wp_remote_post(self::API_BASE . '/ping', ['timeout' => 5, 'blocking' => false, 'sslverify' => apply_filters('dzqcod_ssl_verify', true),
            'body' => wp_json_encode(array_merge($data, ['event' => $event, 'site' => home_url(), 'version' => \DZQCOD_VER])),
            'headers' => ['Content-Type' => 'application/json']]);
    }

    public static function installed_addons(): array {
        global $wpdb;
        $rows = $wpdb->get_results("SELECT slug,is_installed FROM ".$wpdb->prefix.\DZQCOD_DB."addons");
        $m = []; foreach ($rows as $r) $m[$r->slug] = (bool)$r->is_installed; return $m;
    }

    /** Check if ANY of the given addons is installed. Returns true if at least one is active. */
    public static function any_active(array $slugs): bool {
        $inst = self::installed_addons();
        foreach ($slugs as $s) { if (!empty($inst[$s])) return true; }
        return false;
    }

    /** Render a "page locked" message with link to addon store. Returns HTML string. */
    public static function addon_gate(array $slugs, string $page_title): string {
        if (self::any_active($slugs)) return '';
        $all = self::get_addons();
        $names = [];
        foreach ($all as $a) { if (in_array($a['slug'], $slugs)) $names[] = $a['icon'].' '.$a['name']; }
        $list = implode('، ', $names) ?: implode(', ', $slugs);
        return '<div class="wrap dza-wrap" dir="rtl">' . self::_nav_include() .
            '<div class="dza-header"><h1>'.$page_title.'</h1></div><div class="dza-content">' .
            '<div class="dza-card" style="text-align:center;padding:48px 24px">' .
            '<div style="font-size:64px;margin-bottom:16px">🔒</div>' .
            '<h2 style="font-size:22px;font-weight:900;color:#1e293b;margin-bottom:8px">هذه الصفحة تتطلب تفعيل إضافة</h2>' .
            '<p style="font-size:14px;color:#64748b;margin-bottom:6px">فعّل أحد الإضافات التالية من متجر الإضافات:</p>' .
            '<p style="font-size:16px;font-weight:700;margin-bottom:20px">'.$list.'</p>' .
            '<a href="'.admin_url('admin.php?page=dzqcod-addons').'" class="dza-btn primary" style="font-size:15px;padding:12px 28px">🧩 متجر الإضافات</a>' .
            '</div></div></div><!--dza-main--></div><!--dza-layout--></div><!--dza-wrap-->';
    }

    private static function _nav_include(): string {
        ob_start(); include __DIR__.'/../templates/nav.php'; return ob_get_clean();
    }

    public function install_addon(): void {
        check_ajax_referer('dzqcod_admin','nonce'); global $wpdb;
        $slug = sanitize_text_field($_POST['slug']??'');
        $is_remote = (int)($_POST['remote']??0);
        $addon = null; foreach (self::get_addons() as $a) { if ($a['slug']===$slug) { $addon=$a; break; } }
        if (!$addon) wp_send_json_error(['message'=>'إضافة غير موجودة: '.$slug]);
        if ($addon['type']==='pro'&&!Core::is_pro()) wp_send_json_error(['message'=>'تحتاج ترقية PRO لتثبيت هذه الإضافة']);
        if ($addon['type']==='enterprise'&&!Core::is_ent()) wp_send_json_error(['message'=>'تحتاج ترقية ENTERPRISE']);

        // Try to download file from NIBRA cloud if remote addon
        $downloaded = false;
        if ($is_remote || !empty($addon['remote']) || !empty($addon['has_file'])) {
            $cloud_url = Core::opt('admin_cloud_url', 'https://dzqcod.nibra.cloud/admin/api/');
            $license = Core::opt('license_key', '');
            $dl_url = rtrim($cloud_url, '/') . '?route=addons/download&slug=' . urlencode($slug) . '&license=' . urlencode($license);
            
            $tmp = download_url($dl_url, 30);
            if (!is_wp_error($tmp)) {
                // Extract/install the file
                $addons_dir = DZQCOD_PATH . 'addons/';
                if (!is_dir($addons_dir)) wp_mkdir_p($addons_dir);
                
                // Check if ZIP
                $finfo = new \finfo(FILEINFO_MIME_TYPE);
                $mime = $finfo->file($tmp);
                
                if ($mime === 'application/zip' || $mime === 'application/x-zip-compressed') {
                    // Extract ZIP into addons/slug/ directory
                    $zip = new \ZipArchive();
                    if ($zip->open($tmp) === true) {
                        $target = $addons_dir . $slug . '/';
                        if (!is_dir($target)) wp_mkdir_p($target);
                        $zip->extractTo($target);
                        $zip->close();
                        $downloaded = true;
                    }
                } else {
                    // Single PHP file
                    copy($tmp, $addons_dir . $slug . '.php');
                    $downloaded = true;
                }
                wp_delete_file($tmp);
            }
        }

        // Save to DB
        $p = $wpdb->prefix.\DZQCOD_DB.'addons';
        $ex = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$p} WHERE slug=%s",$slug));
        $data = ['is_installed'=>1, 'slug'=>$slug, 'name'=>$addon['name'], 'description'=>$addon['desc']??'', 'type'=>$addon['type']];
        if ($ex) $wpdb->update($p, $data, ['slug'=>$slug]);
        else $wpdb->insert($p, $data);

        $msg = 'تم تثبيت ' . $addon['name'];
        if ($downloaded) $msg .= ' ✅ (تم تحميل الملفات من السيرفر)';
        wp_send_json_success(['message'=>$msg, 'downloaded'=>$downloaded]);
    }

    public function toggle_addon(): void {
        check_ajax_referer('dzqcod_admin','nonce'); global $wpdb;
        $slug = sanitize_text_field($_POST['slug']??'');
        $p = $wpdb->prefix.\DZQCOD_DB.'addons';
        $cur = (int)$wpdb->get_var($wpdb->prepare("SELECT is_installed FROM {$p} WHERE slug=%s",$slug));
        $wpdb->update($p,['is_installed'=>$cur?0:1],['slug'=>$slug]);
        wp_send_json_success(['message'=>$cur?'تم التعطيل':'تم التفعيل']);
    }

    // ═══ RBAC ═══
    const CAPS = [
        'dzqcod_view_orders'=>'عرض الطلبات','dzqcod_manage_orders'=>'إدارة الطلبات',
        'dzqcod_confirm_orders'=>'تأكيد الطلبات','dzqcod_manage_shipments'=>'إدارة الشحن',
        'dzqcod_view_campaigns'=>'عرض الحملات','dzqcod_manage_offers'=>'إدارة العروض',
        'dzqcod_view_fraud'=>'عرض الاحتيال','dzqcod_manage_addons'=>'إدارة الإضافات',
        'dzqcod_manage_license'=>'الترخيص','dzqcod_manage_settings'=>'الإعدادات',
        'dzqcod_print_orders'=>'طباعة','dzqcod_view_analytics'=>'التقارير',
        'dzqcod_manage_users'=>'المستخدمين','dzqcod_send_messages'=>'إرسال رسائل',
    ];

    public static function get_dzqcod_roles(): array {
        global $wp_roles; $roles = [];
        foreach ($wp_roles->roles as $slug=>$role) {
            $dz = []; foreach (self::CAPS as $c=>$l) { if (!empty($role['capabilities'][$c])) $dz[] = $c; }
            if (!empty($dz)||strpos($slug,'dzqcod_')===0) $roles[$slug] = ['name'=>$role['name'],'caps'=>$dz];
        }
        return $roles;
    }

    public function save_role(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        if (!current_user_can('manage_options')) wp_send_json_error();
        $slug = sanitize_text_field($_POST['role']??'');
        $name = sanitize_text_field($_POST['role_name']??'');
        $caps = (array)($_POST['caps']??[]);
        if (!$slug||!$name) wp_send_json_error();
        $role = get_role($slug); if (!$role) { add_role($slug,$name,['read'=>true]); $role = get_role($slug); }
        foreach (self::CAPS as $c=>$l) { if (in_array($c,$caps)) $role->add_cap($c); else $role->remove_cap($c); }
        wp_send_json_success(['message'=>'تم حفظ صلاحيات '.$name]);
    }

    public function delete_role(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        if (!current_user_can('manage_options')) wp_send_json_error();
        $r = sanitize_text_field($_POST['role']??'');
        if (!$r||!strpos($r,'dzqcod_')===0) wp_send_json_error();
        remove_role($r); wp_send_json_success();
    }

    // ═══ WHATSAPP AUTOMATION ═══
    public function wa_on_order(int $oid, $order): void {
        if (Core::opt('wa_auto_new','')!=='yes') return;
        $this->wa_send($order, Core::opt('wa_tpl_new','مرحباً {name}، تم استلام طلبك #{order_id} بقيمة {total}. سنتصل بك قريباً.'));
    }
    public function wa_on_status(int $oid, string $from, string $to, $order): void {
        $st = str_replace('wc-','',$to); $k = 'wa_auto_'.str_replace('-','_',$st);
        if (Core::opt($k,'')!=='yes') return;
        $tpl = Core::opt('wa_tpl_'.str_replace('-','_',$st),''); if ($tpl) $this->wa_send($order,$tpl);
    }
    private function wa_send($order, string $tpl): void {
        if (!$order) return;
        $phone = $order->get_billing_phone(); if (!$phone) return;
        $phone = preg_replace('/^0/','213',preg_replace('/[^0-9]/','',$phone));
        $items = []; foreach ($order->get_items() as $i) $items[] = $i->get_name();
        $msg = str_replace(['{name}','{order_id}','{total}','{wilaya}','{products}','{tracking}'],
            [$order->get_billing_first_name(),$order->get_id(),number_format((float)$order->get_total(),0),$order->get_shipping_state(),implode(', ',$items),$order->get_meta('_dzqcod_tracking_number')?:'-'],$tpl);
        $api = Core::opt('wa_api_url',''); $token = Core::opt('wa_api_token','');
        if ($api&&$token) wp_remote_post($api,['headers'=>['Authorization'=>'Bearer '.$token,'Content-Type'=>'application/json'],'body'=>wp_json_encode(['phone'=>$phone,'message'=>$msg]),'timeout'=>10]);
        global $wpdb; $wpdb->insert($wpdb->prefix.\DZQCOD_DB.'message_logs',['order_id'=>$order->get_id(),'channel'=>'whatsapp','phone'=>$phone,'body'=>$msg,'status'=>($api&&$token)?'sent':'logged']);
    }
    public function wa_send_manual(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        $o = wc_get_order(absint($_POST['order_id']??0)); $msg = sanitize_textarea_field($_POST['message']??'');
        if (!$o||!$msg) wp_send_json_error(); $this->wa_send($o,$msg); wp_send_json_success(['message'=>'تم الإرسال']);
    }
    public function wa_save_templates(): void {
        check_ajax_referer('dzqcod_admin','nonce'); if (!current_user_can('manage_options')) wp_send_json_error();
        foreach ($_POST['settings']??[] as $k=>$v) { if (strpos($k,'wa_')===0) update_option('dzqcod_'.sanitize_key($k),sanitize_text_field($v),false); }
        wp_send_json_success(['message'=>'تم الحفظ']);
    }

    // ═══ CHARGILY ═══
    public function chargily_save(): void {
        check_ajax_referer('dzqcod_admin','nonce');
        if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'صلاحيات غير كافية']);
        foreach (['chargily_key','chargily_secret','chargily_mode'] as $k) update_option('dzqcod_'.$k,sanitize_text_field($_POST[$k]??''),false);
        update_option('dzqcod_chargily_enabled',isset($_POST['enabled'])?'yes':'no',false);
        wp_send_json_success(['message'=>'تم حفظ Chargily']);
    }
    public static function chargily_create(int $oid): ?string {
        $o = wc_get_order($oid); if (!$o) return null;
        $secret = Core::opt('chargily_secret',''); if (!$secret) return null;
        $mode = Core::opt('chargily_mode','test');
        $base = $mode==='live'?'https://pay.chargily.net/api/v2':'https://pay.chargily.net/test/api/v2';
        $r = wp_remote_post($base.'/checkouts',['headers'=>['Authorization'=>'Bearer '.$secret,'Content-Type'=>'application/json'],
            'body'=>wp_json_encode(['amount'=>(float)$o->get_total(),'currency'=>'dzd','description'=>'طلب #'.$oid,
            'success_url'=>add_query_arg(['dzqcod_pay'=>'ok','oid'=>$oid],home_url()),
            'failure_url'=>add_query_arg(['dzqcod_pay'=>'fail','oid'=>$oid],home_url()),
            'webhook_endpoint'=>admin_url('admin-ajax.php?action=dzqcod_chargily_webhook'),
            'metadata'=>['order_id'=>$oid]]),'timeout'=>15]);
        if (is_wp_error($r)) return null;
        $b = json_decode(wp_remote_retrieve_body($r),true); return $b['checkout_url']??null;
    }
    public function chargily_webhook(): void {
        $raw_body = WP_REST_Server::get_raw_data();
        // 1. Signature validation (Chargily sends X-Signature header with HMAC-SHA256)
        $secret = Core::opt('chargily_secret', '');
        if ($secret) {
            $sig = sanitize_text_field($_SERVER['HTTP_SIGNATURE'] ?? $_SERVER['HTTP_X_SIGNATURE'] ?? '');
            if (!$sig) wp_die('Missing signature', '', ['response' => 401]);
            $expected = hash_hmac('sha256', $raw_body, $secret);
            if (!hash_equals($expected, $sig)) wp_die('Invalid signature', '', ['response' => 403]);
        }
        // 2. Parse and validate payload
        $d = json_decode($raw_body, true);
        if (!$d || !isset($d['data']['metadata']['order_id'])) wp_die('Bad request', '', ['response' => 400]);
        $order_id = absint($d['data']['metadata']['order_id']);
        $o = wc_get_order($order_id);
        if (!$o) wp_die('Order not found', '', ['response' => 404]);
        // 3. Prevent replay: check if already processed
        $checkout_id = sanitize_text_field($d['data']['id'] ?? '');
        if ($o->get_meta('_chargily_checkout_id') === $checkout_id) wp_die('Already processed', '', ['response' => 200]);
        // 4. Process payment
        $status = sanitize_key($d['data']['status'] ?? '');
        if ($status === 'paid') {
            $o->payment_complete($checkout_id);
            $o->update_meta_data('_chargily_checkout_id', $checkout_id);
            $o->add_order_note('💳 Chargily: تم الدفع — ' . $checkout_id);
            $o->save();
        } elseif ($status === 'failed') {
            $o->update_status('failed');
            $o->add_order_note('❌ Chargily: فشل الدفع');
            $o->save();
        }
        // 5. Rate limit log
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log("DZQCOD Chargily webhook: order={$order_id} status={$status} checkout={$checkout_id}");
        }
        wp_die('OK', '', ['response' => 200]);
    }

    // ═══ DIGITAL DELIVERY ═══
    public function digital_delivery(int $oid, string $from, string $to, $order): void {
        if ($to!=='wc-delivered'&&$to!=='wc-confirmed') return;
        foreach ($order->get_items() as $item) {
            $pid = $item->get_product_id();
            if (get_post_meta($pid,'_dzqcod_digital',true)!=='yes') continue;
            $url = get_post_meta($pid,'_dzqcod_download_url',true); if (!$url) continue;
            $token = wp_generate_uuid4();
            update_post_meta($oid,'_dzqcod_dl_token_'.$pid,$token);
            update_post_meta($oid,'_dzqcod_dl_remaining_'.$pid,(int)get_post_meta($pid,'_dzqcod_download_limit',true)?:5);
            $order->add_order_note(sprintf('💾 رقمي: %s — جاهز للتحميل',$item->get_name()));
        }
    }

    // ═══ CANVA ═══
    // canva_generate() removed — now in addons/canva.php

    // ═══ i18n ═══
    public function load_textdomain(): void { load_plugin_textdomain('dzqcod',false,dirname(plugin_basename(\DZQCOD_FILE)).'/languages'); }

    const COUNTRIES = [
        'DZ'=>['ar'=>'الجزائر','en'=>'Algeria','cur'=>'DZD','sym'=>'دج','pre'=>'+213','rx'=>'/^0[567]\d{8}$/','wilayas'=>58,'tax'=>0,'flag'=>'🇩🇿','phone_ex'=>'0550123456'],
        'TN'=>['ar'=>'تونس','en'=>'Tunisia','cur'=>'TND','sym'=>'د.ت','pre'=>'+216','rx'=>'/^[2-9]\d{7}$/','wilayas'=>24,'tax'=>19,'flag'=>'🇹🇳','phone_ex'=>'20123456'],
        'MA'=>['ar'=>'المغرب','en'=>'Morocco','cur'=>'MAD','sym'=>'د.م','pre'=>'+212','rx'=>'/^0[5-7]\d{8}$/','wilayas'=>12,'tax'=>20,'flag'=>'🇲🇦','phone_ex'=>'0612345678'],
        'LY'=>['ar'=>'ليبيا','en'=>'Libya','cur'=>'LYD','sym'=>'د.ل','pre'=>'+218','rx'=>'/^09[1-6]\d{7}$/','wilayas'=>22,'tax'=>0,'flag'=>'🇱🇾','phone_ex'=>'0912345678'],
        'EG'=>['ar'=>'مصر','en'=>'Egypt','cur'=>'EGP','sym'=>'ج.م','pre'=>'+20','rx'=>'/^01[0125]\d{8}$/','wilayas'=>27,'tax'=>14,'flag'=>'🇪🇬','phone_ex'=>'01012345678'],
        'SA'=>['ar'=>'السعودية','en'=>'Saudi Arabia','cur'=>'SAR','sym'=>'ر.س','pre'=>'+966','rx'=>'/^05\d{8}$/','wilayas'=>13,'tax'=>15,'flag'=>'🇸🇦','phone_ex'=>'0512345678'],
        'AE'=>['ar'=>'الإمارات','en'=>'UAE','cur'=>'AED','sym'=>'د.إ','pre'=>'+971','rx'=>'/^05\d{8}$/','wilayas'=>7,'tax'=>5,'flag'=>'🇦🇪','phone_ex'=>'0501234567'],
        'IQ'=>['ar'=>'العراق','en'=>'Iraq','cur'=>'IQD','sym'=>'د.ع','pre'=>'+964','rx'=>'/^07[3-9]\d{8}$/','wilayas'=>18,'tax'=>0,'flag'=>'🇮🇶','phone_ex'=>'07701234567'],
        'JO'=>['ar'=>'الأردن','en'=>'Jordan','cur'=>'JOD','sym'=>'د.أ','pre'=>'+962','rx'=>'/^07[789]\d{7}$/','wilayas'=>12,'tax'=>16,'flag'=>'🇯🇴','phone_ex'=>'0791234567'],
    ];
    public static function country(): array { $c = Core::opt('country','DZ'); return self::COUNTRIES[$c]??self::COUNTRIES['DZ']; }
    public static function sym(): string { return self::country()['sym']; }
    public static function pre(): string { return self::country()['pre']; }

    // ═══════════════════════════════════════════
    //  SMS AUTO — Send SMS on order events
    // ═══════════════════════════════════════════
    public function sms_on_order(int $oid, $order): void {
        if (Core::opt('sms_auto_enabled', '') !== 'yes') return;
        $tpl = Core::opt('sms_tpl_new', 'مرحباً {name}، تم استلام طلبك #{order_id} بقيمة {total} {currency}. سنتصل بك قريباً.');
        $this->sms_send($order, $tpl);
    }

    public function sms_on_status(int $oid, string $from, string $to, $order): void {
        if (Core::opt('sms_auto_enabled', '') !== 'yes') return;
        $st = str_replace('wc-', '', $to);
        $tpl = Core::opt('sms_tpl_' . str_replace('-', '_', $st), '');
        if ($tpl) $this->sms_send($order, $tpl);
    }

    private function sms_send($order, string $tpl): void {
        if (!$order) return;
        $phone = $order->get_billing_phone();
        if (!$phone) return;

        // Build message from template
        $items = []; foreach ($order->get_items() as $i) $items[] = $i->get_name();
        $tracking = $order->get_meta('_dzqcod_tracking_number') ?: '-';
        $msg = str_replace(
            ['{name}', '{order_id}', '{total}', '{currency}', '{wilaya}', '{products}', '{tracking}', '{status}'],
            [$order->get_billing_first_name(), $order->get_id(), number_format((float)$order->get_total(), 0),
             self::sym(), $order->get_shipping_state(), implode(', ', $items), $tracking,
             Core::ST[str_replace('wc-', '', $order->get_status())]['l'] ?? $order->get_status()],
            $tpl
        );

        $result = $this->dispatch_sms($phone, $msg);

        // Log
        global $wpdb;
        $wpdb->insert($wpdb->prefix . \DZQCOD_DB . 'message_logs', [
            'order_id' => $order->get_id(), 'channel' => 'sms', 'phone' => $phone,
            'body' => $msg, 'status' => $result['sent'] ? 'sent' : 'failed',
            'template' => substr($tpl, 0, 50)
        ]);
    }

    /**
     * ═══ UNIFIED SMS DISPATCH ═══
     * Single method used by BOTH sms_send() and sms_test()
     * Returns ['sent'=>bool, 'code'=>int, 'body'=>string, 'error'=>string]
     */
    private function dispatch_sms(string $phone, string $msg): array {
        $provider = Core::opt('sms_provider', '');
        if (!$provider) return ['sent'=>false,'code'=>0,'body'=>'','error'=>'لم يتم اختيار مزود SMS'];

        // Read all provider settings
        $key    = Core::opt('sms_api_key', '');
        $secret = Core::opt('sms_api_secret', '');
        $sender = Core::opt('sms_sender_id', 'DZQCOD');
        $sid    = Core::opt('sms_twilio_sid', '');
        $from   = Core::opt('sms_from_number', '');
        $handle = Core::opt('sms_budgetsms_handle', '');
        $url    = Core::opt('sms_api_url', '');

        if (!$key && $provider !== 'generic') return ['sent'=>false,'code'=>0,'body'=>'','error'=>'API Key فارغ'];

        // Format phone to international
        $country = self::country();
        $prefix = str_replace('+', '', $country['pre']);
        $raw = preg_replace('/[^0-9]/', '', $phone);
        $intl = preg_replace('/^0/', $prefix, $raw);

        $r = null;

        switch ($provider) {
            case 'twilio':
                $account = $sid ?: $key;
                $token = $secret ?: $key;
                if (!$from) return ['sent'=>false,'code'=>0,'body'=>'','error'=>'Twilio: رقم المرسل (From) مطلوب'];
                $r = wp_remote_post("https://api.twilio.com/2010-04-01/Accounts/{$account}/Messages.json", [
                    'headers' => ['Authorization' => 'Basic ' . base64_encode($account . ':' . $token)],
                    'body' => ['To' => '+' . $intl, 'From' => $from, 'Body' => $msg],
                    'timeout' => 20
                ]);
                break;

            case 'infobip':
                $base = $url ?: 'https://api.infobip.com';
                $r = wp_remote_post(rtrim($base, '/') . '/sms/2/text/advanced', [
                    'headers' => ['Authorization' => 'App ' . $key, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['messages' => [['destinations' => [['to' => $intl]],
                        'from' => $sender, 'text' => $msg]]]),
                    'timeout' => 20
                ]);
                break;

            case 'sms_to':
                $r = wp_remote_post('https://api.sms.to/sms/send', [
                    'headers' => ['Authorization' => 'Bearer ' . $key, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['to' => '+' . $intl, 'message' => $msg, 'sender_id' => $sender]),
                    'timeout' => 20
                ]);
                break;

            case 'easysendsms':
                $r = wp_remote_post('https://api.easysendsms.app/bulksms', [
                    'body' => ['username' => $key, 'password' => $secret, 'to' => $intl,
                               'text' => $msg, 'from' => $sender, 'type' => '0'],
                    'timeout' => 20
                ]);
                break;

            case 'budgetsms':
                $r = wp_remote_get(add_query_arg([
                    'username' => $key, 'userid' => $secret,
                    'handle' => $handle ?: $key, 'to' => $intl,
                    'msg' => $msg, 'from' => $sender,
                ], 'https://api.budgetsms.net/sendsms/'), ['timeout' => 20]);
                break;

            case 'sendsmsgate':
                $r = wp_remote_post('https://api.sendsmsgate.com/v1/sms/send', [
                    'headers' => ['Authorization' => 'Bearer ' . $key, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['phone' => '+' . $intl, 'message' => $msg, 'sender' => $sender]),
                    'timeout' => 20
                ]);
                break;

            case 'sobersys':
                $r = wp_remote_post('https://app.sobersys.com/api/sms/send', [
                    'headers' => ['Authorization' => 'Bearer ' . $key, 'Content-Type' => 'application/json', 'Accept' => 'application/json'],
                    'body' => wp_json_encode(['to' => $intl, 'message' => $msg, 'from' => $sender]),
                    'timeout' => 20
                ]);
                break;

            case 'plivo':
                $r = wp_remote_post("https://api.plivo.com/v1/Account/{$key}/Message/", [
                    'headers' => ['Authorization' => 'Basic ' . base64_encode($key . ':' . $secret), 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['src' => $sender, 'dst' => $intl, 'text' => $msg]),
                    'timeout' => 20
                ]);
                break;

            case 'bulksms':
                $r = wp_remote_post('https://api.bulksms.com/v1/messages', [
                    'headers' => ['Authorization' => 'Basic ' . base64_encode($key . ':' . $secret), 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['to' => '+' . $intl, 'body' => $msg, 'from' => $sender]),
                    'timeout' => 20
                ]);
                break;

            case 'victorylink':
                $ep = $url ?: 'https://smsvas.vlserv.com/KannelSending/service.asmx/SendSMS';
                $r = wp_remote_post($ep, [
                    'body' => ['api_id' => $key, 'api_password' => $secret, 'sms_type' => '3',
                               'encoding' => 'UTF8', 'phonenumber' => $intl,
                               'textmessage' => $msg, 'sender_id' => $sender],
                    'timeout' => 20
                ]);
                break;

            case 'smspm':
                $r = wp_remote_get(add_query_arg([
                    'apikey' => $key, 'apisecret' => $secret,
                    'to' => $intl, 'from' => $sender, 'text' => $msg,
                ], 'https://api.smspm.com/sms/send'), ['timeout' => 20]);
                break;

            case 'messaggio':
                $r = wp_remote_post('https://msg.messaggio.com/api/v1/send', [
                    'headers' => ['Authorization' => 'Bearer ' . $key, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['phone' => '+' . $intl, 'text' => $msg, 'channel' => 'sms', 'from' => $sender]),
                    'timeout' => 20
                ]);
                break;

            case 'generic':
                if (!$url) return ['sent'=>false,'code'=>0,'body'=>'','error'=>'Generic: رابط API مطلوب'];
                $r = wp_remote_post($url, [
                    'headers' => ['Authorization' => 'Bearer ' . $key, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['to' => '+' . $intl, 'phone' => $intl, 'message' => $msg,
                        'text' => $msg, 'from' => $sender, 'api_key' => $key, 'sender_id' => $sender]),
                    'timeout' => 20
                ]);
                break;

            default:
                return ['sent'=>false,'code'=>0,'body'=>'','error'=>'مزود غير معروف: '.$provider];
        }

        if (is_wp_error($r)) {
            return ['sent'=>false,'code'=>0,'body'=>'','error'=>$r->get_error_message()];
        }

        $code = (int)wp_remote_retrieve_response_code($r);
        $body = wp_remote_retrieve_body($r);

        // BudgetSMS uses OK in body not HTTP codes
        if ($provider === 'budgetsms') {
            $sent = stripos($body, 'OK') !== false || $code === 200;
        } else {
            $sent = $code >= 200 && $code < 300;
        }

        return ['sent'=>$sent, 'code'=>$code, 'body'=>$body, 'error'=>'', 'phone_intl'=>$intl, 'provider'=>$provider];
    }

    public function sms_save_config(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if (!current_user_can('manage_options')) wp_send_json_error();
        $keys = ['sms_auto_enabled', 'sms_provider', 'sms_api_key', 'sms_api_secret', 'sms_api_url',
                 'sms_twilio_sid', 'sms_from_number', 'sms_sender_id', 'sms_budgetsms_handle',
                 'sms_tpl_new', 'sms_tpl_confirmed', 'sms_tpl_shipped', 'sms_tpl_delivered', 'sms_tpl_cancelled'];
        foreach ($keys as $k) {
            if (isset($_POST[$k])) update_option('dzqcod_' . $k, sanitize_text_field($_POST[$k]), false);
        }
        wp_send_json_success(['message' => 'تم حفظ إعدادات SMS ✅']);
    }

    public function sms_test(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        $phone = sanitize_text_field($_POST['phone'] ?? '');
        if (!$phone) wp_send_json_error(['message' => 'أدخل رقم الهاتف للاختبار']);

        $provider = Core::opt('sms_provider', '');
        if (!$provider) wp_send_json_error(['message' => 'اختر مزود SMS أولاً من الإعدادات']);

        $msg = '✅ DZQCOD Test — إذا وصلتك هذه الرسالة فإعدادات SMS تعمل بنجاح';
        $result = $this->dispatch_sms($phone, $msg);

        if ($result['sent']) {
            wp_send_json_success(['message' => "تم الإرسال إلى +{$result['phone_intl']} عبر {$result['provider']} ✅ (HTTP {$result['code']})"]);
        } else {
            $detail = $result['error'] ?: mb_substr($result['body'], 0, 200);
            wp_send_json_error(['message' => "فشل ({$result['provider']}): {$detail} [HTTP {$result['code']}]"]);
        }
    }

    //  BARIDIMOB — Manual CCP payment
    // ═══════════════════════════════════════════
    public function baridimob_save(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if (!current_user_can('manage_options')) wp_send_json_error();
        $keys = ['baridimob_enabled', 'baridimob_ccp_number', 'baridimob_ccp_name', 'baridimob_ccp_key',
                 'baridimob_instructions', 'baridimob_auto_confirm'];
        foreach ($keys as $k) {
            if (isset($_POST[$k])) update_option('dzqcod_' . $k, sanitize_text_field($_POST[$k]), false);
        }
        wp_send_json_success(['message' => 'تم حفظ إعدادات بريدي موب ✅']);
    }

    public function baridimob_confirm(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if (!current_user_can('manage_woocommerce')) wp_send_json_error();
        $oid = absint($_POST['order_id'] ?? 0);
        $o = wc_get_order($oid); if (!$o) wp_send_json_error(['message' => 'طلب غير موجود']);
        $ref = sanitize_text_field($_POST['payment_ref'] ?? '');

        $o->payment_complete($ref ?: 'baridimob-' . $oid);
        $o->update_meta_data('_dzqcod_payment_method', 'baridimob');
        $o->update_meta_data('_dzqcod_baridimob_ref', $ref);
        $o->update_meta_data('_dzqcod_baridimob_confirmed_at', current_time('mysql'));
        $o->update_meta_data('_dzqcod_baridimob_confirmed_by', get_current_user_id());
        $o->add_order_note(sprintf('📱 بريدي موب: تم تأكيد الدفع — المرجع: %s', $ref ?: 'يدوي'));
        $o->set_status('wc-confirmed');
        $o->save();
        wp_send_json_success(['message' => '✅ تم تأكيد دفع بريدي موب لطلب #' . $oid]);
    }

    // BaridiMob: show payment instructions in front form
    public static function baridimob_instructions(): string {
        if (Core::opt('baridimob_enabled', '') !== 'yes') return '';
        $ccp = Core::opt('baridimob_ccp_number', '');
        $name = Core::opt('baridimob_ccp_name', '');
        $key = Core::opt('baridimob_ccp_key', '');
        $instr = Core::opt('baridimob_instructions', 'أرسل المبلغ عبر بريدي موب ثم أدخل مرجع العملية');
        if (!$ccp) return '';

        return '<div class="dzqcod-baridimob-info" style="background:#fff3cd;border:1px solid #ffc107;border-radius:10px;padding:12px;margin:10px 0;font-size:13px">'
            . '<div style="font-weight:700;margin-bottom:6px">📱 الدفع عبر بريدي موب</div>'
            . '<div>📋 رقم الحساب CCP: <strong style="direction:ltr;display:inline-block;font-family:monospace;font-size:15px">' . esc_html($ccp) . '</strong></div>'
            . ($key ? '<div>🔑 المفتاح: <strong style="font-family:monospace">' . esc_html($key) . '</strong></div>' : '')
            . ($name ? '<div>👤 باسم: <strong>' . esc_html($name) . '</strong></div>' : '')
            . '<div style="margin-top:6px;color:#856404">' . esc_html($instr) . '</div>'
            . '<div style="margin-top:8px"><label style="font-size:12px;font-weight:600">مرجع العملية (اختياري)</label>'
            . '<input type="text" name="dzqcod_baridimob_ref" placeholder="رقم العملية من بريدي موب" '
            . 'style="width:100%;padding:8px;border:1px solid #ddd;border-radius:6px;margin-top:4px"></div></div>';
    }
}
