<?php
if (!class_exists('AI_APP_ONSITE_User_Stats_Handler')) {
    class AI_APP_ONSITE_User_Stats_Handler {
        public function __construct() {
            // Hook the AJAX action to the appropriate method in this class
            add_action('wp_ajax_ai_app_onsite_save_user_stats', array($this, 'ai_app_onsite_save_user_stats'));
            add_action('wp_ajax_nopriv_ai_app_onsite_save_user_stats', array($this, 'ai_app_onsite_save_user_stats'));
            
            // Hook the AJAX action to download user stats
            add_action('wp_ajax_ai_app_onsite_download_user_stats', array($this, 'ai_app_onsite_download_user_stats'));

            add_action('wp_ajax_ai_app_onsite_save_feedback', [$this, 'ai_app_onsite_save_feedback']);
            add_action('wp_ajax_nopriv_ai_app_onsite_save_feedback', [$this, 'ai_app_onsite_save_feedback']);

            add_action('wp_ajax_ai_app_onsite_store_session', [$this, 'ai_app_onsite_store_session']);
            add_action('wp_ajax_nopriv_ai_app_onsite_store_session', [$this, 'ai_app_onsite_store_session']);

            add_action('ai_app_onsite_user_stats_cron', [$this, 'ai_app_onsite_user_stats_callback']);

            if (!wp_next_scheduled('ai_app_onsite_user_stats_cron')) {
                wp_clear_scheduled_hook('ai_app_onsite_user_stats_cron');
                $random_time = $this->ai_app_onsite_generate_random_time();
                wp_schedule_single_event($random_time, 'ai_app_onsite_user_stats_cron');
            }
        }

        public function ai_app_onsite_generate_random_time() {
            $dt = new DateTime('tomorrow midnight', new DateTimeZone('UTC'));
            $start = $dt->getTimestamp() - 10; // 23:59:50 UTC, 10 sec before midnight
            $end   = $start + (15 * 60);       // 00:14:50 UTC, 900 sec/15 min after midnight
            return rand($start, $end);
        }

		/**
		 * Save user statistics after AI response
		 *
		 * @param array $result The AI response result.
		 * @param string $prompt The original prompt sent to the AI.
		 * @param array $formData Additional form data submitted with the request.
		 * @param string $response_content The content of the AI's response.
		 * @return string The response ID of the saved statistics.
		 */
        public function ai_app_onsite_save_user_stats($result, $prompt, $formData,$response_content): string
        {
            global $wpdb;

	        $app_selector = ai_app_onsite_get_app_selector();
	        if (!$app_selector) {
		        wp_send_json_error('App not found. Please create an app first.');
		        exit;
	        }

		    // Fallback: Get IP using PHP
		    $user_ip = 'Unknown';

		    // Optional fallback message
		    $user_geolocation = wp_json_encode(array(
		        'ip' => $user_ip,
		        'source' => 'fallback-php',
			    'error' => ''
		    ));
	        
            // Extract individual settings values
            $formData    = isset($formData) ? wp_json_encode($formData) : '';
            $used_token  = isset($result['usage']['total_tokens']) ? sanitize_text_field($result['usage']['total_tokens']) : '';
            $response_Id = isset($result['id']) ? sanitize_text_field($result['id']) : '';
            $prompt      = isset($prompt) ? sanitize_text_field($prompt) : '';

            // Check if the model is reasoning or not
            $table_name_models = $wpdb->prefix . 'ai_app_onsite_models';
            $table_name_model_settings = $wpdb->prefix . 'ai_app_onsite_model_settings';

            $model_settings = $wpdb->get_results(
                $wpdb->prepare("SELECT * FROM $table_name_model_settings WHERE app_id = %s", $app_selector),
                ARRAY_A
            );

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

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

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

            // Insert new row
            $table_name_stats = $wpdb->prefix . 'ai_app_onsite_user_statistics';
            $wpdb->insert(
                $table_name_stats,
                array(
                    'app_id'           => 1,
                    'response_id'      => $response_Id,
                    'user_ip'          => $user_ip,
                    'user_geolocation' => $user_geolocation,
                    'prompt'           => $prompt,
                    'ai_output'        => $response_content,
                    'data'             => $formData,
                    'used_token'       => $used_token,
                    'created_at'       => current_time('mysql'),
                    'updated_at'       => current_time('mysql')
                ),
                array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
            );

            return $response_Id;

        }

	    /**
	     * The function to download the user stats based on the
	     * duration set by the user
	     */
	    function ai_app_onsite_download_user_stats() {
		    global $wpdb;

		    if (
			    ! isset($_POST['ai_app_onsite_download_user_stats_nonce']) ||
			    ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ai_app_onsite_download_user_stats_nonce'])), 'ai_app_onsite_download_user_stats_nonce')
		    ) {
			    wp_send_json_error(['message' => 'Nonce verification failed for this action.']);
			    return;
		    }

		    $app_selector = ai_app_onsite_get_app_selector();
		    if (!$app_selector) {
			    wp_send_json_error('App not found. Please create an app first.');
			    exit;
		    }

		    $duration = isset($_POST['duration']) ? sanitize_text_field(wp_unslash($_POST['duration'])) : '';
		    if (empty($duration)) {
			    wp_send_json_error('Duration parameter is required.');
			    return;
		    }
		    $where_clauses = ["app_id = %d"];
		    $query_params = [$app_selector];

		    $today = date('Y-m-d', strtotime('-1 day'));
		    $now   = current_time('mysql');
		    $timezone = wp_timezone();
		    $now_dt = new DateTime('now', $timezone);
		    $today_start_dt = new DateTime('today midnight', $timezone);

		    switch ($duration) {
			    case 'today':
				    $where_clauses[] = "updated_at BETWEEN %s AND %s";
				    $query_params[] = $today_start_dt->format('Y-m-d H:i:s');
				    $query_params[] = $now_dt->format('Y-m-d H:i:s');
				    break;
			    case 'last_7_days':
				    $start = date('Y-m-d', strtotime('-7 days'));
				    $where_clauses[] = "DATE(updated_at) BETWEEN %s AND %s";
				    $query_params[] = $start;
				    $query_params[] = $today;
				    break;
			    case 'current_month':
				    $start = date('Y-m-01');
				    $where_clauses[] = "DATE(updated_at) BETWEEN %s AND %s";
				    $query_params[] = $start;
				    $query_params[] = $today;
				    break;
			    case 'last_month':
				    $start = date('Y-m-01', strtotime('first day of last month'));
				    $end = date('Y-m-t', strtotime('last day of last month'));
				    $where_clauses[] = "DATE(updated_at) BETWEEN %s AND %s";
				    $query_params[] = $start;
				    $query_params[] = $end;
				    break;

			    default:
				    break;
		    }

		    $table_name = $wpdb->prefix . 'ai_app_onsite_app_usage_statistics';
		    $sql = "SELECT * FROM $table_name WHERE " . implode(" AND ", $where_clauses);
		    $prepared_sql = $wpdb->prepare($sql, $query_params);
		    $user_stats = $wpdb->get_results($prepared_sql, ARRAY_A);

		    if (!$user_stats) {
			    wp_send_json_error('No user statistics found for this duration.');
			    return;
		    }

		    foreach ($user_stats as &$row) {
			    if (!empty($row['response_id'])) {
				    $response_data = $wpdb->get_row(
					    $wpdb->prepare(
						    "SELECT data FROM " . $wpdb->prefix . "ai_app_onsite_user_statistics WHERE response_id = %s LIMIT 1",
						    $row['response_id']
					    ),
					    ARRAY_A
				    );
				    if ($response_data && !empty($response_data['data'])) {
					    $data_array = json_decode($response_data['data'], true);
					    if (json_last_error() === JSON_ERROR_NONE && isset($data_array['email']) && !empty($data_array['email'])) {
						    $row['user_id'] = sanitize_email($data_array['email']);
					    }
				    }
			    }
		    }
		    unset($row);

		    // Begin CSV output
		    if (ob_get_contents()) ob_end_clean();
		    header('Content-Type: text/csv; charset=utf-8');
		    header('Content-Disposition: attachment; filename="user_stats_export.csv"');
		    header('Pragma: no-cache');
		    header('Expires: 0');

		    $output = fopen('php://output', 'w');

		    // ========================
		    // Summary (Top 4 Rows)
		    // ========================

		    // Row 1
		    $monthTitle = ucfirst(str_replace('_', ' ', $duration));
		    $app_name   = ai_app_onsite_get_current_app_name();
		    fputcsv($output, ["AiappOnsite User Stats: $monthTitle - $app_name"]);

		    // Row 2: Empty
		    fputcsv($output, []);

		    // Row 3: Summary headers
		    fputcsv($output, [
			    'App Visitor Total', 'Time on App (Avg)', 'App Use Total', 'Results Visitors Total',
			    'Time on Results (Avg)', 'App Reuse Total', 'Results Liked Total', 'Results Disliked Total', 'Report Date/Time'
		    ]);

		    // Row 4: Summary values
		    $summary = [
			    'visitor_total'     => count(array_unique(array_column($user_stats, 'user_id'))),
			    'time_on_app_avg'   => $this->average_duration(array_column($user_stats, 'time_on_app')),
			    'app_use_total'     => count(array_filter($user_stats, fn($row) => $row['app_use'] === 'Y')),
			    'results_visited'   => count(array_filter($user_stats, fn($row) => $row['results_visited'] === 'Y')),
			    'time_on_result_avg'=> $this->average_duration(array_column($user_stats, 'time_on_results')),
			    'app_reuse'         => count(array_filter($user_stats, fn($row) => $row['app_reuse'] === 'Y')),
			    'liked'             => count(array_filter($user_stats, fn($row) => $row['results_liked'] === 'Y')),
			    'disliked'          => count(array_filter($user_stats, fn($row) => $row['results_disliked'] === 'Y')),
			    'report_time'       => current_time('mysql')
		    ];

		    fputcsv($output, array_values($summary));

		    // Row 5: Empty line
		    fputcsv($output, []);

		    // ========================
		    // Detail Rows
		    // ========================
		    $headers = [
			    'App Visitor (User ID)', 'Time on App', 'App Use', 'Results Visited',
			    'Time on Results', 'App Reuse', 'Results Liked', 'Results Disliked', 'Date/Time'
		    ];
		    fputcsv($output, $headers);

		    foreach ($user_stats as $row) {
			    fputcsv($output, [
				    $row['user_id'],
				    $row['time_on_app'],
				    $row['app_use'],
				    $row['results_visited'],
				    $row['time_on_results'],
				    $row['app_reuse'],
				    $row['results_liked'],
				    $row['results_disliked'],
				    $row['updated_at']
			    ]);
		    }

		    fclose($output);
		    exit;
	    }

        // Helper to calculate average time (hh:mm:ss format)
		public function average_duration($timeArray): string {
			$totalSeconds = 0;
			$count = 0;

			foreach ($timeArray as $timeStr) {
				if (!$timeStr) continue;

				$parts = explode(':', $timeStr);

				// Strictly mm:ss format
				if (count($parts) === 2) {
					[$m, $s] = $parts;
					if (is_numeric($m) && is_numeric($s)) {
						$totalSeconds += ((int)$m * 60) + (int)$s;
						$count++;
					}
				}
			}

			if ($count === 0) return '00:00:00';

			$avgSeconds = (int)($totalSeconds / $count);
			return gmdate('H:i:s', $avgSeconds); // Format as HH:MM:SS
		}


		function ai_app_onsite_save_feedback() {
            global $wpdb;
        
            if (!isset($_POST['response_id']) || !isset($_POST['feedback']) || empty($_POST['response_id']) || empty($_POST['feedback'])) {
                wp_send_json_error('Invalid Data');
            }
        
            $response_id = sanitize_text_field($_POST['response_id']); 
            $feedback    = sanitize_text_field($_POST['feedback']); 
        
            $table_name_stats = $wpdb->prefix . 'ai_app_onsite_user_statistics';
        
            $update = $wpdb->update(
                $table_name_stats,
                ['feedback' => $feedback, 'updated_at' => current_time('mysql')],
                ['response_id' => $response_id],
                ['%s', '%s'],
                ['%s']
            );
        
            if ($update === false) {
                wp_send_json_error('Failed to save feedback');
            }
        
            wp_send_json_success('Feedback saved successfully');
        }

        /**
	     * The function to store the user usage session based on the
	     * app interaction
	     */
        function ai_app_onsite_store_session() {
            if (empty($_POST['app_id']) || empty($_POST['user_id'])) {
                wp_send_json_error('Missing required session fields');
            }

            global $wpdb;
            $table_name = $wpdb->prefix . 'ai_app_onsite_app_usage_statistics';

            // Sanitize inputs
            $session_data = array(
                'app_id'          => sanitize_text_field($_POST['app_id']),
                'response_id'     => sanitize_text_field($_POST['response_id'] ?? ''),
                'user_id'         => sanitize_text_field($_POST['user_id']),
                'time_on_app'     => sanitize_text_field($_POST['time_on_app'] ?? ''),
                'app_use'         => sanitize_text_field($_POST['app_use'] ?? 'N'),
                'results_visited' => sanitize_text_field($_POST['results_visited'] ?? 'N'),
                'time_on_results' => sanitize_text_field($_POST['time_on_results'] ?? ''),
                'app_reuse'       => sanitize_text_field($_POST['app_reuse'] ?? 'N'),
                'results_liked'   => sanitize_text_field($_POST['results_liked'] ?: 'N'),
                'results_disliked'=> sanitize_text_field($_POST['results_disliked'] ?: 'N'),
                'updated_at'      => current_time('mysql')
            );

            // Check if the session already exists
            $existing_session = $wpdb->get_row(
                $wpdb->prepare(
                    "SELECT id, time_on_app, time_on_results 
                    FROM $table_name 
                    WHERE app_id = %s AND user_id = %s 
                    ORDER BY updated_at DESC, id DESC 
                    LIMIT 1",
                    $session_data['app_id'],
                    $session_data['user_id']
                )
            );

            if ($existing_session) {
                unset($session_data['created_at']);
                // Update existing session
                $session_data['time_on_app']     = $this->aiao_sum_time($existing_session->time_on_app, $session_data['time_on_app']);
                $session_data['time_on_results'] = $this->aiao_sum_time($existing_session->time_on_results, $session_data['time_on_results']);

                $wpdb->update(
                    $table_name,
                    $session_data,
                    ['id' => $existing_session->id],
                    array_fill(0, count($session_data), '%s'),
                    ['%d']
                );

                if($session_data['app_reuse'] === 'Y') {
                    $wpdb->insert( $table_name, [ 
                        'app_id'  => $session_data['app_id'],
                        'user_id' => $session_data['user_id'],
                        'created_at' => current_time('mysql'),
                        'updated_at' => current_time('mysql')
                    ], array_fill(0, 4, '%s'));
                }
            } else {
                $session_data['created_at'] = current_time('mysql');
                // Insert new session
                $wpdb->insert(
                    $table_name,
                    $session_data,
                    array_fill(0, count($session_data), '%s')
                );
            }

            // Check for errors
            if ($wpdb->last_error) {
                wp_send_json_error('Error storing session data: ' . $wpdb->last_error);
            }   
        }

        // Helper to sum two 'i:s' time strings
        function aiao_sum_time($time1, $time2) {
            if (empty($time1)) {
                return $time2;
            }
            if (empty($time2)) {
                return $time1;
            }
            $parts1 = explode(':', str_pad($time1, 5, '0', STR_PAD_LEFT));
            $parts2 = explode(':', str_pad($time2, 5, '0', STR_PAD_LEFT));
            $sec = ((int)$parts1[0] * 60 + (int)$parts1[1]) + ((int)$parts2[0] * 60 + (int)$parts2[1]);
            return sprintf('%02d:%02d', floor($sec / 60), $sec % 60);
        }

        /**
         * Generate a CSVs for today's usage
         *
         */
        function ai_app_onsite_user_stats_callback() {
            global $wpdb;

            $table = $wpdb->prefix . 'ai_app_onsite_app_usage_statistics';

            $rows = $wpdb->get_results("SELECT * FROM $table ORDER BY app_id, user_id", ARRAY_A);

            if (empty($rows)) {
                wp_send_json_error('No user statistics found for today.');
                return;
            }

            // --- credentials from Step 1 registration ---
            $client_credentials = get_option('aiapp_client_credentials', []);
            $key    = $client_credentials['key']    ?? '';
            $secret = $client_credentials['secret'] ?? '';
            if ($key === '' || $secret === '') {
                wp_send_json_error('Missing client credentials. Registration not completed.');
                return;
            }

            $api_base = rtrim(get_option('aiapp_server_base_url'), '/');
            if ($api_base === '') {
                wp_send_json_error('AIAO API base URL not configured.');
                return;
            }

            $site_unique_id = get_option('ai_app_onsite_unique_id') ?: 'Unknown';
            $now_stamp      = current_time('mysql');
            $filename_stamp = date('Y-m-d-H-i-s');
            $csv_filename   = "user_stats_{$site_unique_id}_{$filename_stamp}.csv";

            // Write CSV to memory (not php://output!)
            $csv_stream = fopen('php://temp', 'r+'); // memory-safe temp stream
            fwrite($csv_stream, "\xEF\xBB\xBF"); // UTF-8 BOM

            $grouped = [];
            foreach ($rows as $row) {
                $grouped[$row['app_id']][] = $row;
            }

            foreach ($grouped as $app_id => $app_rows) {
                fputcsv($csv_stream, ["AIappOnsite User Stats - Site: $site_unique_id"]);
                fputcsv($csv_stream, []);

                fputcsv($csv_stream, [
                    'App Visitor Total', 'Time on App (Avg)', 'App Use Total', 'Results Visitors Total',
                    'Time on Results (Avg)', 'App Reuse Total', 'Results Liked Total', 'Results Disliked Total', 'Report Date/Time'
                ]);

                $visitor_total      = count(array_unique(array_column($app_rows, 'user_id')));
                $time_on_app_avg    = $this->average_duration(array_column($app_rows, 'time_on_app'));
                $app_use_total      = count(array_filter($app_rows, fn($r) => strtoupper(trim($r['app_use'] ?? '')) === 'Y'));
                $results_visited    = count(array_filter($app_rows, fn($r) => strtoupper(trim($r['results_visited'] ?? '')) === 'Y'));
                $time_on_result_avg = $this->average_duration(array_column($app_rows, 'time_on_results'));
                $app_reuse          = count(array_filter($app_rows, fn($r) => strtoupper(trim($r['app_reuse'] ?? '')) === 'Y'));
                $liked              = count(array_filter($app_rows, fn($r) => strtoupper(trim($r['results_liked'] ?? '')) === 'Y'));
                $disliked           = count(array_filter($app_rows, fn($r) => strtoupper(trim($r['results_disliked'] ?? '')) === 'Y'));

                fputcsv($csv_stream, [
                    $visitor_total,
                    $time_on_app_avg,
                    $app_use_total,
                    $results_visited,
                    $time_on_result_avg,
                    $app_reuse,
                    $liked,
                    $disliked,
                    $now_stamp
                ]);

                fputcsv($csv_stream, []);
            }

            rewind($csv_stream);
            $csv_data = stream_get_contents($csv_stream);
            fclose($csv_stream);

            $ts       = (string) time();
            $checksum = hash('sha256', $csv_data);
            $sig      = base64_encode(hash_hmac('sha256', $ts . ':' . $checksum, $secret, true));

            // Upload to remote server
            $upload_url = $api_base . '/wp-json/aiao/v1/csv-upload';
            $args = [
                'method'  => 'POST',
                'timeout' => 60,
                'headers' => [
                    'X-Filename'    => $csv_filename,
                    'Content-Type'     => 'text/csv',
                    'X-AIAO-Key'       => $key,
                    'X-AIAO-Timestamp' => $ts,
                    'X-AIAO-Checksum'  => $checksum,
                    'X-AIAO-Signature' => $sig,
                    'X-AIAO-Filename'  => $csv_filename,
                    'Expect'           => '',
                ],
                'body'    => $csv_data,
                'sslverify' => true,
            ];

            $response = wp_remote_post($upload_url, $args);

            if (is_wp_error($response)) {
                error_log('CSV Upload Failed: ' . $response->get_error_message());
                wp_send_json_error('CSV upload failed');
            } else {
                error_log('CSV uploaded successfully: ' . $csv_filename);
                if (!wp_next_scheduled('ai_app_onsite_user_stats_cron')) {
                    $random_time = $this->ai_app_onsite_generate_random_time();
                    wp_schedule_single_event($random_time, 'ai_app_onsite_user_stats_cron');
                }
                wp_send_json_success('CSV uploaded and sent successfully');
            }
        }
        
    }

    new AI_APP_ONSITE_User_Stats_Handler(); // Instantiate the class
}
