<?php
/**
 * Plugin Name: ایران درگاه
 * Description: مجموعه درگاه‌های پرداخت ایران (زرین پال + سامان)
 * Version: 1.0.0
 * Author: IranDargah
 * Text Domain: irandargah
 * Domain Path: /languages
 * WC requires at least: 3.0
 * WC tested up to: 10.3.5
 * Requires at least: 5.8
 * Tested up to: 6.7.1
 * Requires PHP: 7.4
 * License: GPLv3 or later
 * License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

if (!defined('IRANDARGAH_PLUGIN_DIR')) {
    define('IRANDARGAH_PLUGIN_DIR', plugin_dir_path(__FILE__));
}

if (!defined('IRANDARGAH_PLUGIN_URL')) {
    define('IRANDARGAH_PLUGIN_URL', plugin_dir_url(__FILE__));
}

// بارگذاری ترجمه‌ها در هوک init مطابق توصیه وردپرس 6.7+
add_action('init', function () {
    load_plugin_textdomain('irandargah', false, dirname(plugin_basename(__FILE__)) . '/languages');
});

// نگهداری پیام‌های خطا برای نمایش در ادمین
global $irandargah_setup_warnings;
$irandargah_setup_warnings = [];

/**
 * برخی هاست‌ها کتابخانه Action Scheduler را پیش از تعریف بازهٔ «every_minute»
 * لود نمی‌کنند و وردپرس هنگام زمان‌بندی event اصلی آن (action_scheduler_run_queue)
 * خطای invalid_schedule را لاگ می‌کند. این فیلتر در صورت نبود، آن بازه را
 * اضافه می‌کند تا فعال‌سازی افزونه به خاطر خطای کرون متوقف نشود.
 */
add_filter('cron_schedules', function ($schedules) {
    if (!isset($schedules['every_minute'])) {
        $schedules['every_minute'] = [
            'interval' => 60,
            'display'  => __('Every minute', 'irandargah'),
        ];
    }
    return $schedules;
});

/**
 * بارگذاری امن فایل‌های درگاه؛ در صورت نبود فایل، خطای ادمین نشان می‌دهیم
 * تا افزونه به‌جای Fatal Error، پیام راهنما بدهد.
 */
function irandargah_safe_require($relative_path, $label = '') {
    global $irandargah_setup_warnings;
    $full_path = IRANDARGAH_PLUGIN_DIR . ltrim($relative_path, '/');
    if (file_exists($full_path)) {
        require_once $full_path;
        return true;
    }
    $label_text = $label ?: $relative_path;
    $irandargah_setup_warnings[] = sprintf(
        /* translators: 1: gateway/file label, 2: path */
        __('پرونده %1$s پیدا نشد: %2$s. لطفاً بستهٔ افزونه را کامل و مجدداً بارگذاری کنید.', 'irandargah'),
        $label_text,
        $relative_path
    );
    return false;
}

/**
 * نمایش هشدارهای راه‌اندازی (فایل ناقص یا نبود جدول Action Scheduler)
 */
add_action('admin_notices', function () {
    global $irandargah_setup_warnings;
    if (!current_user_can('manage_options') || empty($irandargah_setup_warnings)) {
        return;
    }
    echo '<div class="notice notice-error"><p>';
    echo implode('<br>', array_map('esc_html', $irandargah_setup_warnings));
    echo '</p></div>';
});

/**
 * چک می‌کند که جداول Action Scheduler ووکامرس ساخته شده باشد؛
 * در صورت نبود، هشدار می‌دهد تا از ابزارهای ووکامرس برای ساخت جداول استفاده شود.
 */
add_action('plugins_loaded', function () {
    global $wpdb, $irandargah_setup_warnings;
    $table = $wpdb->prefix . 'actionscheduler_actions';
    $exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table));
    if ($exists !== $table) {
        $irandargah_setup_warnings[] = __('جداول Action Scheduler در دیتابیس موجود نیست. از ووکامرس > وضعیت > ابزارها، گزینه ساخت جداول برنامه‌ریز را اجرا کنید یا دسترسی CREATE/ALTER دیتابیس را بررسی کنید.', 'irandargah');
    }
});

/**
 * اگر جداول Action Scheduler وجود نداشته باشد، از اجرای آن جلوگیری می‌کنیم
 * تا Fatal Error رخ ندهد و افزونه بتواند فعال شود. پس از ساخت جداول، این
 * فیلتر مانع اجرا نخواهد شد.
 */
