<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * VMO Email Provisioner - Auto-create email accounts via hosting control panels
 * 
 * Supports:
 * - cPanel (UAPI)
 * - Plesk (XML API)
 * - DirectAdmin (API)
 * - MXroute REST API for VMO QuickLaunch domains on Vultr.com + Cloudflare
 * 
 * For unsupported hosts, directs users to Jarvis AI for guidance.
 * 
 * @since 8.2.0
 */

if (!defined('ABSPATH')) exit;

class VMO_Email_Provisioner {
    private static $instance = null;
    private static $hooks_registered = false;
    
    const OPTION_CREDENTIALS = 'vmo_email_provisioner_credentials';
    const OPTION_PANEL_TYPE = 'vmo_email_provisioner_panel';
    
    // Known managed WordPress hosts that don't support email hosting
    private static $managed_hosts = [
        'wpengine' => 'WP Engine',
        'kinsta' => 'Kinsta',
        'flywheel' => 'Flywheel',
        'pantheon' => 'Pantheon',
        'cloudways' => 'Cloudways',
        'pressable' => 'Pressable',
        'pagely' => 'Pagely',
        'nexcess' => 'Nexcess',
        'convesio' => 'Convesio'
    ];
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function __construct() {
        self::$instance = $this;
        if (self::$hooks_registered) {
            return;
        }
        self::$hooks_registered = true;
        add_action('wp_ajax_vmo_detect_hosting_panel', array($this, 'ajax_detect_hosting_panel'));
        add_action('wp_ajax_vmo_save_panel_credentials', array($this, 'ajax_save_panel_credentials'));
        add_action('wp_ajax_vmo_provision_email_account', array($this, 'ajax_provision_email_account'));
        add_action('wp_ajax_vmo_test_panel_connection', array($this, 'ajax_test_panel_connection'));
        add_action('wp_ajax_vmo_get_panel_status', array($this, 'ajax_get_panel_status'));
    }

    /**
     * Provision multiple consultation-approved mailboxes through the active route.
     * This is the non-AJAX interface used by the business wizard.
     */
    public function provision_emails($user_id, $domain, array $mailboxes, array $options = array()) {
        $user_id = intval($user_id);
        $domain = strtolower(sanitize_text_field((string) $domain));
        if ($user_id <= 0 || empty($domain) || empty($mailboxes)) {
            return array('success' => false, 'error' => 'Missing user, domain, or mailbox list.');
        }

        $credentials = get_option(self::OPTION_CREDENTIALS, array());
        $panel_type = get_option(self::OPTION_PANEL_TYPE, '');
        $route_policy = $this->detect_vultr_cloudflare_mxroute_route($domain);

        if (!empty($route_policy['route_ready'])) {
            $mx_server = trim((string) get_option('vmo_mxroute_server', ''));
            $mx_user = trim((string) get_option('vmo_mxroute_username', ''));
            $mx_key = trim((string) get_option('vmo_mxroute_api_key', ''));
            if ($mx_server !== '' && $mx_user !== '' && $mx_key !== '') {
                $credentials = array(
                    'username' => $mx_user,
                    'api_token' => $this->encrypt_token($mx_key),
                    'panel_url' => $mx_server,
                );
                $panel_type = 'mxroute';
            }
        }

        if (empty($credentials) || empty($panel_type)) {
            return array(
                'success' => false,
                'error' => 'Email provisioning route is not configured. Use QuickLaunch MXroute credentials or connect a supported mail provider first.',
                'route_policy' => $route_policy,
            );
        }

        $created = array();
        $failed = array();
        $quota = max(100, intval($options['quota'] ?? 1024));

        foreach ($mailboxes as $mailbox) {
            $role = sanitize_key((string) ($mailbox['role'] ?? $mailbox['category'] ?? 'general'));
            $email = sanitize_email((string) ($mailbox['email'] ?? ''));
            $local_part = sanitize_user((string) ($mailbox['local_part'] ?? ''), true);
            if (!$email && $local_part) {
                $email = sanitize_email($local_part . '@' . $domain);
            }
            if (!$email || strpos($email, '@') === false) {
                $failed[] = array('role' => $role, 'error' => 'Invalid email address.');
                continue;
            }
            $parts = explode('@', $email);
            $local_part = sanitize_user($parts[0] ?? $role, true);
            $mail_domain = strtolower(sanitize_text_field($parts[1] ?? $domain));
            if ($mail_domain !== $domain) {
                $failed[] = array('role' => $role, 'email' => $email, 'error' => 'Email domain does not match consultation domain.');
                continue;
            }

            $password = (string) ($mailbox['password'] ?? '');
            if ($password === '') {
                $password = $this->generate_secure_password();
            }

            $result = $this->create_email_account($panel_type, $credentials, $local_part, $domain, $password, $quota);
            if (empty($result['success']) && empty($result['already_exists'])) {
                $failed[] = array(
                    'role' => $role,
                    'email' => $email,
                    'error' => $result['message'] ?? 'Unknown provisioning error.',
                );
                continue;
            }

            $settings = $this->get_smtp_settings_for_panel($panel_type, $domain);
            $save_result = $this->save_provisioned_email($email, $role, $domain, $user_id, $panel_type, $password, $settings, $mailbox);
            if (is_wp_error($save_result)) {
                $failed[] = array('role' => $role, 'email' => $email, 'error' => $save_result->get_error_message());
                continue;
            }

            $created[] = array(
                'id' => intval($save_result),
                'role' => $role,
                'email' => $email,
                'provider' => $panel_type,
                'already_exists' => !empty($result['already_exists']),
                'smtp_settings' => $settings,
            );
        }

        return array(
            'success' => empty($failed),
            'created' => $created,
            'failed' => $failed,
            'route_policy' => $route_policy,
            'provider' => $panel_type,
            'error' => !empty($failed) ? 'One or more mailboxes could not be provisioned.' : '',
        );
    }
    
