<?php
/**
 * کلاس امنیت چندلایه Dima Shop
 */
if (!defined('ABSPATH')) exit;

class Dima_Security {
    
    private static $instance = null;
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        add_action('send_headers', array($this, 'add_security_headers'));
        add_filter('authenticate', array($this, 'limit_login_attempts'), 30, 3);
        add_filter('rest_authentication_errors', array($this, 'protect_rest_api'));
        add_filter('upload_mimes', array($this, 'restrict_upload_mimes'));
        add_filter('the_generator', '__return_empty_string');
        
        if (!defined('DISALLOW_FILE_EDIT')) {
            define('DISALLOW_FILE_EDIT', true);
        }
    }
    
    /**
     * هدرهای امنیتی HTTP
     */
    public function add_security_headers() {
        if (is_admin() || defined('REST_REQUEST')) return;
        
        $headers = array(
            'X-Frame-Options' => 'SAMEORIGIN',
            'X-Content-Type-Options' => 'nosniff',
            'X-XSS-Protection' => '1; mode=block',
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
            'Permissions-Policy' => 'geolocation=(), microphone=(), camera=()',
            'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains'
        );
        
        foreach ($headers as $name => $value) {
            header("{$name}: {$value}");
        }
        
        $csp_domains = array(
            "'self'", "'unsafe-inline'", "'unsafe-eval'",
            'https://www.zarinpal.com', 'https://api.zarinpal.com',
            'https://api.idpay.ir', 'https://bpm.shaparak.ir',
            'https://cdn.tailwindcss.com', 'https://cdn.jsdelivr.net'
        );
        
        $csp = "default-src 'self'; " .
               "script-src " . implode(' ', $csp_domains) . "; " .
               "style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; " .
               "img-src 'self' data: https:; " .
               "font-src 'self' data:; " .
               "connect-src 'self' https://api.zarinpal.com https://api.idpay.ir; " .
               "frame-ancestors 'self';";
        
        header("Content-Security-Policy: " . $csp);
    }
    
    /**
     * محدود کردن تلاش‌های ورود (Brute Force Protection)
     */
    public function limit_login_attempts($user, $username, $password) {
        if (empty($username)) return $user;
        
        $ip = $this->get_client_ip();
        $transient_key = 'dima_login_attempts_' . md5($ip);
        $attempts = get_transient($transient_key);
        
        if ($attempts >= 5) {
            $this->log_security_event('brute_force_blocked', array(
                'ip' => $ip,
                'username' => $username,
                'attempts' => $attempts
            ), 'critical');
            
            return new WP_Error(
                'too_many_attempts',
                '<strong>⚠️ خطای امنیتی:</strong> تعداد تلاش‌های ورود بیش از حد مجاز است. لطفاً ۱۵ دقیقه دیگر تلاش کنید.'
            );
        }
        
        if (is_wp_error($user)) {
            $attempts = $attempts ? $attempts + 1 : 1;
            set_transient($transient_key, $attempts, 15 * MINUTE_IN_SECONDS);
            
            $this->log_security_event('failed_login', array(
                'ip' => $ip,
                'username' => $username
            ), 'warning');
        } else {
            delete_transient($transient_key);
        }
        
        return $user;
    }
    
    /**
     * محافظت از REST API
     */
    public function protect_rest_api($result) {
        if (!empty($result)) return $result;
        
        $protected_routes = array('/wp/v2/users', '/dima/v1/orders', '/dima/v1/security');
        $current_route = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        
        foreach ($protected_routes as $route) {
            if (strpos($current_route, $route) !== false && !is_user_logged_in()) {
                return new WP_Error('rest_forbidden', 'دسترسی غیرمجاز', array('status' => 403));
            }
        }
        
        return $result;
    }
    
    /**
     * محدود کردن انواع فایل‌های قابل آپلود
     */
    public function restrict_upload_mimes($mimes) {
        unset($mimes['svg'], $mimes['swf'], $mimes['exe'], $mimes['php'], $mimes['html'], $mimes['htm'], $mimes['js']);
        return $mimes;
    }
    
    /**
     * دریافت IP واقعی کاربر
     */
    public function get_client_ip() {
        $ip_keys = array(
            'HTTP_CF_CONNECTING_IP',
            'HTTP_X_REAL_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_CLIENT_IP',
            'REMOTE_ADDR'
        );
        
        foreach ($ip_keys as $key) {
            if (!empty($_SERVER[$key])) {
                $ip = explode(',', $_SERVER[$key])[0];
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
        
        return '0.0.0.0';
    }
    
    /**
     * لاگ‌گیری رویدادهای امنیتی
     */
    public function log_security_event($event_type, $data = array(), $severity = 'warning') {
        global $wpdb;
        $table = $wpdb->prefix . 'dima_security_logs';
        
        if ($wpdb->get_var("SHOW TABLES LIKE '{$table}'") !== $table) return;
        
        $wpdb->insert($table, array(
            'event_type' => sanitize_text_field($event_type),
            'severity' => sanitize_text_field($severity),
            'ip_address' => $this->get_client_ip(),
            'user_id' => get_current_user_id(),
            'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field($_SERVER['HTTP_USER_AGENT']) : '',
            'details' => wp_json_encode($data),
            'created_at' => current_time('mysql')
        ));
        
        $this->cleanup_old_logs();
        
        if ($severity === 'critical') {
            $this->notify_admin($event_type, $data);
        }
    }
    
    /**
     * پاکسازی لاگ‌های قدیمی
     */
    private function cleanup_old_logs() {
        global $wpdb;
        $table = $wpdb->prefix . 'dima_security_logs';
        
        $count = $wpdb->get_var("SELECT COUNT(*) FROM {$table}");
        if ($count > 1000) {
            $wpdb->query("DELETE FROM {$table} WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY)");
        }
    }
    
    /**
     * اطلاع‌رسانی به مدیر
     */
    private function notify_admin($event_type, $data) {
        $admin_email = get_option('admin_email');
        $site_name = get_bloginfo('name');
        
        $subject = "🚨 رویداد امنیتی بحرانی - {$site_name}";
        $message = "رویداد: {$event_type}\n";
        $message .= "IP: " . $this->get_client_ip() . "\n";
        $message .= "زمان: " . current_time('mysql') . "\n";
        $message .= "جزئیات:\n" . wp_json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        
        wp_mail($admin_email, $subject, $message);
    }
    
    /**
     * توابع کمکی sanitization
     */
    public static function sanitize_amount($amount) {
        return floatval(preg_replace('/[^0-9.]/', '', $amount));
    }
    
    public static function sanitize_phone($phone) {
        return preg_replace('/[^0-9+]/', '', $phone);
    }
    
    public static function sanitize_postal_code($code) {
        return preg_replace('/[^0-9]/', '', $code);
    }
    
    /**
     * بررسی صحت مبلغ پرداخت
     */
    public static function verify_payment_amount($order_id, $received_amount) {
        global $wpdb;
        $table = $wpdb->prefix . 'dima_orders';
        
        $order = $wpdb->get_row($wpdb->prepare("SELECT final_amount FROM {$table} WHERE id = %d", $order_id));
        if (!$order) return false;
        
        $expected = floatval($order->final_amount);
        $received = floatval($received_amount);
        
        $is_valid = abs($expected - $received) <= 1000;
        
        if (!$is_valid) {
            self::get_instance()->log_security_event('payment_tampering', array(
                'order_id' => $order_id,
                'expected' => $expected,
                'received' => $received
            ), 'critical');
        }
        
        return $is_valid;
    }
    
    /**
     * تولید توکن امن برای تراکنش‌ها
     */
    public static function generate_transaction_token($order_id) {
        $secret = defined('AUTH_KEY') ? AUTH_KEY : 'dima_shop_secret_key';
        return hash_hmac('sha256', $order_id . '|' . time(), $secret);
    }
    
    /**
     * بررسی توکن تراکنش
     */
    public static function verify_transaction_token($order_id, $token, $max_age = 3600) {
        $secret = defined('AUTH_KEY') ? AUTH_KEY : 'dima_shop_secret_key';
        
        for ($i = 0; $i < $max_age; $i += 60) {
            $check = hash_hmac('sha256', $order_id . '|' . (time() - $i), $secret);
            if (hash_equals($check, $token)) return true;
        }
        
        return false;
    }
    
    /**
     * Rate Limiting برای AJAX
     */
    public static function check_rate_limit($action, $max_requests = 30, $period = 60) {
        $user_id = get_current_user_id();
        $ip = self::get_instance()->get_client_ip();
        $key = 'dima_rate_' . md5($action . '_' . ($user_id ?: $ip));
        
        $data = get_transient($key);
        
        if (!$data) {
            $data = array('count' => 0, 'start' => time());
        }
        
        if (time() - $data['start'] > $period) {
            $data = array('count' => 0, 'start' => time());
        }
        
        $data['count']++;
        set_transient($key, $data, $period);
        
        if ($data['count'] > $max_requests) {
            self::get_instance()->log_security_event('rate_limit_exceeded', array(
                'action' => $action,
                'count' => $data['count'],
                'ip' => $ip
            ), 'warning');
            return false;
        }
        
        return true;
    }
}