<?php
/**
 * The public-facing functionality of the plugin
 *
 * @package SPAI_Contact_Form
 */

class SPAI_Public {
    
    /**
     * The ID of this plugin
     */
    private $plugin_name;
    
    /**
     * The version of this plugin
     */
    private $version;
    
    /**
     * Initialize the class
     */
    public function __construct($plugin_name, $version) {
        $this->plugin_name = $plugin_name;
        $this->version = $version;
    }
    
    /**
     * Register the stylesheets for the public-facing side
     */
    public function enqueue_styles() {
        wp_register_style($this->plugin_name, SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/css/frontend.css', array(), $this->version, 'all');
        
        // Register phone input override styles
        wp_register_style($this->plugin_name . '-phone-input', SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/css/phone-input.css', array('intl-tel-input'), $this->version);
    }
    
    /**
     * Register the JavaScript for the public-facing side
     */
    public function enqueue_scripts() {
        // Register intl-tel-input
        wp_register_script('intl-tel-input', SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/js/vendor/intl-tel-input/js/intlTelInput.min.js', array(), '25.3.1', false);
        wp_register_style('intl-tel-input', SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/css/css/intlTelInput.min.css', array(), '25.3.1');
        
        // Register phone input component
        wp_register_script($this->plugin_name . '-phone-input', SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/js/phone-input.js', array('intl-tel-input'), time(), false);
        
        // Register marketing tracker for site-wide tracking
        wp_register_script($this->plugin_name . '-marketing-tracker', SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/js/marketing-tracker.js', array(), time(), true);
        
        // Register main frontend script
        wp_register_script($this->plugin_name, SPAI_CONTACT_FORM_PLUGIN_URL . 'assets/js/frontend.js', array('jquery', $this->plugin_name . '-phone-input'), time(), false);
        
        // Check if any forms have marketing data fields - if so, enable site-wide tracking
        if ($this->has_marketing_data_fields()) {
            wp_enqueue_script($this->plugin_name . '-marketing-tracker');
        }
        
        // Get settings
        $settings = get_option('spai_contact_form_settings', array(
            'max_file_size' => 10,
            'max_attachments' => 2,
            'allowed_file_types' => array('pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png'),
            'enable_recaptcha' => false,
            'recaptcha_site_key' => '',
            'recaptcha_secret_key' => ''
        ));
        
        // Get PHP limits
        $php_limits = $this->get_php_upload_limits();
        
        // Calculate effective limits (stricter of WordPress settings vs PHP limits)
        $effective_max_size = min($settings['max_file_size'], $php_limits['max_file_size_mb']);
        $effective_max_attachments = min(
            isset($settings['max_attachments']) ? $settings['max_attachments'] : 2,
            $php_limits['max_file_uploads']
        );
        
        // Localize script
        wp_localize_script($this->plugin_name, 'spai_form', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'plugin_url' => SPAI_CONTACT_FORM_PLUGIN_URL,
            'settings' => array(
                'max_file_size' => $effective_max_size,
                'max_attachments' => $effective_max_attachments,
                'allowed_file_types' => $settings['allowed_file_types'],
                'enable_recaptcha' => !empty($settings['enable_recaptcha']),
                'recaptcha_site_key' => !empty($settings['recaptcha_site_key']) ? $settings['recaptcha_site_key'] : ''
            ),
            'php_limits' => $php_limits,
            'strings' => array(
                'submitting' => __('Please wait...', 'spai-contact-form'),
                'success' => __('Thank you for your submission!', 'spai-contact-form'),
                'error' => __('An error occurred. Please try again.', 'spai-contact-form'),
                'file_too_large' => __('File size exceeds maximum allowed size.', 'spai-contact-form'),
                'invalid_file_type' => __('Invalid file type.', 'spai-contact-form'),
                'too_many_files' => __('Maximum number of files exceeded.', 'spai-contact-form'),
                'php_limit_exceeded' => __('File exceeds server upload limit.', 'spai-contact-form'),
                'recaptcha_error' => __('reCAPTCHA verification failed. Please try again.', 'spai-contact-form')
            )
        ));
    }
    
    /**
     * Register shortcode
     */
    public function register_shortcode() {
        add_shortcode('spai_form', array($this, 'render_form_shortcode'));
    }
    
    /**
     * Render form shortcode
     */
    public function render_form_shortcode($atts) {
        $atts = shortcode_atts(array(
            'id' => '',
            'class' => ''
        ), $atts, 'spai_form');
        
        if (empty($atts['id'])) {
            return '<p>' . __('Please specify a form ID.', 'spai-contact-form') . '</p>';
        }
        
        // Get form data
        $db_handler = new SPAI_DB_Handler();
        $form = $db_handler->get_form($atts['id']);
        
        if (!$form || !$form->active) {
            return '<p>' . __('Form not found.', 'spai-contact-form') . '</p>';
        }
        
        // Get form settings for tracking
        $form_settings = json_decode($form->form_settings, true);
        
        // Get global settings for reCAPTCHA
        $global_settings = get_option('spai_contact_form_settings', array());
        
        // Enqueue scripts and styles
        wp_enqueue_style($this->plugin_name);
        wp_enqueue_style('intl-tel-input');
        wp_enqueue_style($this->plugin_name . '-phone-input');
        wp_enqueue_script('intl-tel-input');
        wp_enqueue_script($this->plugin_name . '-phone-input');
        wp_enqueue_script($this->plugin_name);
        
        // Load reCAPTCHA v3 if enabled
        if (!empty($global_settings['enable_recaptcha']) && !empty($global_settings['recaptcha_site_key'])) {
            wp_enqueue_script(
                'google-recaptcha-v3',
                'https://www.google.com/recaptcha/api.js?render=' . $global_settings['recaptcha_site_key'],
                array(),
                null,
                true
            );
        }
        
        // Add form-specific tracking data
        wp_add_inline_script($this->plugin_name, 
            'window.spai_form_' . $atts['id'] . ' = ' . json_encode(array(
                'google_ads_conversion_id' => isset($form_settings['google_ads_conversion_id']) ? $form_settings['google_ads_conversion_id'] : '',
                'google_ads_conversion_label' => isset($form_settings['google_ads_conversion_label']) ? $form_settings['google_ads_conversion_label'] : '',
                'ga4_event_name' => isset($form_settings['ga4_event_name']) ? $form_settings['ga4_event_name'] : 'form_submission'
            )) . ';', 
            'before'
        );
        
        // Render form
        ob_start();
        require SPAI_CONTACT_FORM_PLUGIN_DIR . 'templates/frontend/contact-form.php';
        return ob_get_clean();
    }
    
    /**
     * Ajax handler for form submission
     */
    public function ajax_submit_form() {
        // Verify nonce
        if (!isset($_POST['spai_form_nonce']) || !wp_verify_nonce($_POST['spai_form_nonce'], 'spai_form_submit')) {
            wp_send_json_error(__('Security check failed.', 'spai-contact-form'));
        }
        
        // Check honeypot
        if (!empty($_POST['spai_hp_firstname'])) {
            // Fake success for bots
            wp_send_json_success(array(
                'message' => __('Thank you for your submission!', 'spai-contact-form')
            ));
        }
        
        // Get settings for reCAPTCHA
        $settings = get_option('spai_contact_form_settings', array());
        
        // Verify reCAPTCHA v3 if enabled
        if (!empty($settings['enable_recaptcha']) && !empty($settings['recaptcha_secret_key'])) {
            $recaptcha_token = isset($_POST['recaptcha_token']) ? sanitize_text_field($_POST['recaptcha_token']) : '';
            
            if (empty($recaptcha_token)) {
                wp_send_json_error(__('reCAPTCHA verification failed. Please try again.', 'spai-contact-form'));
            }
            
            // Verify token with Google
            $response = wp_remote_post('https://www.google.com/recaptcha/api/siteverify', array(
                'body' => array(
                    'secret' => $settings['recaptcha_secret_key'],
                    'response' => $recaptcha_token,
                    'remoteip' => $_SERVER['REMOTE_ADDR']
                )
            ));
            
            if (is_wp_error($response)) {
                wp_send_json_error(__('reCAPTCHA verification failed. Please try again.', 'spai-contact-form'));
            }
            
            $body = wp_remote_retrieve_body($response);
            $result = json_decode($body, true);
            
            // Check if verification was successful and score is acceptable (v3)
            if (!$result['success'] || (isset($result['score']) && $result['score'] < 0.5)) {
                wp_send_json_error(__('reCAPTCHA verification failed. Please try again.', 'spai-contact-form'));
            }
        }
        
        $form_id = isset($_POST['spai_form_id']) ? intval($_POST['spai_form_id']) : 0;
        
        if (!$form_id) {
            wp_send_json_error(__('Invalid form.', 'spai-contact-form'));
        }
        
        // Process form data
        $form_data = $this->process_form_data($_POST);
        
        // Process files if any
        $files = isset($_FILES) ? $_FILES : array();
        
        // Handle submission
        $form_handler = new SPAI_Form_Handler();
        $result = $form_handler->process_submission($form_id, $form_data, $files);
        
        if ($result['success']) {
            // Remove 'success' key as wp_send_json_success adds it
            unset($result['success']);
            wp_send_json_success($result);
        } else {
            wp_send_json_error($result['message']);
        }
    }
    
    /**
     * Process form data
     */
    private function process_form_data($post_data) {
        $form_data = array();
        
        // Extract spai_ prefixed fields
        foreach ($post_data as $key => $value) {
            if (strpos($key, 'spai_field_') === 0) {
                $field_name = str_replace('spai_field_', '', $key);
                
                // PHP converts dots to underscores in POST field names automatically
                // We need to convert them back for field names that should have dots
                // Convert underscores to dots for known dotted field patterns
                // BUT exclude direct address field names like address_unit and marketing_data which should stay as is
                if (preg_match('/^(address|metadata)_/', $field_name) && !in_array($field_name, ['address_unit', 'marketing_data'])) {
                    // For address_ and metadata_ prefixes, convert underscores to dots
                    $field_name = preg_replace('/^(address|metadata)_/', '$1.', $field_name);
                    // Also convert any remaining underscores to dots for nested paths
                    $field_name = str_replace('_', '.', $field_name);
                }
                
                $form_data[$field_name] = $this->sanitize_field_value($value);
            }
        }
        
        // Append IP address with geo data to marketing_data if it exists
        if (isset($form_data['marketing_data'])) {
            $ip_with_geo = $this->get_client_ip_with_geo();
            $marketing_data = $form_data['marketing_data'];
            $form_data['marketing_data'] = $marketing_data 
                ? $marketing_data . ', IP: ' . $ip_with_geo 
                : 'IP: ' . $ip_with_geo;
        }
        
        return $form_data;
    }
    
    /**
     * Sanitize field value
     */
    private function sanitize_field_value($value) {
        if (is_array($value)) {
            return array_map(array($this, 'sanitize_field_value'), $value);
        }
        
        return sanitize_text_field($value);
    }
    
    /**
     * Get PHP upload limits
     */
    private function get_php_upload_limits() {
        // Get PHP configuration values
        $max_upload_size = ini_get('upload_max_filesize');
        $max_post_size = ini_get('post_max_size');
        $max_file_uploads = ini_get('max_file_uploads');
        
        // Convert to bytes for comparison
        $max_upload_bytes = $this->convert_to_bytes($max_upload_size);
        $max_post_bytes = $this->convert_to_bytes($max_post_size);
        
        // Effective maximum is the smaller of upload_max_filesize and post_max_size
        $effective_max_bytes = min($max_upload_bytes, $max_post_bytes);
        $effective_max_mb = floor($effective_max_bytes / (1024 * 1024));
        
        return array(
            'upload_max_filesize' => $max_upload_size,
            'post_max_size' => $max_post_size,
            'max_file_uploads' => (int) $max_file_uploads,
            'max_file_size_mb' => $effective_max_mb,
            'max_file_size_bytes' => $effective_max_bytes
        );
    }
    
    /**
     * Convert PHP size notation to bytes
     */
    private function convert_to_bytes($value) {
        $value = trim($value);
        $last = strtolower($value[strlen($value)-1]);
        $value = (int)$value;
        switch($last) {
            case 'g': $value *= 1024;
            case 'm': $value *= 1024;
            case 'k': $value *= 1024;
        }
        return $value;
    }
    
    /**
     * Check if any forms have marketing data fields
     * If so, we need to enable site-wide tracking
     */
    private function has_marketing_data_fields() {
        $db_handler = new SPAI_DB_Handler();
        $forms = $db_handler->get_forms();
        
        foreach ($forms as $form) {
            $form_fields = json_decode($form->form_fields, true);
            if (!$form_fields) {
                continue;
            }
            
            foreach ($form_fields as $field) {
                if (isset($field['name']) && $field['name'] === 'marketing_data') {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * Get client IP address
     */
    private function get_client_ip() {
        $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
        
        foreach ($ip_keys as $key) {
            if (array_key_exists($key, $_SERVER) === true) {
                foreach (explode(',', $_SERVER[$key]) as $ip) {
                    $ip = trim($ip);
                    
                    if (filter_var($ip, FILTER_VALIDATE_IP,
                        FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
                        return $ip;
                    }
                }
            }
        }
        
        return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
    }
    
    /**
     * Get client IP with geo location data
     */
    private function get_client_ip_with_geo() {
        $ip = $this->get_client_ip();
        
        // Skip geo lookup for invalid/local IPs
        if ($ip === '0.0.0.0' || $ip === '127.0.0.1' || $this->is_private_ip($ip)) {
            return $ip;
        }
        
        // Load GeoIP class
        require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/utils/class-spai-geoip.php';
        
        try {
            $geoip = new SPAI_GeoIP();
            return $geoip->format_ip_with_geo($ip);
        } catch (Exception $e) {
            // Return plain IP on any error
            return $ip;
        }
    }
    
    /**
     * Check if IP is private
     */
    private function is_private_ip($ip) {
        return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false;
    }

    /**
     * Check if chat widget should be loaded
     * Quick check without API call - verifies basic prerequisites
     */
    private function should_load_chat_widget() {
        // Skip admin pages
        if (is_admin()) {
            return false;
        }

        // Get SalesPartner settings (need company_id from here)
        $salespartner_settings = get_option('spai_contact_form_salespartner_settings', array());

        // SalesPartner integration must be enabled with valid company_id
        if (empty($salespartner_settings['enabled']) || empty($salespartner_settings['company_id'])) {
            return false;
        }

        // Chat widget must be separately enabled (defaults to enabled for backward compatibility)
        $chat_widget_settings = get_option('spai_contact_form_chat_widget_settings', array('enabled' => true));
        if (empty($chat_widget_settings['enabled'])) {
            return false;
        }

        return true;
    }

    /**
     * Get chat widget enabled status from backend (cached)
     * Uses WordPress transients for 5-minute caching
     */
    private function get_chat_widget_status() {
        $settings = get_option('spai_contact_form_salespartner_settings', array());
        $company_id = $settings['company_id'] ?? '';

        if (empty($company_id)) {
            return array('enabled' => false);
        }

        // Check transient cache (5 minute TTL)
        $cache_key = 'spai_chat_widget_status_' . md5($company_id);
        $cached = get_transient($cache_key);

        if ($cached !== false) {
            return $cached;
        }

        // Fetch from backend API - extract base URL from full api_url setting
        // api_url may contain full path (e.g., .../api/v2/forms/...) but we need just scheme://host
        $api_url = $settings['api_url'] ?? 'https://api.salespartnerai.com';
        $parsed = parse_url($api_url);
        $base_url = ($parsed['scheme'] ?? 'https') . '://' . ($parsed['host'] ?? 'api.salespartnerai.com') . (isset($parsed['port']) ? ':' . $parsed['port'] : '');
        $config_url = $base_url . '/api/v2/chat/config/' . $company_id;

        $response = wp_remote_get($config_url, array(
            'timeout' => 5, // Short timeout to not block page load
            'sslverify' => true
        ));

        // Default to disabled on any error
        if (is_wp_error($response)) {
            $status = array('enabled' => false, 'error' => $response->get_error_message());
            set_transient($cache_key, $status, 180); // Cache errors for 3 minutes
            return $status;
        }

        $status_code = wp_remote_retrieve_response_code($response);

        // 403 = disabled, treat as expected
        if ($status_code === 403) {
            $status = array('enabled' => false);
            set_transient($cache_key, $status, 300); // 5 minutes
            return $status;
        }

        // Success - widget is enabled
        if ($status_code === 200) {
            $body = json_decode(wp_remote_retrieve_body($response), true);
            $status = array(
                'enabled' => true,
                'config' => $body['data']['config'] ?? array()
            );
            set_transient($cache_key, $status, 300); // 5 minutes
            return $status;
        }

        // Other errors
        $status = array('enabled' => false, 'error' => 'HTTP ' . $status_code);
        set_transient($cache_key, $status, 180); // 3 minutes
        return $status;
    }

    /**
     * Output chat widget script in footer
     * Called via wp_footer hook
     *
     * Note: Google Ads tracking (gadsId, gadsLabel) is now configured in the
     * SalesPartner dashboard and loaded via the widget's API call. No need
     * to pass them as data attributes - single source of truth!
     */
    public function maybe_render_chat_widget() {
        if (!$this->should_load_chat_widget()) {
            return;
        }

        $status = $this->get_chat_widget_status();

        if (empty($status['enabled'])) {
            return;
        }

        // Get SalesPartner settings for API URL and company_id
        $salespartner_settings = get_option('spai_contact_form_salespartner_settings', array());
        // Extract base URL from full api_url setting (may contain full path for forms)
        $api_url = $salespartner_settings['api_url'] ?? 'https://api.salespartnerai.com';
        $parsed = parse_url($api_url);
        $base_url = ($parsed['scheme'] ?? 'https') . '://' . ($parsed['host'] ?? 'api.salespartnerai.com') . (isset($parsed['port']) ? ':' . $parsed['port'] : '');
        $company_id = esc_attr($salespartner_settings['company_id']);

        // Output widget script tag - analytics config comes from API
        printf(
            '<script src="%s/chat/widget.js" data-company-id="%s" async></script>',
            esc_url($base_url),
            $company_id
        );
    }
}
