<?php
/**
 * Central Site Manager - Auth Manager
 * إدارة المصادقة الرئيسية للنظام الفرعي
 * 
 * @package CSM
 * @subpackage Authentication
 * @version 1.0.0
 */

// منع الوصول المباشر
if (!defined('ABSPATH')) {
    exit;
}

class CSM_Auth_Manager extends CSM_Base {
    
    /**
     * إصدار الكلاس
     */
    const VERSION = '1.0.0';
    
    /**
     * الحد الأدنى لإصدار WordPress
     */
    const MIN_WP_VERSION = '5.0';
    
    /**
     * كائن IP Validator
     * @var CSM_IP_Validator
     */
    private $ip_validator;
    
    /**
     * كائن API Key Validator
     * @var CSM_API_Key_Validator
     */
    private $api_key_validator;
    
    /**
     * كائن Rate Limiter
     * @var CSM_Rate_Limiter
     */
    private $rate_limiter;
    
    /**
     * البناء
     */
    public function __construct() {
        parent::__construct();
        $this->init_dependencies();
        $this->setup_hooks();
    }
    
    /**
     * تهيئة التبعيات
     */
    private function init_dependencies() {
        // تحميل الكلاسات المطلوبة
        require_once plugin_dir_path(__FILE__) . 'class-ip-validator.php';
        require_once plugin_dir_path(__FILE__) . 'class-api-key-validator.php';
        require_once plugin_dir_path(__FILE__) . 'class-rate-limiter.php';
        
        // إنشاء الكائنات
        $this->ip_validator         = new CSM_IP_Validator();
        $this->api_key_validator    = new CSM_API_Key_Validator();
        $this->rate_limiter         = new CSM_Rate_Limiter();
        
        // Logger (سيتم تنفيذه لاحقاً)
        $this->logger = class_exists('CSM_Logger') ? new CSM_Logger() : null;
    }
    

    
    /**
     * إعداد الـ Hooks
     */
    private function setup_hooks() {
        // تنظيف مفاتيح API المنتهية الصلاحية يومياً
        if (!wp_next_scheduled('csm_cleanup_expired_keys')) {
            wp_schedule_event(time(), 'daily', 'csm_cleanup_expired_keys');
        }
        add_action('csm_cleanup_expired_keys', [$this, 'cleanup_expired_api_keys']);
        
        // تنظيف محاولات الدخول الفاشلة
        if (!wp_next_scheduled('csm_cleanup_failed_attempts')) {
            wp_schedule_event(time(), 'hourly', 'csm_cleanup_failed_attempts');
        }
        add_action('csm_cleanup_failed_attempts', [$this, 'cleanup_failed_attempts']);
    }
    
    /**
     * التحقق من صحة الطلب
     * 
     * @param WP_REST_Request $request
     * @return bool|WP_Error
     */
    public function validate_request($request, $options = []) {
        $options = wp_parse_args($options, [
            'check_token'      => true,
            'check_rate_limit' => true,
            'check_ip'         => true,
        ]);

        $client_ip = $this->get_client_ip();
        $user_agent = $request->get_header('User-Agent');
        $api_key = $this->extract_api_key($request);

        try {
            // 1. فحص Rate Limiting
            if ($options['check_rate_limit'] && $this->settings['enable_rate_limiting']) {
                $rate_check = $this->rate_limiter->check_rate_limit($client_ip);
                if (is_wp_error($rate_check)) {
                    $this->log_failed_attempt($client_ip, 'rate_limit_exceeded', $user_agent);
                    return $rate_check;
                }
            }

            // 2. فحص IP المسموح
            if ($options['check_ip'] && $this->settings['enable_ip_restriction']) {
                $ip_check = $this->ip_validator->validate_ip($client_ip);
                if (is_wp_error($ip_check)) {
                    $this->log_failed_attempt($client_ip, 'ip_not_allowed', $user_agent);
                    return $ip_check;
                    return new WP_Error(
                        'ip_not_allowed',
                        'عذراً، عنوان IP غير مسموح له بالوصول',
                        ['status' => 403]
                    );
                }
            }

            // 3. التحقق من مفتاح API
            if ($options['check_token']) {
                if (empty($api_key)) {
                    $this->log_failed_attempt($client_ip, 'missing_api_key', $user_agent);
                    return new WP_Error(
                        'missing_api_key',
                        'مفتاح API مطلوب',
                        ['status' => 401]
                    );
                }

                $api_validation = $this->validate_api_key($api_key);
                if (is_wp_error($api_validation)) {
                    $this->log_failed_attempt($client_ip, 'invalid_api_key', $user_agent, [
                        'api_key' => substr($api_key, 0, 8) . '...'
                    ]);
                    return $api_validation;
                }

                // تسجيل نجاح المصادقة
                $this->log_successful_auth($client_ip, $api_key, $user_agent);

                // تحديث آخر استخدام لمفتاح API
                $this->update_api_key_usage($api_key, $client_ip);
            }

            return true;

        } catch (Exception $e) {
            $this->log_error('validation_exception', $e->getMessage(), [
                'client_ip' => $client_ip,
                'user_agent' => $user_agent,
                'trace' => $e->getTraceAsString()
            ]);

            return new WP_Error(
                'auth_system_error',
                'حدث خطأ في نظام المصادقة',
                ['status' => 500]
            );
        }
    }