add_filter('action_scheduler_pre_init', function ($should_init) {
    global $wpdb, $irandargah_setup_warnings;
    $table = $wpdb->prefix . 'actionscheduler_actions';
    $exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table));
    if ($exists !== $table) {
        $irandargah_setup_warnings[] = __('اجرای Action Scheduler به دلیل نبود جداول متوقف شد. لطفاً جداول را از ووکامرس > وضعیت > ابزارها ایجاد کنید.', 'irandargah');
        return false;
    }
    return $should_init;
}, 5);

if (!function_exists('irandargah_get_gateway_ids')) {
    /**
     * لیست همه کلاس‌های درگاه‌هایی که توسط داشبورد ایران‌درگاه مدیریت می‌شوند
     *
     * این شناسه‌ها همان شناسه‌های مورد استفاده در ووکامرس هستند.
     *
     * @return array
     */
    function irandargah_get_gateway_ids() {
        return [
            'WC_ZPal',                 // زرین‌پال
            'WC_Sep_Payment_Gateway',  // سامان (سپ)
            'WC_aqayepardakht',        // آقای پرداخت
            'WC_bitpayir2',            // بیت‌پی
            'WC_payping',              // پی‌پینگ
            'bahamta_payment_gateway', // باهمتا
            'WC_IDPay',                // آی‌دی‌پی
            'irankish',                // ایران‌کیش
            'bankparsian',             // پارسیان
            'pasargad',                // پاسارگاد
            'rayanpay',                // رایان‌پی
            'melli_pay',               // بانک ملّی
            'pas',                     // سپهرپی (sepehrpay)
            'Fanava',                  // فن‌آوا کارت (بر پایه ووکامرس پارسی)
            'WC_BankMellat',           // بانک ملت
            'WC_NextPay',              // نکست‌پی
            'WC_Payment4',             // پیمنت۴
        ];
    }
}

/**
 * هنگام فعال‌سازی افزونه: همهٔ درگاه‌ها را پیش‌فرض غیرفعال می‌کنیم
 * و تنظیم enabled آن‌ها در ووکامرس را نیز روی "no" می‌گذاریم تا فقط از طریق داشبورد ایران‌درگاه فعال شوند.
 */
register_activation_hook(__FILE__, function () {
    $gateway_ids = irandargah_get_gateway_ids();
    $statuses = [];
    foreach ($gateway_ids as $gateway_id) {
        $statuses[$gateway_id] = 0;
        $option_name = "woocommerce_{$gateway_id}_settings";
        $gateway_settings = get_option($option_name, []);
        $gateway_settings['enabled'] = 'no';
        update_option($option_name, $gateway_settings);
    }
    update_option('irandargah_gateway_statuses', $statuses);
});