    /**
     * Detect the hosting control panel
     */
    public function ajax_detect_hosting_panel() {
        check_ajax_referer('vmo_builder_nonce', 'security');
        
        $detection = $this->detect_hosting_environment();
        
        wp_send_json_success($detection);
    }
    
    /**
     * Get current panel status and saved credentials (masked)
     */
    public function ajax_get_panel_status() {
        check_ajax_referer('vmo_builder_nonce', 'security');
        
        $panel_type = get_option(self::OPTION_PANEL_TYPE, '');
        $credentials = get_option(self::OPTION_CREDENTIALS, []);

        $has_credentials = !empty($credentials['api_token']) && (
            $panel_type === 'cloudflare' || !empty($credentials['username'])
        );
        
        wp_send_json_success([
            'panel_type' => $panel_type,
            'has_credentials' => $has_credentials,
            'username' => $has_credentials ? $credentials['username'] : '',
            'panel_url' => $has_credentials ? ($credentials['panel_url'] ?? '') : '',
            'last_verified' => $credentials['last_verified'] ?? null
        ]);
    }
    
    /**
     * Detect hosting environment
     */
    private function detect_hosting_environment() {
        $result = [
            'panel_type' => null,
            'panel_url' => null,
            'supports_auto_provision' => false,
            'is_managed_host' => false,
            'managed_host_name' => null,
            'detection_method' => null,
            'domain' => $this->get_site_domain(),
            'route_mode' => 'zoho_manual',
            'route_ready' => false,
            'route_reason' => 'Vultr/Cloudflare/MXroute route not detected. Using Zoho setup.',
            'requires_zoho' => true,
            'route_signals' => []
        ];

        $route_policy = $this->detect_vultr_cloudflare_mxroute_route($result['domain']);
        $result = array_merge($result, $route_policy);

        // Route policy: only users on Vultr + Cloudflare + MXroute path get auto-provisioning.
        if (!empty($result['route_ready'])) {
            $result['panel_type'] = 'cloudflare';
            $result['panel_url'] = 'https://dash.cloudflare.com';
            $result['supports_auto_provision'] = true;
            $result['is_managed_host'] = false;
            $result['managed_host_name'] = null;
            $result['detection_method'] = 'vmo_vultr_cloudflare_mxroute';
            return $result;
        }
        
        // Check for managed WordPress hosts first
        $managed = $this->detect_managed_host();
        if ($managed) {
            $result['is_managed_host'] = true;
            $result['managed_host_name'] = $managed;
            $result['detection_method'] = 'managed_host_signature';
            return $result;
        }
        
        // Keep panel detection for diagnostics, but enforce Zoho route for non-QuickLaunch users.
        $panel = $this->detect_control_panel();
        if ($panel) {
            $result['panel_type'] = $panel['type'];
            $result['panel_url'] = $panel['url'];
            $result['detection_method'] = $panel['method'];
        }
        
        return $result;
    }

    /**
     * Determine if Vultr + Cloudflare + MXroute route is configured and usable.
     */
    private function detect_vultr_cloudflare_mxroute_route($domain) {
        $vultr_key = trim((string) get_option('vmo_vultr_api_key', ''));
        $cf_token = trim((string) get_option('vmo_cloudflare_api_token', ''));
        $mx_server = trim((string) get_option('vmo_mxroute_server', ''));
        $mx_user = trim((string) get_option('vmo_mxroute_username', ''));
        $mx_key = trim((string) get_option('vmo_mxroute_api_key', ''));

        $signals = [
            'vultr_configured' => !empty($vultr_key),
            'cloudflare_configured' => !empty($cf_token),
            'mxroute_configured' => !empty($mx_server) && !empty($mx_user) && !empty($mx_key),
            'dns_check_supported' => class_exists('VMO_DNS_Detector'),
            'cloudflare_dns' => false,
            'dns_host_type' => null
        ];

        if ($signals['dns_check_supported'] && !empty($domain)) {
            $dns = VMO_DNS_Detector::get_instance()->detect_dns_host($domain);
            if (is_array($dns)) {
                $signals['dns_host_type'] = $dns['host_type'] ?? null;
                $signals['cloudflare_dns'] = ($signals['dns_host_type'] === 'cloudflare');
            }
        }

        $keys_ready = $signals['vultr_configured'] && $signals['cloudflare_configured'] && $signals['mxroute_configured'];
        $dns_ready = $signals['cloudflare_dns'] || !$signals['dns_check_supported'];
        $route_ready = $keys_ready && $dns_ready;

        if ($route_ready) {
            return [
                'route_mode' => 'vultr_cloudflare_mxroute',
                'route_ready' => true,
                'route_reason' => 'Vultr/Cloudflare/MXroute route detected. Auto-provisioning is available.',
                'requires_zoho' => false,
                'route_signals' => $signals
            ];
        }

        $reason = 'Vultr/Cloudflare/MXroute route not fully configured. Using Zoho setup.';
        if (!$keys_ready) {
            $reason = 'Missing Vultr, Cloudflare, or MXroute configuration. Using Zoho setup.';
        } elseif (!$dns_ready) {
            $reason = 'Domain is not on Cloudflare DNS yet. Using Zoho setup.';
        }

        return [
            'route_mode' => 'zoho_manual',
            'route_ready' => false,
            'route_reason' => $reason,
            'requires_zoho' => true,
            'route_signals' => $signals
        ];
    }
    