    /**
     * التحقق من مفتاح API
     * 
     * @param string $api_key
     * @return bool|WP_Error
     */
    public function validate_api_key($api_key) {
        return $this->api_key_validator->validate($api_key);
    }
    
    /**
     * إنشاء مفتاح API جديد
     * 
     * @param string $key1 المفتاح الأول
     * @param string $key2 المفتاح الثاني
     * @return array|WP_Error
     */

    public function authenticate_client($api_key, $api_secret) {

        if (empty($api_key) || empty($api_secret)) {
            return new WP_Error('missing_credentials', 'API key and secret are required.');
        }

        $raw = trim(get_option('csm_slave_auth', ''));

        // تحقق من أن التنسيق يحتوي على ":::"
        if (strpos($raw, ':::') === false) {
            return new WP_Error('invalid_format', 'تنسيق بيانات المصادقة غير صحيح في إعدادات الموقع الفرعي', ['status' => 500]);
        }

        // ADD dynamic text to secret
        date_default_timezone_set('UTC');
        $today_timestamp = strtotime('today');
        $raw .= $today_timestamp;

        list($stored_key1, $stored_key2) = array_map('trim', explode(':::', $raw, 2));

        /* **TODO** Delete error_timestamp from responce */
        if ($stored_key1 !== $api_key || $stored_key2 !== $api_secret) {
            return new WP_Error('invalid_credentials', 'بيانات الدخول غير صحيحة', ['status' => 403, 'error_timestamp' => $today_timestamp]);
        }

        // إنشاء مفتاح API جديد عند المصادقة الناجحة
        $response = $this->api_key_validator->generate_api_key();

        if (is_wp_error($response)) {
            return $response;
        }

        return $response;
    }


    
    /**
     * إلغاء مفتاح API
     * 
     * @param string $api_key
     * @return bool|WP_Error
     */
    public function revoke_api_key($api_key) {
        $result = $this->api_key_validator->revoke_key($api_key);
        
        if ($result) {
            $this->log_info('api_key_revoked', 'تم إلغاء مفتاح API', [
                'api_key_prefix' => substr($api_key, 0, 8)
            ]);
        }
        
        return $result;
    }
    
    /**
     * استخراج مفتاح API من الطلب
     * 
     * @param WP_REST_Request $request
     * @return string|null
     */
    private function extract_api_key($request) {
        // محاولة الحصول من Header
        $api_key = $request->get_header('X-CSM-API-Key');
        
        if (empty($api_key)) {
            // محاولة الحصول من Authorization Header
            $auth_header = $request->get_header('Authorization');
            if (!empty($auth_header) && strpos($auth_header, 'Bearer ') === 0) {
                $api_key = substr($auth_header, 7);
            }
        }
        
        if (empty($api_key)) {
            // محاولة الحصول من Query Parameter (غير مستحسن للأمان)
            $api_key = $request->get_param('api_key');
        }
        
        return $api_key;
    }
    