// Declare compatibility with WooCommerce features
add_action('before_woocommerce_init', function () {
    if (class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('product_block_editor', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('analytics', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('new_navigation', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('store_api', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('subscriptions', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('subscriptions_update', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('woocommerce-blocks', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('payment_gateway_suggestions', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('order_attribution', __FILE__, true);
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('minified_css', __FILE__, true);
    }
});

// Load Zarinpal gateway
irandargah_safe_require('zarinpal/zarinpal.php', 'زرین‌پال');

// Load SEP gateway
irandargah_safe_require('sep/sep.php', 'سپ سامان');

// Load additional Iranian gateways so they can be managed from IranDargah dashboard.
// آن‌ها را روی هوک plugins_loaded لود می‌کنیم تا ابتدا ووکامرس کلاس‌های خودش را بارگذاری کرده باشد.
add_action('plugins_loaded', function () {
    $gateway_bootstraps = [
        'aqayepardakht/index.php',
        'bitpay/index.php',
        'payping/index.php',
        'bahamta/bahamta-gateway-wooc.php',
        'idpay/woo-idpay-gateway.php',
        'irankish/class-wc-gateway-irankish.php',
        'parsian/parsian-woocommerce.php',
        'pasargad/woocommerce-pasargad.php',
        'rayanpay/rayanpay.php',
        'sepehrpay/wszb-sepehrpay.php',
        'melli/index.php',
        'FanAva/index.php',
        'mellat/index.php',
        'nextpay/index.php',
        'payment4/index.php',
    ];

    foreach ($gateway_bootstraps as $relative_file) {
        $full_path = IRANDARGAH_PLUGIN_DIR . $relative_file;
        if (file_exists($full_path)) {
            require_once $full_path;
        }
    }

    /**
     * برخی درگاه‌ها داخل فایل خودشان، روی هوک plugins_loaded رجیستر می‌شوند.
     * چون ما آن‌ها را همین‌جا (پس از اجرای اولیۀ plugins_loaded) لود می‌کنیم،
     * باید توابع init آن‌ها را دستی فراخوانی کنیم تا فیلترها/کلاس‌ها ثبت شوند.
     */
    $manual_inits = [
        'load_aqayepardakht_woo_gateway',
        'load_payping_woo_gateway',
        'bahamta_payment_gateway_init',
        'wc_gateway_idpay_init',
        'woocommerce_pas_init',
        'init_melli_woocommerce',
        'Load_BankMellat_Gateway',
    ];

    foreach ($manual_inits as $init_fn) {
        if (function_exists($init_fn)) {
            $init_fn();
        }
    }
    
    // اطمینان از ثبت درگاه‌هایی که نیاز به تابع خاصی دارند
    // نکست‌پی
    if (function_exists('Load_NextPay_Gateway') && class_exists('WC_Payment_Gateway') && !class_exists('WC_NextPay')) {
        Load_NextPay_Gateway();
    }
    
    // ایران‌کیش
    if (function_exists('Load_IranKish_Gateway') && class_exists('WC_Payment_Gateway') && !class_exists('WC_Gateway_Irankish')) {
        Load_IranKish_Gateway();
    }
    
    // پاسارگاد
    if (function_exists('woocommerce_pasargad_payment_init') && class_exists('WC_Payment_Gateway')) {
        woocommerce_pasargad_payment_init();
    }
    
    // پارسیان
    if (function_exists('Load_BankParsian_Gateway') && class_exists('WC_Payment_Gateway') && !class_exists('WC_Gateway_Bankparsian')) {
        Load_BankParsian_Gateway();
    }
}, 20);

/**
 * ثبت مرکزی تمام درگاه‌های ایرانی در لیست ووکامرس
 * این فیلتر اطمینان می‌دهد که همه درگاه‌ها در تب "پرداخت" نمایش داده شوند
 */
add_filter('woocommerce_payment_gateways', function($methods) {
    // فقط در پیشخوان این فیلتر را اعمال کن
    if (!is_admin()) {
        return $methods;
    }
    
    // Mapping شناسه درگاه به نام کلاس (برای درگاه‌هایی که ID و نام کلاس متفاوت است)
    $gateway_class_mapping = [
        'irankish' => 'WC_Gateway_Irankish',
        'melli_pay' => 'WC_Gateway_Melli',
        'bankparsian' => 'WC_Gateway_Bankparsian',
        'pasargad' => 'WC_Pasargad_Gateway',
        'rayanpay' => 'WC_RayanPay',
        'pas' => 'WC_pas',
        'Fanava' => 'Woocommerce_Ir_Gateway_Fanava',
    ];
    
    $gateway_ids = irandargah_get_gateway_ids();
    
    foreach ($gateway_ids as $gateway_id) {
        // بررسی اینکه آیا درگاه در لیست است
        $found = false;
        $class_name_to_check = isset($gateway_class_mapping[$gateway_id]) ? $gateway_class_mapping[$gateway_id] : $gateway_id;
        
        foreach ($methods as $method) {
            if (is_object($method)) {
                $method_id = method_exists($method, 'get_id') ? $method->get_id() : (isset($method->id) ? $method->id : '');
                $class_name = get_class($method);
                
                // بررسی بر اساس ID درگاه
                if ($method_id === $gateway_id) {
                    $found = true;
                    break;
                }
                
                // بررسی بر اساس نام کلاس
                if ($class_name === $gateway_id || $class_name === $class_name_to_check) {
                    $found = true;
                    break;
                }
            } elseif (is_string($method)) {
                // اگر رشته است، بررسی بر اساس نام کلاس
                if ($method === $gateway_id || $method === $class_name_to_check) {
                    $found = true;
                    break;
                }
            }
        }
        
        // اگر پیدا نشد، سعی کن کلاس را پیدا کنی و اضافه کنی
        if (!$found) {
            // اول سعی کن با نام کلاس اصلی
            if (class_exists($gateway_id)) {
                $methods[] = $gateway_id;
                $found = true;
            }
            // اگر پیدا نشد، با نام کلاس mapped
            elseif (isset($gateway_class_mapping[$gateway_id]) && class_exists($gateway_class_mapping[$gateway_id])) {
                $methods[] = $gateway_class_mapping[$gateway_id];
                $found = true;
            }
        }
    }
    
    return $methods;
}, 999);

// Load custom Iranian Gateways admin dashboard
if (is_admin()) {
    require_once IRANDARGAH_PLUGIN_DIR . 'admin/dashboard.php';
}

/**
 * مسیریابی تنظیمات درگاه‌ها به داشبورد ایران‌درگاه (جلوگیری از تغییر تنظیمات از صفحه ووکامرس)
 */
add_action('admin_init', function () {
    if (!is_admin()) {
        return;
    }
    $gateway_ids = irandargah_get_gateway_ids();
    $section = isset($_GET['section']) ? sanitize_text_field(wp_unslash($_GET['section'])) : '';
    $tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : '';
    $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';

    if ($page === 'wc-settings' && $tab === 'checkout' && $section && in_array($section, $gateway_ids, true)) {
        wp_safe_redirect(admin_url('admin.php?page=irandargah-dashboard'));
        exit;
    }
});

/**
 * همگام‌سازی وضعیت درگاه‌ها از تنظیمات ووکامرس به irandargah_gateway_statuses
 * این تابع در صورت عدم وجود رکورد در irandargah_gateway_statuses، از تنظیمات ووکامرس استفاده می‌کند
 * 
 * این تابع فقط در پیشخوان اجرا می‌شود تا از بار اضافی در فرانت‌اند جلوگیری شود
 */
add_action('admin_init', function() {
    // فقط یک بار در هر درخواست اجرا شود
    static $synced = false;
    if ($synced) {
        return;
    }
    $synced = true;
    
    $statuses = get_option('irandargah_gateway_statuses', []);
    $gateway_ids = irandargah_get_gateway_ids();

    // اگر وضعیت درگاه در irandargah وجود نداشت، پیش‌فرض غیرفعال قرار بده (0)
    foreach ($gateway_ids as $gateway_id) {
        if (!isset($statuses[$gateway_id])) {
            $statuses[$gateway_id] = 0;
        }
    }
    update_option('irandargah_gateway_statuses', $statuses);

    // وضعیت ایران‌درگاه مرجع است؛ آن را به تنظیمات ووکامرس هم اعمال می‌کنیم
    foreach ($gateway_ids as $gateway_id) {
        $option_name = "woocommerce_{$gateway_id}_settings";
        $gateway_settings = get_option($option_name, []);
        $gateway_settings['enabled'] = (int)$statuses[$gateway_id] === 1 ? 'yes' : 'no';
        update_option($option_name, $gateway_settings);
    }
}, 10);

// AJAX handler for toggling gateway status from Iranian Gateways dashboard
add_action('wp_ajax_irandargah_toggle_gateway', function() {
    check_ajax_referer('irandargah_dashboard_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('دسترسی لازم را ندارید.', 'irandargah')]);
    }

    $gateway_id = isset($_POST['gateway_id']) ? sanitize_text_field(wp_unslash($_POST['gateway_id'])) : '';
    $enabled    = isset($_POST['enabled']) && $_POST['enabled'] === 'yes';

    if (empty($gateway_id)) {
        wp_send_json_error(['message' => __('شناسه درگاه معتبر نیست.', 'irandargah')]);
    }

    if (!class_exists('IranDargah_Settings_Loader')) {
        require_once IRANDARGAH_PLUGIN_DIR . 'admin/inc/settings-loader.php';
    }

    IranDargah_Settings_Loader::toggle_gateway($gateway_id, $enabled);

    wp_send_json_success(['message' => __('وضعیت درگاه تغییر کرد.', 'irandargah')]);
});

/**
 * کنترل نمایش درگاه‌ها در فرانت‌اند: تنها درگاه‌هایی که در داشبورد ایران‌درگاه فعال شده‌اند نمایش داده می‌شوند.
 */
add_filter('woocommerce_available_payment_gateways', function($available) {
    if (is_admin()) {
        return $available;
    }
    if (empty($available) || !is_array($available)) {
        return $available;
    }

    $statuses = get_option('irandargah_gateway_statuses', []);
    $gateway_ids = irandargah_get_gateway_ids();

    foreach ($gateway_ids as $gateway_id) {
        $actual_key = null;

        if (isset($available[$gateway_id])) {
            $actual_key = $gateway_id;
        } else {
            foreach ($available as $key => $gateway) {
                if (is_object($gateway)) {
                    $obj_id = method_exists($gateway, 'get_id') ? $gateway->get_id() : (isset($gateway->id) ? $gateway->id : '');
                    if ($obj_id === $gateway_id) {
                        $actual_key = $key;
                        break;
                    }
                    if (get_class($gateway) === $gateway_id) {
                        $actual_key = $key;
                        break;
                    }
                }
            }
        }

        if ($actual_key === null || !isset($available[$actual_key])) {
            continue;
        }

        $is_enabled = isset($statuses[$gateway_id]) && (int)$statuses[$gateway_id] === 1;
        if (!$is_enabled) {
            unset($available[$actual_key]);
        }
    }

    return $available;
}, 20);

