<?php
/**
 * Form processing handler
 *
 * @package SPAI_Contact_Form
 */

class SPAI_Form_Handler {
    
    /**
     * Database handler instance
     */
    private $db_handler;
    
    /**
     * File handler instance
     */
    private $file_handler;
    
    /**
     * Constructor
     */
    public function __construct() {
        $this->db_handler = new SPAI_DB_Handler();
        $this->file_handler = new SPAI_File_Handler();
    }
    
    /**
     * Process form submission
     */
    public function process_submission($form_id, $form_data, $files = array()) {
        // Get form configuration
        $form = $this->db_handler->get_form($form_id);
        
        if (!$form) {
            return array(
                'success' => false,
                'message' => __('Form not found.', 'spai-contact-form')
            );
        }
        
        $form_fields = json_decode($form->form_fields, true);
        $form_settings = json_decode($form->form_settings, true);
        
        // Validate required fields
        $validation = $this->validate_fields($form_data, $form_fields);
        if (!$validation['success']) {
            return $validation;
        }
        
        // Process file uploads
        $file_data = array();
        if (!empty($files)) {
            $file_results = $this->file_handler->process_uploads($files, $form_id);
            if (!$file_results['success']) {
                return $file_results;
            }
            $file_data = $file_results['files'];
        }
        
        // Prepare submission data
        $submission_data = array(
            'form_id' => $form_id,
            'submission_data' => $form_data,
            'integration_status' => array(),
            'file_data' => $file_data,
            'ip_address' => $this->get_client_ip(),
            'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field($_SERVER['HTTP_USER_AGENT']) : ''
        );
        
        // Save submission
        $submission_id = $this->db_handler->save_submission($submission_data);
        
        if (!$submission_id) {
            return array(
                'success' => false,
                'message' => __('Failed to save submission.', 'spai-contact-form')
            );
        }
        
        // Process integrations synchronously with parallel uploads for speed
        $integration_results = $this->process_integrations($submission_id, $form_data, $file_data, $form_settings);
        
        // Prepare response
        $response = array(
            'success' => true,
            'message' => __('Form submitted successfully.', 'spai-contact-form'),
            'submission_id' => $submission_id,
            'integrations' => $integration_results
        );
        
        // Check if redirect is needed
        if (!empty($form_settings['redirect_url'])) {
            $response['redirect'] = $form_settings['redirect_url'];
        }
        
        return $response;
    }
    
    /**
     * Validate form fields
     */
    private function validate_fields($data, $fields) {
        foreach ($fields as $field) {
            // Skip file fields - they are handled separately via $_FILES
            if ($field['type'] === 'file') {
                continue;
            }
            
            if (spai_is_field_required($field) && empty($data[$field['name']])) {
                return array(
                    'success' => false,
                    'message' => sprintf(__('%s is required.', 'spai-contact-form'), $field['label'])
                );
            }
            
            // Email validation
            if ($field['type'] === 'email' && !empty($data[$field['name']])) {
                if (!is_email($data[$field['name']])) {
                    return array(
                        'success' => false,
                        'message' => sprintf(__('%s must be a valid email address.', 'spai-contact-form'), $field['label'])
                    );
                }
            }
            
            // Phone validation
            if ($field['type'] === 'phone' && !empty($data[$field['name']])) {
                $phone = preg_replace('/[^0-9+]/', '', $data[$field['name']]);
                if (!preg_match('/^\+?[1-9]\d{1,14}$/', $phone)) {
                    return array(
                        'success' => false,
                        'message' => sprintf(__('%s must be a valid phone number.', 'spai-contact-form'), $field['label'])
                    );
                }
            }
        }
        
        // Address validation (US addresses only)
        $address_validation = $this->validate_address($data);
        if (!$address_validation['success']) {
            return $address_validation;
        }
        
        return array('success' => true);
    }
    
    /**
     * Validate address fields
     */
    private function validate_address($data) {
        // Check if we have any address fields - support actual field names
        $has_address_fields = false;
        $address_fields = array('street', 'city', 'state', 'zip', 'country', 'address.street', 'address.city', 'address.state', 'address.zipCode', 'address.country');
        
        foreach ($address_fields as $field) {
            if (isset($data[$field]) && !empty(trim($data[$field]))) {
                $has_address_fields = true;
                break;
            }
        }
        
        // Skip address validation if no address fields provided
        if (!$has_address_fields) {
            return array('success' => true);
        }
        
        // Load address validator
        require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/utils/class-spai-address-validator.php';
        
        // Only validate US addresses for now - check both field formats
        $country = isset($data['country']) ? trim($data['country']) : (isset($data['address.country']) ? trim($data['address.country']) : '');
        if (!empty($country) && !in_array(strtoupper($country), array('US', 'USA', 'UNITED STATES'))) {
            // Skip validation for non-US addresses
            return array('success' => true);
        }
        
        // Validate US address
        $validation_result = SPAI_Address_Validator::validate_us_address($data);
        
        if (!$validation_result['valid']) {
            return array(
                'success' => false,
                'message' => $validation_result['errors'][0] // Return first error
            );
        }
        
        return array('success' => true);
    }
    