    /**
     * الحصول على IP العميل
     * 
     * @return string
     */
    private function get_client_ip() {
        $ip_headers = [
            'HTTP_CF_CONNECTING_IP',     // Cloudflare
            'HTTP_CLIENT_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_CLUSTER_CLIENT_IP',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED',
            'REMOTE_ADDR'
        ];
        
        foreach ($ip_headers as $header) {
            if (!empty($_SERVER[$header])) {
                $ip = $_SERVER[$header];
                
                // إذا كان هناك عدة IPs، أخذ الأول
                if (strpos($ip, ',') !== false) {
                    $ip = trim(explode(',', $ip)[0]);
                }
                
                // التحقق من صحة IP
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
        
        return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
    }
    
    
    // /**
    //  * فحص إذا كان IP محظور مؤقتاً
    //  * 
    //  * @param string $ip
    //  * @return bool
    //  */
    // private function is_ip_locked($ip) {
    //     global $wpdb;
        
    //     $table_name = $wpdb->prefix . 'csm_failed_attempts';
        
    //     $failed_attempts = $wpdb->get_var($wpdb->prepare(
    //         "SELECT COUNT(*) FROM {$table_name} 
    //          WHERE ip_address = %s 
    //          AND attempt_time > %s 
    //          AND is_successful = 0",
    //         $ip,
    //         date('Y-m-d H:i:s', time() - $this->settings['lockout_duration'])
    //     ));
        
    //     return $failed_attempts >= $this->settings['max_failed_attempts'];
    // }
    
    /**
     * تسجيل محاولة دخول فاشلة
     * 
     * @param string $ip
     * @param string $reason
     * @param string $user_agent
     * @param array $additional_data
     */
    private function log_failed_attempt($ip, $reason, $user_agent = '', $additional_data = []) {
        global $wpdb;
        
        if (!$this->settings['enable_request_logging']) {
            return;
        }
        
        $table_name = $wpdb->prefix . 'csm_failed_attempts';
        
        $wpdb->insert(
            $table_name,
            [
                'ip_address' => $ip,
                'reason' => $reason,
                'user_agent' => $user_agent,
                'additional_data' => json_encode($additional_data),
                'attempt_time' => current_time('mysql'),
                'is_successful' => 0
            ],
            ['%s', '%s', '%s', '%s', '%s', '%d']
        );
        
        // تسجيل في النظام العام إذا كان متاحاً
        if ($this->logger) {
            $this->logger->log_warning('auth_failed', "محاولة مصادقة فاشلة: {$reason}", [
                'ip' => $ip,
                'user_agent' => $user_agent,
                'additional_data' => $additional_data
            ]);
        }
    }
    
    /**
     * تسجيل مصادقة ناجحة
     * 
     * @param string $ip
     * @param string $api_key
     * @param string $user_agent
     */
    private function log_successful_auth($ip, $api_key, $user_agent = '') {
        if ($this->logger) {
            $this->logger->log_info('auth_success', 'مصادقة ناجحة', [
                'ip' => $ip,
                'api_key_prefix' => substr($api_key, 0, 8),
                'user_agent' => $user_agent
            ]);
        }
    }
    
    /**
     * تحديث استخدام مفتاح API
     * 
     * @param string $api_key
     * @param string $ip
     */
    private function update_api_key_usage($api_key, $ip) {
        $this->api_key_validator->update_key_usage($api_key, $ip);
    }
    
    /**
     * تنظيف مفاتيح API المنتهية الصلاحية
     */
    public function cleanup_expired_api_keys() {
        $cleaned = $this->api_key_validator->cleanup_expired_keys();
        
        if ($cleaned > 0 && $this->logger) {
            $this->logger->log_info('cleanup_expired_keys', "تم حذف {$cleaned} مفتاح API منتهي الصلاحية");
        }
    }
    
    /**
     * تنظيف محاولات الدخول الفاشلة القديمة
     */
    public function cleanup_failed_attempts() {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'csm_failed_attempts';
        
        $deleted = $wpdb->query($wpdb->prepare(
            "DELETE FROM {$table_name} WHERE attempt_time < %s",
            date('Y-m-d H:i:s', time() - (7 * 24 * 3600)) // حذف السجلات الأقدم من أسبوع
        ));
        
        if ($deleted > 0 && $this->logger) {
            $this->logger->log_info('cleanup_failed_attempts', "تم حذف {$deleted} سجل محاولة دخول فاشلة");
        }
    }
    
    /**
     * الحصول على إحصائيات المصادقة
     * 
     * @param int $days عدد الأيام للإحصائيات
     * @return array
     */
    public function get_auth_statistics($days = 30) {
        global $wpdb;
        
        $failed_attempts_table = $wpdb->prefix . 'csm_failed_attempts';
        $since_date = date('Y-m-d H:i:s', time() - ($days * 24 * 3600));
        
        // إحصائيات المحاولات الفاشلة
        $failed_stats = $wpdb->get_results($wpdb->prepare(
            "SELECT reason, COUNT(*) as count 
             FROM {$failed_attempts_table} 
             WHERE attempt_time >= %s 
             GROUP BY reason 
             ORDER BY count DESC",
            $since_date
        ));
        
        // أكثر IPs محاولة للدخول
        $top_ips = $wpdb->get_results($wpdb->prepare(
            "SELECT ip_address, COUNT(*) as attempts 
             FROM {$failed_attempts_table} 
             WHERE attempt_time >= %s 
             GROUP BY ip_address 
             ORDER BY attempts DESC 
             LIMIT 10",
            $since_date
        ));
        
        // إحصائيات مفاتيح API النشطة
        $active_keys_count = $this->api_key_validator->get_active_keys_count();
        
        return [
            'period_days' => $days,
            'failed_attempts' => $failed_stats,
            'top_suspicious_ips' => $top_ips,
            'active_api_keys' => $active_keys_count,
            'generated_at' => current_time('mysql')
        ];
    }
    
    /**
     * تحديث إعدادات المصادقة
     * 
     * @param array $new_settings
     * @return bool
     */
    public function update_settings($new_settings) {
        $this->settings = wp_parse_args($new_settings, $this->settings);
        return update_option('csm_auth_settings', $this->settings);
    }
    

    
}