<?php
if (! class_exists('AI_APP_ONSITE_OpenAi_Api_Handler')) {
    class AI_APP_ONSITE_OpenAi_Api_Handler
    {
        public function __construct()
        {
            // Hook the AJAX action to the appropriate method in this class

            // Ajax handler
            add_action('wp_ajax_ai_app_onsite_openAi_api', array($this, 'ai_app_onsite_openAi_api'));
            add_action('wp_ajax_nopriv_ai_app_onsite_openAi_api', array($this, 'ai_app_onsite_openAi_api'));
        }

        public static function ai_app_onsite_openAi_api()
        {
            if (
                isset($_POST['aiappOnsitePropertiesNonce']) &&
                !wp_verify_nonce(
                    sanitize_text_field(wp_unslash($_POST['aiappOnsitePropertiesNonce'])),
                    'ai_app_onsite_properties_nonce'
                )
            ) {
                wp_send_json_error('Invalid nonce. Please refresh the page and try again.');
                return;
            }

            // Handle the AJAX request
            global $wpdb;
            $table_name_prompt_editor   = $wpdb->prefix . 'ai_app_onsite_prompt_editor';
            $table_name_model_settings  = $wpdb->prefix . 'ai_app_onsite_model_settings';
            $table_name_plugin_settings = $wpdb->prefix . 'ai_app_onsite_plugin_settings';
            $table_name_field_selector  = $wpdb->prefix . 'ai_app_onsite_field_selector_settings';
            $table_name_app_properties  = $wpdb->prefix . 'ai_app_onsite_app_properties';
            $table_name_models          = $wpdb->prefix . 'ai_app_onsite_models';

            $response_message = '';
            $app_name = '';
            $properties = $wpdb->get_results("SELECT response_message, app_name_show, app_name FROM $table_name_app_properties WHERE app_id = 1 LIMIT 1", ARRAY_A);

            if (!empty($properties[0])) {
                $response_message = $properties[0]['response_message'] ?? '';
                $app_name = !empty($properties[0]['app_name_show']) ? $properties[0]['app_name_show'] : ($properties[0]['app_name'] ?? '');
            } 

            $model_settings = $wpdb->get_results("SELECT * FROM $table_name_model_settings WHERE app_id = 1", ARRAY_A);

            $plugin_settings = $wpdb->get_results("SELECT * FROM $table_name_plugin_settings WHERE app_id = 1", ARRAY_A);

            $formData = $_POST;

            $field_names = array_keys($formData);
            $field_values = array_values($formData);
            $pairs = array_combine($field_names, $field_values);

            $field_selector_settings = $wpdb->get_results("SELECT `field_label`, `field_tag` FROM $table_name_field_selector WHERE app_id = 1", ARRAY_A);
            
            $map = [];
            foreach ($field_selector_settings as $r) {
                $cleanTag = preg_replace('/[{}\s]/', '', $r['field_tag']);
                $normalized = strtolower(preg_replace('/\s+/', '_', trim($r['field_label'])));
                $map[$r['field_label']] = $cleanTag;
                $map[$normalized] = $cleanTag;
            }
            // Replace label keys with their field_tag (keep unmapped as-is)
            $tag_pairs = [];
            foreach ($formData as $label => $value) {
                $normalized = strtolower(preg_replace('/\s+/', '_', trim($label)));
                if (isset($map[$label]) || isset($map[$normalized])) {
                    $key = $map[$label] ?? $map[$normalized]; 
                    $tag_pairs[$key] = sanitize_text_field($value);
                }
            }
            
            $field_tag_names  = array_keys($tag_pairs);
            $field_tag_values = array_values($tag_pairs);
            $field_tag_parirs = array_combine($field_tag_names, $field_tag_values);


            $banned_words = (!empty($plugin_settings) && isset($plugin_settings[0]['banned_words']) && !is_null($plugin_settings[0]['banned_words']))
            ? unserialize($plugin_settings[0]['banned_words'])
            : [];
            $app_email = isset($plugin_settings[0]['app_email']) ? $plugin_settings[0]['app_email'] : null;

            function containsBannedWordPart($value, $banned_word)
            {
                // Split banned word into parts by space
                $banned_parts = explode(' ', $banned_word);
                foreach ($banned_parts as $part) {
                    // Use preg_match to find exact words
                    if (preg_match('/\b' . preg_quote($part, '/') . '\b/i', $value)) {
                        return true;
                    }
                }
                return false;
            }

            // Iterate through field values and check against banned words
            if (!empty($banned_words)) {
                foreach ($field_tag_values as $value) {
                    foreach ($banned_words as $banned_word) {
                        if (containsBannedWordPart($value, $banned_word)) {
                            wp_send_json_error("Banned word included in: " . $value);
                            break 2;
                        }
                    }
                }
            }
           
            $fieldLabels = array_column($field_selector_settings, 'field_label');
            // Process each element of the array
            $fieldLabels = array_map(function ($item) {
                // Replace spaces with underscores in each item
                return preg_replace('/\s+/', '_', $item);
            }, $fieldLabels);

            $fieldTagLabels = array_column($field_selector_settings, 'field_tag');
            // Process each element of the array
            $fieldTagLabels = array_map(function ($item) {
                // Remove {{ and }} from each item
                return trim(str_replace(['{{', '}}'], '', $item));
            }, $fieldTagLabels);

            if (empty($model_settings)) {
                wp_send_json_error('Plugin Model settings are missing');
            }

            $model_setting = $model_settings[0];

            $openai_key = $model_setting['openai_key'];
            $key_status = $model_setting['key_status'];
            $model = $model_setting['model'];
            $temperature = $model_setting['temperature'] ?: '';
            $f_penalty = $model_setting['f_penalty'] ?: '';
            $p_penalty = $model_setting['p_penalty'] ?: '';
            $max_tokens = $model_setting['max_tokens'] ?: '';
            $top_p = $model_setting['top_p'] ?: '';

            // Check for missing keys
            if (empty($openai_key)) {
                wp_send_json_error('OpenAI API key is missing');
            }

            if (empty($model)) {
                wp_send_json_error('OpenAI API Model is missing');
            }
            if ($key_status === 'false') {
                wp_send_json_error('OpenAI API key is disable');
            }

            $formatted_field_names = array_map(function ($key) {
                return '{{' . strtolower($key) . '}}';
            }, $field_tag_names);

            $replace_array = array_combine($formatted_field_names, $field_tag_values);
           
            $prompt_results = $wpdb->get_results("SELECT * FROM $table_name_prompt_editor WHERE app_id = 1", ARRAY_A);
           
            if (empty($prompt_results)) {
                wp_send_json_error('No prompt results found');
            }

            $prompt_result = $prompt_results[0];

            if (!isset($prompt_result['prompt']) || empty($prompt_result['prompt'])) {
                wp_send_json_error('Prompt string is empty');
            }

            $prompt = str_replace(array_keys($replace_array), array_values($replace_array), $prompt_result['prompt']);

            // Check for empty prompt
            if (empty($prompt)) {
                wp_send_json_error('Prompt is missing');
            }

            $model_parameters = $wpdb->get_row(
                $wpdb->prepare("SELECT * FROM $table_name_models WHERE model = %s LIMIT 1", $model),
                ARRAY_A
            );

            if (empty($model_parameters)) {
                wp_send_json_error('Model parameters not found for the selected model');
            }

            $api_url = $model_parameters['endpoint'] ?? 'https://api.openai.com/v1/chat/completions';
            $model   = $model_parameters['model'] ?? $model;

            $OPENAI_API_KEY = $openai_key;

            $headers = [
                "Content-Type" => "application/json",
                "Authorization" => "Bearer $OPENAI_API_KEY"
            ];

            $is_reasoning = (strpos($api_url, '/v1/responses') !== false);

            if ($is_reasoning) {
                // Reasoning API payload
                $data = [
                    "model"             => $model,
                    "input"             => $prompt,
                    "max_output_tokens" => !empty($max_tokens) ? (int)$max_tokens : 3000,
                ];
            } else {
                // Chat API payload
                $data = [
                    "model"    => $model,
                    "messages" => [
                        ["role" => "user",   "content" => $prompt]
                    ],
                    "max_tokens" => !empty($max_tokens) ? (int)$max_tokens : 3000,
                ];
            }

            $model_parameters['supported_parameters'] = json_decode($model_parameters['supported_parameters'], true);   
            $supported_parameters = $model_parameters['supported_parameters'] ?? [];
            
            // Add parameters based on model capabilities
            if (in_array('temperature', $supported_parameters) && !empty($temperature)) {
                $data["temperature"] = (float)$temperature;
            }
            if (in_array('top_p', $supported_parameters) && !empty($top_p)) {
                $data["top_p"] = (float)$top_p;
            }
            if (in_array('frequency_penalty', $supported_parameters) && !empty($f_penalty)) {
                $data["frequency_penalty"] = (float)$f_penalty;
            }
            if (in_array('presence_penalty', $supported_parameters) && !empty($p_penalty)) {
                $data["presence_penalty"] = (float)$p_penalty;
            } 
            if (!empty($model_parameters['default_tools'])) {
                $tool_type = trim($model_parameters['default_tools']);
                $data['tools'] = [['type' => $tool_type]];
            }

          
            // Send request
            $response = wp_remote_post($api_url, [
                'headers'     => $headers,
                'body'        => wp_json_encode($data),
                'timeout'     => 20 * 1000, 
                'data_format' => 'body',
            ]);

            $response_code = wp_remote_retrieve_response_code($response);
            $result        = json_decode(wp_remote_retrieve_body($response), true);


            // Extract output
            if ($is_reasoning) {
                $output = $result['output'] ?? [];
                // Find first message with text content
                $response_content = null;
                foreach ($output as $item) {
                    if (
                        isset($item['type'], $item['content']) &&
                        $item['type'] === 'message' &&
                        is_array($item['content'])
                    ) {
                        foreach ($item['content'] as $content) {
                            if (!empty($content['text'])) {
                                $response_content = $content['text'];
                                break 2;
                            }
                        }
                    }
                }
            } else {
                $response_content = $result['choices'][0]['message']['content'] ?? null;
            }

            if (!$response_content) wp_send_json_error('Invalid response from OpenAI');

            // Optional: format output for HTML display
            $response_content = htmlspecialchars($response_content);
            $response_content = str_replace('Hello!', 'Hello!<br><br>', $response_content);
            $response_content = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $response_content);
            $response_content = preg_replace('/####\s*(.*)/', '<h2>$1</h2>', $response_content);
            $response_content = nl2br($response_content);


            if (!empty($app_email)) {
                $resultArray = array_filter(
                    $pairs,
                    function ($key) use ($fieldLabels) {
                        return in_array($key, $fieldLabels);
                    },
                    ARRAY_FILTER_USE_KEY
                );

                self::ai_app_onsite_send_email($app_email, $resultArray, $response_content, $app_name);
            }

            $user_stats_handler = new AI_APP_ONSITE_User_Stats_Handler();
            $response_Id = $user_stats_handler->ai_app_onsite_save_user_stats($result, $prompt, $formData,$response_content);


            // Optionally handle response from external URL
            $response = [
                'success'     => true,
                'message'     => 'Form data received successfully',
                'data'        => $response_content,
                'response_message' => $response_message,
                'response_id' => $response_Id,
            ];

            wp_send_json($response);
        }

        // Sending email with dynamic data
	    public static function ai_app_onsite_send_email($to, $data, $ai_output, $app_name): void
	    {
		    // Normalize $data -> safe HTML list items
		    $dynamic_list = '';
		    foreach ($data as $key => $value) {
			    if (is_array($value) || is_object($value)) {
				    $value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
			    }
			    // Convert simple newlines to <br> for readability
			    $safeValue = nl2br(htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'));
			    $safeKey = htmlspecialchars(ucfirst(str_replace('_', ' ', (string)$key)), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
			    $dynamic_list .= "<tr><td style=\"padding:6px 0;border-bottom:1px solid #eee;\"><strong>{$safeKey}:</strong> {$safeValue}</td></tr>";
		    }

		    // If AI output is plain text, keep formatting; if HTML, it will pass through.
		    $ai_output_block = $ai_output;
		    // Best-effort: if it looks plain (no tags), escape then nl2br
		    if ($ai_output === strip_tags($ai_output)) {
			    $ai_output_block = nl2br(htmlspecialchars($ai_output, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'));
		    }

		    $brand   = 'AIappOnsite';
		    $suffix  = !empty($app_name) ? " – " . htmlspecialchars($app_name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') : '';
		    $site_name = get_bloginfo('name');
		    $safe_site_name = htmlspecialchars($site_name ?: 'this site', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
		    $subject = "{$brand} App Usage{$suffix}";

		    // Hidden preheader (appears in inbox preview)
		    $preheader = "Your {$brand} submission and AI response{$suffix}.";

		    // NOTE: Keep styles inline & table-based for broad client support
		    $email_template = <<<HTML
					<!doctype html>
					<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
					  <head>
					    <meta http-equiv="x-ua-compatible" content="ie=edge">
					    <meta name="viewport" content="width=device-width, initial-scale=1"> 
					    <meta charset="UTF-8">
					    <title>{$brand}{$suffix}</title>
					    <!--[if mso]>
					      <style type="text/css">
					        body, table, td {font-family: Arial, sans-serif !important;}
					      </style>
					    <![endif]-->
					    <style>
					      /* Minimal mobile fluidity without relying on head CSS */
					      @media only screen and (max-width: 620px) {
					        .container {width: 100% !important;}
					        .p-24 {padding:16px !important;}
					        .h1 {font-size: 20px !important; line-height: 26px !important;}
					      }
					    </style>
					  </head>
					  <body style="margin:0;padding:0;background-color:#f5f7fb;">
					    <span style="display:none!important;visibility:hidden;opacity:0;color:transparent;height:0;width:0;overflow:hidden;">{$preheader}</span>
					    <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f5f7fb;">
					      <tr>
					        <td align="center" style="padding:24px;">
					          <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="720" class="container" style="width:720px;max-width:720px;background:#ffffff;border-radius:8px;box-shadow:0 2px 8px rgba(16,24,40,0.06);">
					            <tr>
					              <td class="p-24" style="padding:24px 24px 0 24px;">
					                <table width="100%" role="presentation" cellpadding="0" cellspacing="0" border="0">
					                  <tr>
					                    <td align="left" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; color:#111827;">
					 
					                      <h1 class="h1" style="margin:0;font-size:22px;line-height:28px;font-weight:700;">{$brand} App Input Data{$suffix}</h1>
					                    </td>
					                  </tr>
					                </table>
					              </td>
					            </tr>
					
					            <tr>
					              <td class="p-24" style="padding:16px 24px 0 24px;">
					                <p style="margin:0 0 12px 0;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size:14px; line-height:20px; color:#374151;">
					                  This is the data you provided:
					                </p>
					                <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
					                  {$dynamic_list}
					                </table>
					              </td>
					            </tr>
					
					            <tr>
					              <td class="p-24" style="padding:16px 24px 0 24px;">
					                <p style="margin:0 0 8px 0;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size:14px; line-height:20px; color:#374151;"><strong>App Results:</strong></p>
					                <div style="border:1px solid #e5e7eb; background:#f9fafb; border-radius:6px; padding:16px; font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size:13px; line-height:20px; color:#111827;">
					                  {$ai_output_block}
					                </div>
					              </td>
					            </tr>
					
					            <tr>
					              <td class="p-24" style="padding:16px 24px 24px 24px;">
					                <p style="margin:12px 0 0 0;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size:13px; line-height:20px; color:#6b7280;">
					                  Thanks for using {$brand}, provided by {$safe_site_name}!
					                </p>
					              </td>
					            </tr>
					          </table>
					
					          <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="720" class="container" style="width:720px;max-width:720px;">
					            <tr>
					              <td align="center" style="padding:12px 8px 0 8px;">
					                <p style="margin:0;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; font-size:11px; line-height:16px; color:#9ca3af;">
					                This email was requested by the recipient and sent by the {$safe_site_name} website using AIappOnsite.
					                </p>
					              </td>
					            </tr>
					            <tr><td style="height:24px; line-height:24px;">&nbsp;</td></tr>
					          </table>
					        </td>
					      </tr>
					    </table>
					  </body>
					</html>
					HTML;

		    // Build headers (prefer wp_mail when available)
		    $headers = [];
		    $headers[] = 'MIME-Version: 1.0';
		    $headers[] = 'Content-Type: text/html; charset=UTF-8';

		    $fromEmail = defined('AIAPP_FROM_EMAIL') ? AIAPP_FROM_EMAIL : null;
		    if ($fromEmail) {
			    $headers[] = 'From: AIappOnsite <' . $fromEmail . '>';
			    $headers[] = 'Reply-To: ' . $fromEmail;
		    }

		    // Use wp_mail if available; fallback to mail()
		    if (function_exists('wp_mail')) {
			    wp_mail($to, $subject, $email_template, $headers);
		    } else {
			    // mail() expects headers as a string
			    $headers_str = implode("\r\n", $headers);
			    @mail($to, $subject, $email_template, $headers_str);
		    }
	    }
    }

    new AI_APP_ONSITE_OpenAi_Api_Handler(); // Instantiate the class
}



function AI_APP_ONSITE_Break_Paragraph($text, $words_per_chunk = 200)
{
    // Split the text into an array of words
    $words = preg_split('/\s+/', $text);

    $chunks = array_chunk($words, $words_per_chunk);

    $result = '';
    foreach ($chunks as $chunk) {
        $result .= implode(' ', $chunk) . "\n\n";
    }

    return $result;
}