    /**
     * Detect managed WordPress hosts that don't support email
     */
    private function detect_managed_host() {
        // Check server software and environment variables
        $server_software = $_SERVER['SERVER_SOFTWARE'] ?? '';
        $server_name = $_SERVER['SERVER_NAME'] ?? '';
        $document_root = $_SERVER['DOCUMENT_ROOT'] ?? '';
        
        // WP Engine detection
        if (defined('WPE_APIKEY') || 
            strpos($document_root, 'wpe') !== false ||
            getenv('IS_WPE')) {
            return self::$managed_hosts['wpengine'];
        }
        
        // Kinsta detection
        if (defined('KINSTA_CACHE_ZONE') || 
            strpos($document_root, 'kinsta') !== false ||
            getenv('KINSTA_TOOL_SECRET')) {
            return self::$managed_hosts['kinsta'];
        }
        
        // Flywheel detection
        if (defined('FLYWHEEL_CONFIG_DIR') ||
            strpos($document_root, 'flywheel') !== false) {
            return self::$managed_hosts['flywheel'];
        }
        
        // Pantheon detection
        if (defined('PANTHEON_ENVIRONMENT') ||
            getenv('PANTHEON_ENVIRONMENT')) {
            return self::$managed_hosts['pantheon'];
        }
        
        // Cloudflare Detection (DNS Level)
        // If Cloudflare is detected, we can support auto-provisioning via API
        if (class_exists('VMO_DNS_Detector')) {
            $dns = VMO_DNS_Detector::get_instance()->detect_dns_host($this->get_site_domain());
            if (isset($dns['host_type']) && $dns['host_type'] === 'cloudflare') {
                // Cloudflare is technically a DNS host, but we treat it as a provisioner
                // because it has an API. We return null here so it doesn't fail as "Managed Host"
                // but we will catch it in detect_control_panel logic later.
                return null; 
            }
        }
        
        // Cloudways detection
        if (strpos($document_root, 'cloudways') !== false ||
            strpos($server_software, 'cloudways') !== false) {
            return self::$managed_hosts['cloudways'];
        }
        
        // Pressable detection
        if (defined('STARTER_VERSION') && strpos($document_root, 'developer') !== false) {
            return self::$managed_hosts['pressable'];
        }
        
        // Pagely detection
        if (defined('JEOMOMO_STATIC_CDN_URL') ||
            strpos($document_root, 'pagely') !== false) {
            return self::$managed_hosts['pagely'];
        }
        
        // Check for common managed host environment variables
        $env_indicators = [
            'IS_WPE' => 'wpengine',
            'KINSTA_TOOL_SECRET' => 'kinsta',
            'PANTHEON_SITE' => 'pantheon',
        ];
        
        foreach ($env_indicators as $env_var => $host_key) {
            if (getenv($env_var)) {
                return self::$managed_hosts[$host_key];
            }
        }
        
        return null;
    }
    
    /**
     * Detect control panel type
     */
    private function detect_control_panel() {
        $site_url = site_url();
        $parsed = parse_url($site_url);
        $host = $parsed['host'] ?? '';
        $scheme = $parsed['scheme'] ?? 'https';
        
        // VMO: Check for Cloudflare first (API based)
        // If the site is identifying as having Cloudflare DNS, we treat that as our control panel
        if (class_exists('VMO_DNS_Detector')) {
            $dns = VMO_DNS_Detector::get_instance()->detect_dns_host($host);
            if (isset($dns['host_type']) && $dns['host_type'] === 'cloudflare') {
                require_once plugin_dir_path(__FILE__) . 'class-vmo-cloudflare-manager.php';
                return [
                    'type' => 'cloudflare',
                    'url' => 'https://dash.cloudflare.com',
                    'method' => 'dns_api_check'
                ];
            }
        }

        // Get server IP for direct panel access
        $server_ip = $_SERVER['SERVER_ADDR'] ?? gethostbyname($host);
        
        // Common panel ports and paths
        $panels = [
            'cpanel' => [
                'ports' => [2083, 2082],
                'paths' => ['/cpanel', '/.cpanel'],
                'api_path' => ':2083/execute/'
            ],
            'plesk' => [
                'ports' => [8443, 8880],
                'paths' => ['/plesk', '/smb'],
                'api_path' => ':8443/api/v2/'
            ],
            'directadmin' => [
                'ports' => [2222],
                'paths' => ['/CMD_LOGIN'],
                'api_path' => ':2222/CMD_API_'
            ]
        ];
        
        // Method 1: Check for panel files in common locations
        $panel_indicators = [
            'cpanel' => ['/usr/local/cpanel', '/var/cpanel'],
            'plesk' => ['/usr/local/psa', '/opt/psa'],
            'directadmin' => ['/usr/local/directadmin']
        ];
        
        foreach ($panel_indicators as $panel_type => $paths) {
            foreach ($paths as $path) {
                if (@is_dir($path)) {
                    return [
                        'type' => $panel_type,
                        'url' => $this->build_panel_url($host, $panels[$panel_type]['ports'][0]),
                        'method' => 'filesystem'
                    ];
                }
            }
        }
        
        // Method 2: Check for environment variables
        if (getenv('CPANEL') || defined('CPANEL')) {
            return [
                'type' => 'cpanel',
                'url' => $this->build_panel_url($host, 2083),
                'method' => 'environment'
            ];
        }
        
        // Method 3: Try to connect to panel ports (with short timeout)
        foreach ($panels as $panel_type => $config) {
            foreach ($config['ports'] as $port) {
                $test_url = "{$scheme}://{$host}:{$port}/";
                
                $response = wp_remote_head($test_url, [
                    'timeout' => 3,
                    'sslverify' => false,
                    'redirection' => 0
                ]);
                
                if (!is_wp_error($response)) {
                    $code = wp_remote_retrieve_response_code($response);
                    if ($code >= 200 && $code < 500) {
                        return [
                            'type' => $panel_type,
                            'url' => $test_url,
                            'method' => 'port_probe'
                        ];
                    }
                }
            }
        }
        
        // Method 4: Check server headers for panel signatures
        $headers = function_exists('apache_response_headers') ? apache_response_headers() : [];
        $server_signature = $_SERVER['SERVER_SIGNATURE'] ?? '';
        
        if (stripos($server_signature, 'cpanel') !== false || 
            stripos($server_signature, 'whm') !== false) {
            return [
                'type' => 'cpanel',
                'url' => $this->build_panel_url($host, 2083),
                'method' => 'server_signature'
            ];
        }
        
        if (stripos($server_signature, 'plesk') !== false) {
            return [
                'type' => 'plesk',
                'url' => $this->build_panel_url($host, 8443),
                'method' => 'server_signature'
            ];
        }
        
        return null;
    }
    