    /**
     * Process integrations
     */
    private function process_integrations($submission_id, $form_data, $file_data, $settings) {
        $results = array();
        
        // Get integration settings from WordPress options
        $monday_settings = get_option('spai_contact_form_monday_settings', array());
        $salespartner_settings = get_option('spai_contact_form_salespartner_settings', array());
        $gchat_settings = get_option('spai_contact_form_gchat_settings', array());
        
        // Process Monday.com integration first
        if (!empty($monday_settings['enabled']) && $monday_settings['enabled']) {
            $monday_result = $this->process_monday_integration($submission_id, $form_data, $file_data, $monday_settings);
            $results['monday'] = $monday_result;
            
            // Add Monday ID to form data for SalesPartner
            if ($monday_result['success'] && !empty($monday_result['item_id'])) {
                $form_data['monday_item_id'] = $monday_result['item_id'];
                $form_data['monday_board_id'] = $monday_settings['board_id'];
            }
        }
        
        // Process SalesPartner integration
        if (!empty($salespartner_settings['enabled']) && $salespartner_settings['enabled']) {
            $salespartner_result = $this->process_salespartner_integration($submission_id, $form_data, $file_data, $salespartner_settings);
            $results['salespartner'] = $salespartner_result;
        }
        
        // Process Google Chat notification (after other integrations so it can include their IDs)
        if (!empty($gchat_settings['enabled']) && $gchat_settings['enabled']) {
            $gchat_result = $this->process_gchat_integration($submission_id, $form_data, $gchat_settings);
            $results['gchat'] = $gchat_result;
        }

        // Process Email confirmation (last, after all other integrations)
        $email_settings = isset($settings['email_confirmation']) ? $settings['email_confirmation'] : array();
        if (!empty($email_settings['enabled'])) {
            $email_result = $this->process_email_confirmation($submission_id, $form_data, $email_settings);
            $results['email'] = $email_result;
        }

        // Process Newsletter signup (after email)
        $newsletter_settings = isset($settings['newsletter']) ? $settings['newsletter'] : array();
        if (!empty($newsletter_settings['enabled'])) {
            $newsletter_result = $this->process_newsletter($submission_id, $form_data, $newsletter_settings);
            $results['newsletter'] = $newsletter_result;
        }

        return $results;
    }

    /**
     * Process Newsletter signup
     * Wrapped in try-catch to ensure newsletter errors never break form submission
     */
    private function process_newsletter($submission_id, $form_data, $settings) {
        try {
            // Check if MyEmma plugin is active
            if (!class_exists('SynLawn_MyEmma_API')) {
                return array(
                    'success' => false,
                    'error' => 'MyEmma plugin not active'
                );
            }

            // Get email from form data
            $email = $this->get_email_from_form_data($form_data);
            if (empty($email)) {
                return array(
                    'success' => false,
                    'error' => 'No email address found'
                );
            }

            // Get the field that determines the group
            $field_name = isset($settings['field']) ? $settings['field'] : '';
            $mapping = isset($settings['mapping']) ? $settings['mapping'] : array();

            if (empty($field_name) || empty($mapping)) {
                return array(
                    'success' => false,
                    'error' => 'Newsletter field or mapping not configured'
                );
            }

            // Get the field value from form data
            $field_value = isset($form_data[$field_name]) ? $form_data[$field_name] : '';
            if (empty($field_value)) {
                return array(
                    'success' => false,
                    'error' => 'Field value not found in submission'
                );
            }

            // Look up the group for this field value
            if (!isset($mapping[$field_value])) {
                // No mapping for this value - skip silently
                return array(
                    'success' => true,
                    'skipped' => true,
                    'message' => 'No newsletter group mapped for value: ' . $field_value
                );
            }

            $group_config = $mapping[$field_value];
            $group_id = isset($group_config['group_id']) ? $group_config['group_id'] : '';

            if (empty($group_id)) {
                return array(
                    'success' => false,
                    'error' => 'Group ID not configured for value: ' . $field_value
                );
            }

            // Prepare member fields
            $member_fields = array();
            if (!empty($form_data['first_name'])) {
                $member_fields['first_name'] = sanitize_text_field($form_data['first_name']);
            }
            if (!empty($form_data['last_name'])) {
                $member_fields['last_name'] = sanitize_text_field($form_data['last_name']);
            }

            // Call MyEmma API
            $api = new SynLawn_MyEmma_API();
            $result = $api->add_member($email, $group_id, $member_fields);

            // Update submission status
            $this->db_handler->update_submission_status(
                $submission_id,
                'newsletter',
                $result['success'] ? 'completed' : 'failed',
                isset($result['member_id']) ? $result['member_id'] : null,
                isset($result['error']) ? $result['error'] : null
            );

            return $result;

        } catch (Exception $e) {
            // Log error but never break form submission

            return array(
                'success' => false,
                'error' => $e->getMessage()
            );
        }
    }