    /**
     * Build panel URL
     */
    private function build_panel_url($host, $port) {
        return "https://{$host}:{$port}/";
    }
    
    /**
     * Get site domain
     */
    private function get_site_domain() {
        $site_url = site_url();
        $parsed = parse_url($site_url);
        return $parsed['host'] ?? '';
    }
    
    /**
     * Save panel credentials
     */
    public function ajax_save_panel_credentials() {
        check_ajax_referer('vmo_builder_nonce', 'security');
        
        $panel_type = sanitize_text_field($_POST['panel_type'] ?? '');
        $username = sanitize_text_field($_POST['username'] ?? '');
        $api_token = sanitize_text_field($_POST['api_token'] ?? '');
        $panel_url = esc_url_raw($_POST['panel_url'] ?? '');

        $requires_username = ($panel_type !== 'cloudflare');

        if (empty($panel_type) || empty($api_token) || ($requires_username && empty($username))) {
            wp_send_json_error(['message' => 'Missing required credentials']);
            return;
        }

        if ($panel_type === 'cloudflare') {
            if (empty($username)) {
                $username = 'cloudflare';
            }
            if (empty($panel_url)) {
                $panel_url = 'https://dash.cloudflare.com';
            }
        }
        
        // Test the connection first
        $test_result = $this->test_panel_connection($panel_type, $username, $api_token, $panel_url);
        
        if (!$test_result['success']) {
            wp_send_json_error([
                'message' => 'Connection test failed: ' . $test_result['message'],
                'details' => $test_result
            ]);
            return;
        }
        
        // Save credentials (encrypted)
        $credentials = [
            'username' => $username,
            'api_token' => $this->encrypt_token($api_token),
            'panel_url' => $panel_url,
            'last_verified' => current_time('mysql'),
            'verified_by' => get_current_user_id()
        ];
        
        update_option(self::OPTION_CREDENTIALS, $credentials, false);
        update_option(self::OPTION_PANEL_TYPE, $panel_type, false);
        
        wp_send_json_success([
            'message' => 'Credentials saved and verified successfully',
            'panel_type' => $panel_type,
            'capabilities' => $test_result['capabilities'] ?? []
        ]);
    }
    
    /**
     * Test panel connection
     */
    public function ajax_test_panel_connection() {
        check_ajax_referer('vmo_builder_nonce', 'security');
        
        $panel_type = sanitize_text_field($_POST['panel_type'] ?? '');
        $username = sanitize_text_field($_POST['username'] ?? '');
        $api_token = sanitize_text_field($_POST['api_token'] ?? '');
        $panel_url = esc_url_raw($_POST['panel_url'] ?? '');
        
        $result = $this->test_panel_connection($panel_type, $username, $api_token, $panel_url);
        
        if ($result['success']) {
            wp_send_json_success($result);
        } else {
            wp_send_json_error($result);
        }
    }
    
    /**
     * Test connection to control panel
     */
    private function test_panel_connection($panel_type, $username, $api_token, $panel_url) {
        switch ($panel_type) {
            case 'cpanel':
                return $this->test_cpanel_connection($username, $api_token, $panel_url);
            case 'plesk':
                return $this->test_plesk_connection($username, $api_token, $panel_url);
            case 'cloudflare':
                return $this->test_cloudflare_connection($api_token);
            case 'directadmin':
                return $this->test_directadmin_connection($username, $api_token, $panel_url);
            default:
                return ['success' => false, 'message' => 'Unknown panel type'];
        }
    }
    
    /**
     * Test cPanel connection
     */
    private function test_cpanel_connection($username, $api_token, $panel_url) {
        $api_url = rtrim($panel_url, '/') . '/execute/Email/list_pops';
        
        $response = wp_remote_get($api_url, [
            'headers' => [
                'Authorization' => 'cpanel ' . $username . ':' . $api_token
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return [
                'success' => false,
                'message' => 'Connection failed: ' . $response->get_error_message()
            ];
        }
        
        $code = wp_remote_retrieve_response_code($response);
        $body = json_decode(wp_remote_retrieve_body($response), true);
        
        if ($code === 200 && isset($body['status']) && $body['status'] === 1) {
            return [
                'success' => true,
                'message' => 'Connected to cPanel successfully',
                'capabilities' => ['create_email', 'delete_email', 'list_emails', 'change_password'],
                'existing_emails' => count($body['data'] ?? [])
            ];
        }
        
        // Check for authentication error
        if ($code === 401 || (isset($body['status']) && $body['status'] === 0)) {
            return [
                'success' => false,
                'message' => 'Authentication failed. Check your username and API token.',
                'hint' => 'Generate an API token in cPanel > Security > Manage API Tokens'
            ];
        }
        
        return [
            'success' => false,
            'message' => 'Unexpected response from cPanel (HTTP ' . $code . ')',
            'details' => $body
        ];
    }
    
    /**
     * Test Plesk connection
     */
    private function test_plesk_connection($username, $api_token, $panel_url) {
        $api_url = rtrim($panel_url, '/') . '/api/v2/server';
        
        $response = wp_remote_get($api_url, [
            'headers' => [
                'X-API-Key' => $api_token,
                'Content-Type' => 'application/json'
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return [
                'success' => false,
                'message' => 'Connection failed: ' . $response->get_error_message()
            ];
        }
        
        $code = wp_remote_retrieve_response_code($response);
        
        if ($code === 200) {
            return [
                'success' => true,
                'message' => 'Connected to Plesk successfully',
                'capabilities' => ['create_email', 'delete_email', 'list_emails']
            ];
        }
        
        if ($code === 401 || $code === 403) {
            return [
                'success' => false,
                'message' => 'Authentication failed. Check your API key.',
                'hint' => 'Generate an API key in Plesk > Tools & Settings > API'
            ];
        }
        
        return [
            'success' => false,
            'message' => 'Unexpected response from Plesk (HTTP ' . $code . ')'
        ];
    }
    
    /**
     * Test DirectAdmin connection
     */
    private function test_directadmin_connection($username, $api_token, $panel_url) {
        $api_url = rtrim($panel_url, '/') . '/CMD_API_SHOW_DOMAINS';
        
        $response = wp_remote_get($api_url, [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($username . ':' . $api_token) // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- HTTP Basic auth header
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return [
                'success' => false,
                'message' => 'Connection failed: ' . $response->get_error_message()
            ];
        }
        
        $code = wp_remote_retrieve_response_code($response);
        
        if ($code === 200) {
            return [
                'success' => true,
                'message' => 'Connected to DirectAdmin successfully',
                'capabilities' => ['create_email', 'delete_email', 'list_emails']
            ];
        }
        
        if ($code === 401) {
            return [
                'success' => false,
                'message' => 'Authentication failed. Check your username and login key.',
                'hint' => 'Generate a login key in DirectAdmin > Account Manager > Login Keys'
            ];
        }
        
        return [
            'success' => false,
            'message' => 'Unexpected response from DirectAdmin (HTTP ' . $code . ')'
        ];
    }
    
    /**
     * VMO: Test Cloudflare Connection
     */
    private function test_cloudflare_connection($api_token) {
        if (!class_exists('VMO_Cloudflare_Manager')) {
            require_once plugin_dir_path(__FILE__) . 'class-vmo-cloudflare-manager.php';
        }
        $cf = new VMO_Cloudflare_Manager();
        $cf->set_token($api_token);
        
        $response = $cf->get_zone_id($this->get_site_domain());
        
        if (is_wp_error($response)) {
             return [
                'success' => false,
                'message' => 'Cloudflare connection failed: ' . $response->get_error_message(),
                'hint' => 'Ensure your API Token has Zone.DNS permissions.'
            ];
        }

        return [
            'success' => true,
            'message' => 'Connected to Cloudflare successfully',
            'capabilities' => ['config_dns', 'enable_email_routing']
        ];
    }
    
    /**
     * Provision email account
     */
    public function ajax_provision_email_account() {
        check_ajax_referer('vmo_builder_nonce', 'security');
        
        $email_address = sanitize_email($_POST['email'] ?? '');
        $password = wp_unslash($_POST['password'] ?? '');
        $quota = intval($_POST['quota'] ?? 1024); // Default 1GB
        $category = sanitize_text_field($_POST['category'] ?? 'general');
        
        if (empty($email_address) || !is_email($email_address)) {
            wp_send_json_error(['message' => 'Invalid email address']);
            return;
        }

        // Extract email parts
        $parts = explode('@', $email_address);
        $local_part = $parts[0];
        $domain = $parts[1];
        
        // Get stored credentials
        $credentials = get_option(self::OPTION_CREDENTIALS, []);
        $panel_type = get_option(self::OPTION_PANEL_TYPE, '');

        // Route policy override: when Vultr + Cloudflare + MXroute is ready,
        // create the mailbox through MXroute using the plugin-managed credentials.
        $route_policy = $this->detect_vultr_cloudflare_mxroute_route($domain);
        if (!empty($route_policy['route_ready'])) {
            $mx_server = trim((string) get_option('vmo_mxroute_server', ''));
            $mx_user = trim((string) get_option('vmo_mxroute_username', ''));
            $mx_key = trim((string) get_option('vmo_mxroute_api_key', ''));
            if (!empty($mx_server) && !empty($mx_user) && !empty($mx_key)) {
                $credentials = [
                    'username' => $mx_user,
                    'api_token' => $this->encrypt_token($mx_key),
                    'panel_url' => $mx_server
                ];
                $panel_type = 'mxroute';
            }
        }
        
        if (empty($credentials) || empty($panel_type)) {
            wp_send_json_error([
                'message' => 'Control panel not configured. Please set up your hosting credentials first.'
            ]);
            return;
        }
        
        // Generate password if not provided
        if (empty($password)) {
            $password = $this->generate_secure_password();
        }
        
        // Create the email account
        $result = $this->create_email_account(
            $panel_type,
            $credentials,
            $local_part,
            $domain,
            $password,
            $quota
        );
        
        if ($result['success']) {
            // Save email details to VMO database
            $this->save_provisioned_email($email_address, $category, $domain, get_current_user_id(), $panel_type, $password, $this->get_smtp_settings_for_panel($panel_type, $domain));
            
            wp_send_json_success([
                'message' => 'Email account created successfully',
                'email' => $email_address,
                'password' => $password, // Show once for user to save
                'category' => $category,
                'provider_preset' => $panel_type === 'mxroute' ? 'mxroute' : $panel_type,
                'provisioned_via' => $panel_type,
                'smtp_settings' => $this->get_smtp_settings_for_panel($panel_type, $domain)
            ]);
        } else {
            wp_send_json_error($result);
        }
    }
    
    /**
     * Create email account via control panel API
     */
    private function create_email_account($panel_type, $credentials, $local_part, $domain, $password, $quota) {
        $api_token = $this->decrypt_token($credentials['api_token']);
        $username = $credentials['username'];
        $panel_url = $credentials['panel_url'];
        
        switch ($panel_type) {
            case 'cpanel':
                return $this->create_cpanel_email($username, $api_token, $panel_url, $local_part, $domain, $password, $quota);
            case 'cloudflare':
                 // For Cloudflare, "provisioning" means creating a Routing Rule
                 return $this->create_cloudflare_rule($api_token, $local_part, $domain);
            case 'mxroute':
                return $this->create_mxroute_email($panel_url, $username, $api_token, $local_part, $domain, $password, $quota);
            case 'plesk':
                return $this->create_plesk_email($api_token, $panel_url, $local_part, $domain, $password, $quota);
            case 'directadmin':
                return $this->create_directadmin_email($username, $api_token, $panel_url, $local_part, $domain, $password, $quota);
            default:
                return ['success' => false, 'message' => 'Unknown panel type'];
        }
    }
    
    /**
     * Create email via cPanel UAPI
     */
    private function create_cpanel_email($username, $api_token, $panel_url, $local_part, $domain, $password, $quota) {
        $api_url = rtrim($panel_url, '/') . '/execute/Email/add_pop';
        
        $response = wp_remote_post($api_url, [
            'headers' => [
                'Authorization' => 'cpanel ' . $username . ':' . $api_token,
                'Content-Type' => 'application/x-www-form-urlencoded'
            ],
            'body' => [
                'email' => $local_part,
                'domain' => $domain,
                'password' => $password,
                'quota' => $quota
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return [
                'success' => false,
                'message' => 'API request failed: ' . $response->get_error_message()
            ];
        }
        
        $body = json_decode(wp_remote_retrieve_body($response), true);
        
        if (isset($body['status']) && $body['status'] === 1) {
            return [
                'success' => true,
                'message' => 'Email account created via cPanel'
            ];
        }
        
        // Check for specific errors
        $errors = $body['errors'] ?? [];
        if (!empty($errors)) {
            $error_msg = is_array($errors) ? implode(', ', $errors) : $errors;
            
            // Check if email already exists
            if (stripos($error_msg, 'already exists') !== false) {
                return [
                    'success' => false,
                    'message' => 'This email address already exists',
                    'already_exists' => true
                ];
            }
            
            return ['success' => false, 'message' => $error_msg];
        }
        
        return ['success' => false, 'message' => 'Unknown error creating email account'];
    }
    
    /**
     * Create email via Plesk API
     */
    private function create_plesk_email($api_token, $panel_url, $local_part, $domain, $password, $quota) {
        // First, get the domain ID
        $domain_api = rtrim($panel_url, '/') . '/api/v2/domains?name=' . urlencode($domain);
        
        $domain_response = wp_remote_get($domain_api, [
            'headers' => [
                'X-API-Key' => $api_token,
                'Content-Type' => 'application/json'
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($domain_response)) {
            return ['success' => false, 'message' => 'Failed to fetch domain info'];
        }
        
        $domains = json_decode(wp_remote_retrieve_body($domain_response), true);
        
        if (empty($domains) || !is_array($domains)) {
            return ['success' => false, 'message' => 'Domain not found in Plesk'];
        }
        
        $domain_id = $domains[0]['id'] ?? null;
        
        if (!$domain_id) {
            return ['success' => false, 'message' => 'Could not determine domain ID'];
        }
        
        // Create the email account
        $email_api = rtrim($panel_url, '/') . '/api/v2/cli/mail/create';
        
        $response = wp_remote_post($email_api, [
            'headers' => [
                'X-API-Key' => $api_token,
                'Content-Type' => 'application/json'
            ],
            'body' => json_encode([
                'params' => [
                    '-domain' => $domain,
                    '-name' => $local_part,
                    '-passwd' => $password,
                    '-mailbox' => 'true',
                    '-mbox_quota' => $quota . 'M'
                ]
            ]),
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return ['success' => false, 'message' => 'API request failed: ' . $response->get_error_message()];
        }
        
        $code = wp_remote_retrieve_response_code($response);
        
        if ($code === 200 || $code === 201) {
            return ['success' => true, 'message' => 'Email account created via Plesk'];
        }
        
        $body = json_decode(wp_remote_retrieve_body($response), true);
        return [
            'success' => false,
            'message' => $body['message'] ?? 'Failed to create email account'
        ];
    }
    
    /**
     * Create email via DirectAdmin API
     */
    /**
     * Create Cloudflare Routing Rule
     */
    private function create_cloudflare_rule($api_token, $local_part, $domain) {
        if (!class_exists('VMO_Cloudflare_Manager')) {
            require_once plugin_dir_path(__FILE__) . 'class-vmo-cloudflare-manager.php';
        }
        
        $cf = new VMO_Cloudflare_Manager();
        $cf->set_token($api_token);
        
        // Ensure routing is enabled
        $cf->enable_email_routing($domain);
        
        // Determine destination (default to site admin email)
        $destination = get_option('admin_email');
        
        // Create the rule
        // user@domain.com -> admin_email
        $full_email = "$local_part@$domain";
        $result = $cf->create_routing_rule($domain, 'literal', $full_email, $destination);
        
        if (is_wp_error($result)) {
            return [
                'success' => false,
                'message' => 'Cloudflare Routing Error: ' . $result->get_error_message()
            ];
        }
        
        return [
            'success' => true,
            'message' => "Routing created: $full_email -> $destination",
            'is_forwarder' => true
        ];
    }

    /**
     * Create a real mailbox through MXroute's REST API.
     */
    private function create_mxroute_email($server, $username, $api_key, $local_part, $domain, $password, $quota) {
        $domain_result = $this->mxroute_api('POST', 'domains', array('domain' => $domain), $server, $username, $api_key);
        if (is_wp_error($domain_result)) {
            $message = $domain_result->get_error_message();
            if (stripos($message, '409') === false && stripos($message, 'exists') === false && stripos($message, 'already') === false) {
                return array('success' => false, 'message' => 'MXroute domain error: ' . $message);
            }
        }

        $result = $this->mxroute_api(
            'POST',
            'domains/' . rawurlencode($domain) . '/email-accounts',
            array(
                'user' => $local_part,
                'password' => $password,
                'quota' => max(100, (int) $quota),
            ),
            $server,
            $username,
            $api_key
        );

        if (is_wp_error($result)) {
            $message = $result->get_error_message();
            if (stripos($message, '409') !== false || stripos($message, 'exists') !== false || stripos($message, 'already') !== false) {
                return array('success' => true, 'message' => 'MXroute mailbox already exists', 'already_exists' => true);
            }
            return array('success' => false, 'message' => 'MXroute mailbox error: ' . $message);
        }

        return array(
            'success' => true,
            'message' => 'Email mailbox created via MXroute',
            'server' => $server,
        );
    }

    /**
     * MXroute REST API wrapper.
     */
    private function mxroute_api($method, $endpoint, $body, $server, $username, $api_key) {
        if (empty($server) || empty($username) || empty($api_key)) {
            return new WP_Error('mxroute_missing_config', 'MXroute is not fully configured.');
        }

        $args = array(
            'method' => $method,
            'timeout' => 20,
            'headers' => array(
                'X-Server' => $server,
                'X-Username' => $username,
                'X-API-Key' => $api_key,
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
            ),
        );
        if (!empty($body)) {
            $args['body'] = wp_json_encode($body);
        }

        $response = wp_remote_request('https://api.mxroute.com/' . ltrim($endpoint, '/'), $args);
        if (is_wp_error($response)) {
            return $response;
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $data = json_decode(wp_remote_retrieve_body($response), true);
        if ($code >= 400) {
            $message = is_array($data) ? ($data['error']['message'] ?? ($data['message'] ?? '')) : '';
            return new WP_Error('mxroute_api_error', $message !== '' ? $message : 'MXroute HTTP ' . $code);
        }

        return is_array($data) ? $data : array();
    }

    private function create_directadmin_email($username, $api_token, $panel_url, $local_part, $domain, $password, $quota) {
        $api_url = rtrim($panel_url, '/') . '/CMD_API_POP';
        
        $response = wp_remote_post($api_url, [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($username . ':' . $api_token), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- HTTP Basic auth header
                'Content-Type' => 'application/x-www-form-urlencoded'
            ],
            'body' => [
                'action' => 'create',
                'domain' => $domain,
                'user' => $local_part,
                'passwd' => $password,
                'passwd2' => $password,
                'quota' => $quota
            ],
            'timeout' => 30,
            'sslverify' => false
        ]);
        
        if (is_wp_error($response)) {
            return ['success' => false, 'message' => 'API request failed: ' . $response->get_error_message()];
        }
        
        $body = wp_remote_retrieve_body($response);
        
        // DirectAdmin returns URL-encoded response
        parse_str($body, $result);
        
        if (isset($result['error']) && $result['error'] === '0') {
            return ['success' => true, 'message' => 'Email account created via DirectAdmin'];
        }
        
        return [
            'success' => false,
            'message' => $result['text'] ?? 'Failed to create email account'
        ];
    }
    
    /**
     * Get SMTP settings for panel type
     */
    private function get_smtp_settings_for_panel($panel_type, $domain) {
        if ($panel_type === 'mxroute') {
            $server = trim((string) get_option('vmo_mxroute_server', ''));
            $host = $server !== '' ? $server : 'mail.' . $domain;
            return [
                'type' => 'mailbox',
                'description' => 'MXroute mailbox active for sending and receiving.',
                'vmo_interface' => true,
                'interface_label' => 'VMO Email',
                'smtp_host' => $host,
                'smtp_port' => 587,
                'smtp_secure' => 'tls',
                'imap_host' => $host,
                'imap_port' => 993,
                'pop3_host' => $host,
                'pop3_port' => 995,
                'webmail' => 'https://' . $host . '/roundcube/'
            ];
        }
        if ($panel_type === 'cloudflare') {
            return [
                'type' => 'forwarding',
                'description' => 'Email routing active. Connect SMTP so the VMO Email interface can send from this address.',
                'vmo_interface' => true,
                'interface_label' => 'VMO Email',
                'smtp_host' => 'smtp.gmail.com (Example)',
                'smtp_port' => 587
            ];
        }

        return [
            'type' => 'mailbox',
            'vmo_interface' => true,
            'interface_label' => 'VMO Email',
            'smtp_host' => 'mail.' . $domain,
            'smtp_port' => 587,
            'smtp_secure' => 'tls',
            'imap_host' => 'mail.' . $domain,
            'imap_port' => 993,
            'pop3_host' => 'mail.' . $domain,
            'pop3_port' => 995,
            'webmail' => $this->get_webmail_url($panel_type, $domain)
        ];
    }
    
    /**
     * Get webmail URL
     */
    private function get_webmail_url($panel_type, $domain) {
        switch ($panel_type) {
            case 'cpanel':
                return 'https://' . $domain . ':2096';
            case 'plesk':
                return 'https://webmail.' . $domain;
            case 'directadmin':
                return 'https://' . $domain . '/webmail';
            default:
                return 'https://webmail.' . $domain;
        }
    }
    
    /**
     * Save provisioned email to database
     */
    private function save_provisioned_email($email, $category, $domain, $user_id, $panel_type = null, $password = '', array $settings = array(), array $source = array()) {
        global $wpdb;
        
        $table = $wpdb->prefix . 'vmo_email_accounts';
        
        // Create table if not exists
        $this->maybe_create_email_table();

        $encrypted_password = '';
        if ($password !== '' && function_exists('vmo_encrypt_credential')) {
            $encrypted_password = (string) vmo_encrypt_credential($password);
        }

        $provider = $panel_type ?: get_option(self::OPTION_PANEL_TYPE, 'unknown');
        $payload = array(
            'user_id' => $user_id,
            'email' => $email,
            'email_address' => $email,
            'category' => $category,
            'role' => $category,
            'display_name' => sanitize_text_field((string) ($source['display_name'] ?? ucwords(str_replace(array('_', '-'), ' ', $category)))),
            'domain' => $domain,
            'provider_preset' => $provider,
            'provider_type' => 'provisioned',
            'imap_host' => sanitize_text_field((string) ($settings['imap_host'] ?? '')),
            'imap_port' => intval($settings['imap_port'] ?? 993),
            'smtp_host' => sanitize_text_field((string) ($settings['smtp_host'] ?? '')),
            'smtp_port' => intval($settings['smtp_port'] ?? 587),
            'smtp_secure' => sanitize_key((string) ($settings['smtp_secure'] ?? 'tls')),
            'encrypted_password' => $encrypted_password,
            'verified' => 1,
            'provisioned_at' => current_time('mysql'),
            'provisioned_via' => $provider,
            'status' => 'active',
        );

        if (function_exists('vmo_upsert_email_account')) {
            return vmo_upsert_email_account($user_id, $payload);
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $result = $wpdb->insert($table, $payload);

        if (function_exists('vmo_sync_email_to_sender_identities')) {
            vmo_sync_email_to_sender_identities($user_id, $email, $category, '', 'verified');
        }

        return $result ? intval($wpdb->insert_id) : new WP_Error('email_account_insert_failed', $wpdb->last_error ?: 'Could not save provisioned email.');
    }
    
    /**
     * Create email accounts table
     */
    private function maybe_create_email_table() {
        global $wpdb;
        
        $table = $wpdb->prefix . 'vmo_email_accounts';
        
        if (function_exists('vmo_ensure_email_accounts_table')) {
            vmo_ensure_email_accounts_table();
            return;
        }
        
        $charset = $wpdb->get_charset_collate();
        
        $sql = "CREATE TABLE $table (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            user_id bigint(20) unsigned NOT NULL,
            email_address varchar(255) NOT NULL,
            category varchar(50) DEFAULT 'general',
            domain varchar(255) NOT NULL,
            provisioned_at datetime DEFAULT CURRENT_TIMESTAMP,
            provisioned_via varchar(50) DEFAULT 'unknown',
            status varchar(20) DEFAULT 'active',
            PRIMARY KEY (id),
            KEY user_id (user_id),
            KEY email_address (email_address),
            KEY domain (domain)
        ) $charset;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
    
    /**
     * Generate secure password
     */
    private function generate_secure_password($length = 16) {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
        $password = '';
        
        for ($i = 0; $i < $length; $i++) {
            $password .= $chars[random_int(0, strlen($chars) - 1)];
        }
        
        return $password;
    }
    
    /**
     * Encrypt API token for storage
     */
    private function encrypt_token($token) {
        $key = $this->get_encryption_key();
        $iv = random_bytes(16);
        $encrypted = openssl_encrypt($token, 'AES-256-CBC', $key, 0, $iv);
        return base64_encode($iv . $encrypted); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- encryption/decryption
    }
    
    /**
     * Decrypt API token
     */
    private function decrypt_token($encrypted) {
        $key = $this->get_encryption_key();
        $data = base64_decode($encrypted); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- encryption/decryption
        $iv = substr($data, 0, 16);
        $encrypted_token = substr($data, 16);
        return openssl_decrypt($encrypted_token, 'AES-256-CBC', $key, 0, $iv);
    }
    
    /**
     * Get encryption key
     */
    private function get_encryption_key() {
        $key = get_option('vmo_encryption_key');
        
        if (!$key) {
            $key = base64_encode(random_bytes(32)); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- data encoding
            update_option('vmo_encryption_key', $key, false);
        }
        
        return base64_decode($key); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- data decoding
    }
}

// Initialize
VMO_Email_Provisioner::get_instance();