    /**
     * Get email from form data (tries common field names)
     */
    private function get_email_from_form_data($form_data) {
        $email_fields = array('email', 'user_email', 'contact_email', 'your_email', 'e-mail');

        foreach ($email_fields as $field) {
            if (!empty($form_data[$field])) {
                return sanitize_email($form_data[$field]);
            }
        }

        return null;
    }

    /**
     * Process Email confirmation
     * Wrapped in try-catch to ensure email errors never break form submission
     */
    private function process_email_confirmation($submission_id, $form_data, $settings) {
        try {
            require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/integrations/notifications/class-spai-email-integration.php';

            $email = new SPAI_Email_Integration($settings);
            $result = $email->process_submission($form_data, array());

            // Update submission status
            $this->db_handler->update_submission_status(
                $submission_id,
                'email',
                $result['success'] ? 'completed' : 'failed',
                isset($result['email_id']) ? $result['email_id'] : null,
                isset($result['error']) ? $result['error'] : null
            );

            return $result;
        } catch (Exception $e) {
            // Log error but never break form submission

            $this->db_handler->update_submission_status(
                $submission_id,
                'email',
                'failed',
                null,
                $e->getMessage()
            );

            return array(
                'success' => false,
                'error' => $e->getMessage()
            );
        }
    }
    
    /**
     * Process Monday.com integration
     */
    private function process_monday_integration($submission_id, $form_data, $file_data, $settings) {
        require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/integrations/monday/class-spai-monday-integration.php';
        
        // Get field mapping to find file column
        $field_mapping = get_option('spai_contact_form_monday_mapping', array());
        
        // Find file column ID from mapping
        $file_column_id = null;
        foreach ($field_mapping as $form_field => $monday_column) {
            // Check if this is a file field by looking at the file data
            foreach ($file_data as $file) {
                if ($file['field'] === 'spai_field_' . $form_field) {
                    $file_column_id = $monday_column;
                    break 2;
                }
            }
        }
        
        // Add file column ID to settings
        if ($file_column_id) {
            $settings['file_column_id'] = $file_column_id;
        }
        
        $monday = new SPAI_Monday_Integration($settings['api_key']);
        $result = $monday->create_item($form_data, $file_data, $settings);
        
        // Update submission status
        $status_data = array(
            'status' => $result['success'] ? 'completed' : 'failed',
            'external_id' => $result['success'] ? $result['item_id'] : null,
            'error' => $result['success'] ? null : $result['error'],
            'board_id' => $settings['board_id'],
            'updated_at' => current_time('mysql')
        );
        
        // Update the integration status directly
        global $wpdb;
        $submission = $this->db_handler->get_submission($submission_id);
        if ($submission) {
            $integration_status = $submission->integration_status;
            $integration_status['monday'] = $status_data;
            
            $table = $wpdb->prefix . 'spai_submissions';
            $wpdb->update(
                $table,
                array('integration_status' => wp_json_encode($integration_status)),
                array('id' => $submission_id)
            );
        }
        
        return $result;
    }
    
    /**
     * Process SalesPartner integration
     */
    private function process_salespartner_integration($submission_id, $form_data, $file_data, $settings) {
        require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/integrations/salespartner/class-spai-salespartner-integration.php';
        
        $salespartner = new SPAI_SalesPartner_Integration($settings['api_url']);
        $result = $salespartner->send_contact($form_data, $file_data, $settings);
        
        // Update submission status
        $this->db_handler->update_submission_status(
            $submission_id,
            'salespartner',
            $result['success'] ? 'completed' : 'failed',
            $result['success'] ? $result['contact_id'] : null,
            $result['success'] ? null : $result['error']
        );
        
        return $result;
    }
    
    /**
     * Process Google Chat integration
     */
    private function process_gchat_integration($submission_id, $form_data, $settings) {
        require_once SPAI_CONTACT_FORM_PLUGIN_DIR . 'includes/integrations/notifications/class-spai-gchat-integration.php';
        
        $gchat = new SPAI_GChat_Integration($settings['webhook_url']);
        $result = $gchat->process_submission($form_data, array());
        
        // Update submission status
        $this->db_handler->update_submission_status(
            $submission_id,
            'gchat',
            $result['success'] ? 'completed' : 'failed',
            $result['success'] ? $result['notification_id'] : null,
            $result['success'] ? null : $result['error']
        );
        
        return $result;
    }
    
    /**
     * 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';
    }
}
