<?php
/**
 * Site Context
 *
 * This file contains all site context management, including content strategy AI agent functionality.
 *
 * @package Simple_Ai_Auto_Post
 * @since 1.0.0
 */

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

// Make sure this file is being included by a parent file.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Strip Gutenberg block comments but preserve semantic HTML.
 *
 * Removes <!-- wp:* --> block comments while keeping useful HTML structure
 * like headings, paragraphs, lists, and links that help AI understand content.
 *
 * @param string $content The content to clean.
 * @return string Content with block comments removed but HTML preserved.
 */
function saiap_strip_block_comments( $content ) {
	// Remove Gutenberg block comments (<!-- wp:anything --> and <!-- /wp:anything -->)
	$content = preg_replace( '/<!--\s*\/?wp:[^>]*-->/s', '', $content );

	// Clean up excessive whitespace left behind
	$content = preg_replace( '/\n{3,}/', "\n\n", $content );

	return trim( $content );
}

/**
 * Render the Post Map CTA banner for licensed users with no post maps.
 * This banner encourages users to create post maps to improve content generation.
 * Hidden by default; JavaScript shows it when post types list is empty.
 *
 * @param string $page_context Optional context identifier for the page ('generate', 'site-context', 'scheduler').
 */
function saiap_render_post_map_cta( $page_context = '' ) {
	// Only show for licensed users
	$license_key = get_option( 'saiap_license_key', '' );
	if ( empty( $license_key ) ) {
		return;
	}

	$site_context_url = admin_url( 'admin.php?page=saiap&tab=site-context' );
	?>
	<div id="saiap-post-map-cta" class="saiap-post-map-cta notice notice-info" style="display: none;">
		<div class="saiap-post-map-cta-content">
			<span class="dashicons dashicons-lightbulb"></span>
			<div class="saiap-post-map-cta-text">
				<strong><?php esc_html_e( 'Improve your AI-generated content with Post Maps', 'clearpost-simple-ai-auto-post' ); ?></strong>
				<p><?php esc_html_e( 'Post Maps teach the AI your preferred content structure, style, and format. Create one from an example - just drop in the URL.', 'clearpost-simple-ai-auto-post' ); ?></p>
			</div>
			<?php if ( 'site-context' !== $page_context ) : ?>
				<a href="<?php echo esc_url( $site_context_url ); ?>" class="button button-primary">
					<?php esc_html_e( 'Create a Post Map', 'clearpost-simple-ai-auto-post' ); ?>
				</a>
			<?php else : ?>
				<button type="button" id="saiap-post-map-cta-add" class="button button-primary">
					<?php esc_html_e( 'Create a Post Map', 'clearpost-simple-ai-auto-post' ); ?>
				</button>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render the Context tab
 */
function saiap_render_site_context_tab() {
	// Get site context
	$site_context = get_option( 'saiap_site_context', array() );
	$last_updated = get_option( 'saiap_context_last_updated', 0 );

	// Get cached context data
	$cached_context = get_option( 'saiap_context_cache', null );

	// Format the last updated date
	$last_updated_formatted = $last_updated ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $last_updated ) : __( 'Never', 'clearpost-simple-ai-auto-post' );

	// Show tracking consent prompt if user just started trial.
	// phpcs:ignore WordPress.Security.NonceVerification.Recommended
	if ( isset( $_GET['trial_started'] ) && '1' === $_GET['trial_started'] ) {
		if ( function_exists( 'saiap_render_tracking_consent_prompt' ) ) {
			saiap_render_tracking_consent_prompt();
		}
	}

	// Check if context was auto-loaded from checkout flow
	$context_auto_loaded = get_option( 'saiap_context_auto_loaded', false );

	?>
	<?php if ( $context_auto_loaded ) : ?>
	<div class="notice notice-success" style="margin: 0 0 20px 0; padding: 12px 16px; border-left: 4px solid #46b450;">
		<p style="margin: 0;">
			<strong><?php esc_html_e( 'Your site has been analyzed!', 'clearpost-simple-ai-auto-post' ); ?></strong>
			<?php esc_html_e( 'We pre-generated your context during checkout. You can refine it below or start generating content right away.', 'clearpost-simple-ai-auto-post' ); ?>
		</p>
	</div>
	<?php endif; ?>
	<div class="container">
		<div class="row">
			<div class="col col-12">
				<div class="card spacing-24">
					<h2 class="spacing-16-row"><?php esc_html_e( 'Context + SEO AI Agent', 'clearpost-simple-ai-auto-post' ); ?></h2>
					
					<div class="spacing-16">
						<p class="body-text">
							<?php esc_html_e( 'The Context + SEO AI Agent autonomously learns your site, runs SEO analysis, finds the best keywords in your niche, and maintains a context architecture to create 10x more relevant content that naturally ranks.', 'clearpost-simple-ai-auto-post' ); ?>
						</p>
						
						<p class="small-text spacing-8">
							<?php esc_html_e( 'Last updated:', 'clearpost-simple-ai-auto-post' ); ?> <strong><span class="saiap-last-updated-time"><?php echo esc_html( $last_updated_formatted ); ?></span></strong>
						</p>
						
						<div class="spacing-16">
							<button id="saiap-update-context" class="primary-button">
								<?php esc_html_e( 'Update Context Now', 'clearpost-simple-ai-auto-post' ); ?>
							</button>
							<button id="saiap-refresh-context" class="secondary-button" title="<?php esc_attr_e( 'Refresh from server without regenerating', 'clearpost-simple-ai-auto-post' ); ?>">
								<?php esc_html_e( 'Refresh', 'clearpost-simple-ai-auto-post' ); ?>
							</button>

						<button id="saiap-toggle-context" class="secondary-button" style="float: right;">
							<span class="saiap-toggle-text"><?php esc_html_e( 'Hide Details', 'clearpost-simple-ai-auto-post' ); ?></span>
							<span class="saiap-toggle-icon">▲</span>
						</button>
						</div>
					</div>
					
					<!-- Error message -->
					<div id="saiap-context-error" class="spacing-16" style="display: none;">
						<p class="body-text" style="color: var(--warning-color);">
							<?php esc_html_e( 'Error loading context data. Please try again.', 'clearpost-simple-ai-auto-post' ); ?>
						</p>
					</div>
				
					<div id="saiap-context-display" class="saiap-context-drawer" style="display: block; margin-top: 16px; border-top: 1px solid #ddd; padding-top: 16px;">
						<!-- Content will be loaded here by site-context.js -->
					</div>

					<?php saiap_render_post_map_cta( 'site-context' ); ?>
					
					<!-- Modals (hardcoded shells; populated and shown by JS) -->
					<div id="saiap-modal-overlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:1000;"></div>
					<div id="saiap-add-post-type-modal" style="display:none;position:fixed;left:50%;top:20%;transform:translateX(-50%);background:#fff;padding:16px;border-radius:6px;min-width:360px;z-index:1001;">
						<h4 style="margin-top:0;"><?php esc_html_e( 'Add Post Type from URL', 'clearpost-simple-ai-auto-post' ); ?></h4>
						<label for="saiap-exemplar-url"><?php esc_html_e( 'Exemplar URL', 'clearpost-simple-ai-auto-post' ); ?></label>
						<input type="url" id="saiap-exemplar-url" class="widefat" placeholder="https://example.com/post" />
						<p class="small-text" style="margin:8px 0 0;">
							<a href="#" id="saiap-add-post-type-manual"><?php esc_html_e( 'Or create it manually instead', 'clearpost-simple-ai-auto-post' ); ?></a>
						</p>
						<div style="margin-top:12px;display:flex;gap:8px;justify-content:flex-end;">
							<button id="saiap-add-post-type-cancel" class="secondary-button"><?php esc_html_e( 'Cancel', 'clearpost-simple-ai-auto-post' ); ?></button>
							<button id="saiap-add-post-type-submit" class="primary-button"><?php esc_html_e( 'Create', 'clearpost-simple-ai-auto-post' ); ?></button>
				</div>
			</div>
					
                    <div id="saiap-edit-post-type-modal" style="display:none;position:fixed;left:50%;top:10%;transform:translateX(-50%);background:#fff;padding:16px;border-radius:6px;min-width:520px;max-width:90vw;max-height:80vh;overflow:auto;z-index:1001;">
						<h4 style="margin-top:0;"><?php esc_html_e( 'Edit Post Type', 'clearpost-simple-ai-auto-post' ); ?></h4>
						<input type="hidden" id="saiap-pt-type-key" />
						<div class="spacing-8-row">
							<label for="saiap-pt-name"><?php esc_html_e( 'Name', 'clearpost-simple-ai-auto-post' ); ?></label>
							<input type="text" id="saiap-pt-name" class="widefat" />
						</div>
						<div class="spacing-8-row">
							<label for="saiap-pt-key"><?php esc_html_e( 'Type Key', 'clearpost-simple-ai-auto-post' ); ?></label>
							<input type="text" id="saiap-pt-key" class="widefat" readonly />
						</div>
						<div class="spacing-8-row">
							<label for="saiap-pt-map"><?php esc_html_e( 'Post Map (Markdown)', 'clearpost-simple-ai-auto-post' ); ?></label>
							<textarea id="saiap-pt-map" class="widefat" rows="6"></textarea>
						</div>
						<div class="spacing-8-row">
							<label for="saiap-pt-style"><?php esc_html_e( 'Style Notes', 'clearpost-simple-ai-auto-post' ); ?></label>
							<textarea id="saiap-pt-style" class="widefat" rows="4"></textarea>
						</div>
						<div class="spacing-8-row">
							<label><?php esc_html_e( 'Exemplars (URLs only, up to 4)', 'clearpost-simple-ai-auto-post' ); ?></label>
							<div id="saiap-pt-exemplars" style="display:flex;flex-wrap:wrap;gap:8px;"></div>
							<div style="display:flex;gap:8px;margin-top:8px;">
								<input type="url" id="saiap-pt-ex-url" class="widefat" placeholder="https://example.com/post" />
								<button id="saiap-pt-ex-add" class="secondary-button"><?php esc_html_e( 'Add URL', 'clearpost-simple-ai-auto-post' ); ?></button>
							</div>
							<p class="small-text"><?php esc_html_e( 'Provide an external article URL or choose one of your existing WordPress posts. Up to 4 total.', 'clearpost-simple-ai-auto-post' ); ?></p>
						</div>
						<div style="margin-top:12px;display:flex;gap:8px;justify-content:flex-end;">
							<button id="saiap-edit-post-type-cancel" class="secondary-button"><?php esc_html_e( 'Cancel', 'clearpost-simple-ai-auto-post' ); ?></button>
							<button id="saiap-edit-post-type-save" class="primary-button"><?php esc_html_e( 'Save', 'clearpost-simple-ai-auto-post' ); ?></button>
						</div>
					</div>
				</div>
				<!-- Pick internal post modal -->
				<div id="saiap-pick-wp-post-modal" style="display:none;position:fixed;left:50%;top:15%;transform:translateX(-50%);background:#fff;padding:16px;border-radius:6px;min-width:520px;max-width:90vw;max-height:80vh;overflow:auto;z-index:1001;">
					<h4 style="margin-top:0;"><?php esc_html_e( 'Select a Post from Your Site', 'clearpost-simple-ai-auto-post' ); ?></h4>
					<div class="spacing-8-row">
						<input type="text" id="saiap-pick-search" class="widefat" placeholder="<?php esc_attr_e( 'Search by title…', 'clearpost-simple-ai-auto-post' ); ?>" />
					</div>
					<div id="saiap-pick-list" style="margin-top:10px; max-height: 400px; overflow:auto; border:1px solid #ddd; padding:8px;"></div>
					<div style="margin-top:12px;display:flex;gap:8px;justify-content:flex-end;">
						<button id="saiap-pick-cancel" class="secondary-button"><?php esc_html_e( 'Close', 'clearpost-simple-ai-auto-post' ); ?></button>
					</div>
				</div>
			</div>
		</div>
	</div>
	<?php
}

/**
 * AJAX handler for fetching site context
 */
function saiap_ajax_fetch_context() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( __( 'You do not have sufficient permissions to perform this action.', 'clearpost-simple-ai-auto-post' ) );
		return;
	}

	$license_key = get_option( 'saiap_license_key' );
	if ( empty( $license_key ) ) {
		wp_send_json_error( array( 'error' => 'License key not found' ) );
		return;
	}

	// Get last updated timestamp
	$last_updated           = get_option( 'saiap_context_last_updated', 0 );
	$last_updated_formatted = $last_updated ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $last_updated ) : __( 'Never', 'clearpost-simple-ai-auto-post' );

	// Check if we have cached data
	$cached_context = get_transient( 'saiap_site_context_data' );
	if ( $cached_context ) {
		wp_send_json_success(
			array(
				'context'      => $cached_context,
				'fromCache'    => true,
				'last_updated' => $last_updated_formatted,
			)
		);
		return;
	}

	// No cache, fetch from API
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();

	$response = wp_remote_post(
		'https://saiap.gopurposego.com/api/context',
		array(
			'headers' => array(
				'Content-Type' => 'application/json',
				'Accept'       => 'application/json',
			),
			'body'    => wp_json_encode(
				array(
					'license_key' => $license_key,
					'domain'      => $domain,
				)
			),
			'timeout' => 30,
		)
	);

	if ( is_wp_error( $response ) ) {
		wp_send_json_error(
			array(
				/* translators: %s: Error message from server */
				'message' => sprintf( __( 'Error retrieving site context: %s', 'clearpost-simple-ai-auto-post' ), $response->get_error_message() ),
			)
		);
		return;
	}

	$status_code = wp_remote_retrieve_response_code( $response );
	$body        = wp_remote_retrieve_body( $response );
	$data        = json_decode( $body, true );

    if ( $status_code !== 200 || ! isset( $data['context'] ) ) {
        // If premium indicates no context exists yet, map to a friendly first-time response
        if ( $status_code === 404 && isset( $data['code'] ) && $data['code'] === 'NO_CONTEXT' ) {
            wp_send_json_success(
                array(
                    'context'         => null,
                    'fromCache'       => false,
                    'last_updated'    => $last_updated_formatted,
                    'no_context_yet'  => true,
                    'message'         => __( 'No site context yet. Click "Update Context Now" to generate your site summary and taxonomy rules.', 'clearpost-simple-ai-auto-post' ),
                )
            );
            return;
        }

        wp_send_json_error(
            array(
                'message' => __( 'Failed to retrieve site context. Please try updating the context.', 'clearpost-simple-ai-auto-post' ),
            )
        );
        return;
    }

	// Cache the context data for 24 hours
	set_transient( 'saiap_site_context_data', $data['context'], 24 * HOUR_IN_SECONDS );

	wp_send_json_success(
		array(
			'context'      => $data['context'],
			'fromCache'    => false,
			'last_updated' => $last_updated_formatted,
		)
	);
}
add_action( 'wp_ajax_saiap_fetch_context', 'saiap_ajax_fetch_context' );

/**
 * AJAX handler for clearing the context cache
 */
function saiap_ajax_clear_context_cache() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( __( 'You do not have sufficient permissions to perform this action.', 'clearpost-simple-ai-auto-post' ) );
		return;
	}

	// Clear the context cache
	delete_transient( 'saiap_site_context_data' );

	wp_send_json_success();
}
add_action( 'wp_ajax_saiap_clear_context_cache', 'saiap_ajax_clear_context_cache' );

/**
 * AJAX handler for updating context fields when the user manually updates the context
 */
function saiap_ajax_update_context_fields() {
	// Check nonce
	if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'saiap_update_context' ) ) {
		wp_send_json_error( 'Invalid nonce' );
		return;
	}

	// Check permissions
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
		return;
	}

	// Get license key
	$license_key = get_option( 'saiap_license_key' );
	if ( empty( $license_key ) ) {
		wp_send_json_error( 'License key not found' );
		return;
	}

	// Get and sanitize context fields from POST data
	// For markdown fields (summary, style_guide, etc.), we use a custom sanitization that:
	// - Strips HTML tags (for security)
	// - Preserves newlines and markdown characters (##, -, *, etc.)
	// - Does NOT HTML-encode characters (& stays &, not &amp;)
	$context_fields = null;
	if ( isset( $_POST['context_fields'] ) && is_array( $_POST['context_fields'] ) ) {
		$raw_fields     = wp_unslash( $_POST['context_fields'] );
		$context_fields = array();

		// Summary: Strip HTML tags but preserve markdown formatting (##, -, *, newlines, etc.)
		if ( isset( $raw_fields['summary'] ) ) {
			$context_fields['summary'] = wp_strip_all_tags( $raw_fields['summary'] );
		}

		// Topics: Array of simple strings - sanitize each item
		if ( isset( $raw_fields['topics'] ) ) {
			if ( is_array( $raw_fields['topics'] ) ) {
				$context_fields['topics'] = array_map( 'sanitize_text_field', $raw_fields['topics'] );
			} else {
				$context_fields['topics'] = sanitize_text_field( $raw_fields['topics'] );
			}
		}

		// Style guide: Strip HTML but preserve newlines and formatting
		if ( isset( $raw_fields['style_guide'] ) ) {
			$context_fields['style_guide'] = wp_strip_all_tags( $raw_fields['style_guide'] );
		}

		// Custom context: Nested structure with content field
		if ( isset( $raw_fields['custom_context'] ) && is_array( $raw_fields['custom_context'] ) ) {
			$context_fields['custom_context'] = array();
			if ( isset( $raw_fields['custom_context']['content'] ) ) {
				$context_fields['custom_context']['content'] = wp_strip_all_tags( $raw_fields['custom_context']['content'] );
			}
		}

		// Taxonomy settings: Strip HTML but preserve newlines
		if ( isset( $raw_fields['taxonomy_settings'] ) ) {
			$context_fields['taxonomy_settings'] = wp_strip_all_tags( $raw_fields['taxonomy_settings'] );
		}

		// Future ideas: Array of simple strings
		if ( isset( $raw_fields['future_ideas'] ) ) {
			if ( is_array( $raw_fields['future_ideas'] ) ) {
				$context_fields['future_ideas'] = array_map( 'sanitize_text_field', $raw_fields['future_ideas'] );
			} else {
				$context_fields['future_ideas'] = sanitize_text_field( $raw_fields['future_ideas'] );
			}
		}
	} elseif ( isset( $_POST['context_fields'] ) ) {
		// Handle non-array context fields
		$context_fields = sanitize_text_field( wp_unslash( $_POST['context_fields'] ) );
	}

	if ( empty( $context_fields ) ) {
		wp_send_json_error( 'No context fields provided' );
		return;
	}

	// Ensure context_fields is properly formatted
	if ( is_array( $context_fields ) ) {
		// Format topics and future_ideas if they're strings
		if ( isset( $context_fields['topics'] ) && ! is_array( $context_fields['topics'] ) ) {
			$context_fields['topics'] = array_filter( array_map( 'trim', explode( "\n", $context_fields['topics'] ) ) );
		}
		if ( isset( $context_fields['future_ideas'] ) && ! is_array( $context_fields['future_ideas'] ) ) {
			$context_fields['future_ideas'] = array_filter( array_map( 'trim', explode( "\n", $context_fields['future_ideas'] ) ) );
		}
	} else {
		wp_send_json_error( 'Invalid context fields format' );
		return;
	}

	// Prepare the request to the premium server
	$args = array(
		'body'    => wp_json_encode(
			array(
				'license_key'    => $license_key,
				'domain'         => saiap_get_server_host(),
				'context_fields' => $context_fields,
			)
		),
		'headers' => array(
			'Content-Type' => 'application/json',
		),
		'timeout' => 60,
	);

	// Make the request to the premium server
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/context/update-fields', $args );

	// Check for errors
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( 'Error communicating with the server: ' . $response->get_error_message() );
		return;
	}

	// Get response body
	$body = wp_remote_retrieve_body( $response );
	$data = json_decode( $body, true );

	// Check response status
	$status_code = wp_remote_retrieve_response_code( $response );
	if ( $status_code !== 200 ) {
		wp_send_json_error( 'Error from server: ' . ( $data['error'] ?? 'Unknown error' ) );
		return;
	}

	// If the request was successful and custom context data was provided, store it locally as well
	if ( $status_code === 200 && isset( $context_fields['custom_context']['content'] ) ) {
		update_option( 'saiap_custom_site_context', wp_kses_post( $context_fields['custom_context']['content'] ) );
	}

	// Clear the transient cache so that next fetch returns fresh data with updated fields
	delete_transient( 'saiap_site_context_data' );

	// Return success response
	wp_send_json_success( $data );
}
add_action( 'wp_ajax_saiap_update_context_fields', 'saiap_ajax_update_context_fields' );

/**
 * AJAX: List Post Types
 */
function saiap_ajax_post_types_list() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$args        = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain ) ),
		'timeout' => 30,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/list', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 200 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_list', 'saiap_ajax_post_types_list' );

/**
 * AJAX: Upsert Post Type (proxy)
 */
function saiap_ajax_post_types_upsert() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$type        = isset( $_POST['type'] ) ? json_decode( wp_unslash( $_POST['type'] ), true ) : null;
	if ( empty( $type ) || ! is_array( $type ) ) {
		wp_send_json_error( 'Invalid type payload' );
	}
	$args = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain, 'type' => $type ) ),
		'timeout' => 60,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/upsert', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 200 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_upsert', 'saiap_ajax_post_types_upsert' );

/**
 * AJAX: Delete Post Type (proxy)
 */
function saiap_ajax_post_types_delete() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$type_key    = isset( $_POST['type_key'] ) ? sanitize_text_field( wp_unslash( $_POST['type_key'] ) ) : '';
	if ( empty( $type_key ) ) {
		wp_send_json_error( 'Missing type_key' );
	}
	$args = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain, 'type_key' => $type_key ) ),
		'timeout' => 30,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/delete', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 200 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_delete', 'saiap_ajax_post_types_delete' );

/**
 * AJAX: Create From URL (proxy)
 */
function saiap_ajax_post_types_from_url() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$url         = isset( $_POST['url'] ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : '';
	if ( empty( $url ) ) {
		wp_send_json_error( 'Missing URL' );
	}
	$args = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain, 'url' => $url ) ),
		'timeout' => 120,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/from-exemplar', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 200 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_from_url', 'saiap_ajax_post_types_from_url' );

/**
 * AJAX: Get Post Type (proxy)
 */
function saiap_ajax_post_types_get() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$type_key    = isset( $_POST['type_key'] ) ? sanitize_text_field( wp_unslash( $_POST['type_key'] ) ) : '';
	if ( empty( $type_key ) ) {
		wp_send_json_error( 'Missing type_key' );
	}
	$args = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain, 'type_key' => $type_key ) ),
		'timeout' => 30,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/get', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 200 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_get', 'saiap_ajax_post_types_get' );

/**
 * AJAX: Create From URL (ASYNC start)
 */
function saiap_ajax_post_types_from_url_async() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Insufficient permissions' );
	}
	$license_key = get_option( 'saiap_license_key' );
	$domain      = saiap_get_server_host();
	$url         = isset( $_POST['url'] ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : '';
	if ( empty( $url ) ) {
		wp_send_json_error( 'Missing URL' );
	}
	$args = array(
		'headers' => array( 'Content-Type' => 'application/json', 'Accept' => 'application/json' ),
		'body'    => wp_json_encode( array( 'license_key' => $license_key, 'domain' => $domain, 'url' => $url ) ),
		'timeout' => 30,
	);
	$response = wp_remote_post( 'https://saiap.gopurposego.com/api/site-types/from-exemplar/async', $args );
	if ( is_wp_error( $response ) ) {
		wp_send_json_error( $response->get_error_message() );
	}
	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( 202 !== $code ) {
		wp_send_json_error( $body && isset( $body['error'] ) ? $body['error'] : 'Unknown error' );
	}
	wp_send_json_success( $body );
}
add_action( 'wp_ajax_saiap_post_types_from_url_async', 'saiap_ajax_post_types_from_url_async' );
/**
 * Get the site context for content generation
 *
 * @return array The site context
 */
function saiap_get_site_context() {

	// Get homepage content
	$homepage_id = get_option( 'page_on_front' );
	if ( ! $homepage_id ) {
		// If no static homepage is set, get the blog posts page
		$homepage_id = get_option( 'page_for_posts' );
	}

	$homepage_content = '';
	if ( $homepage_id ) {
		$homepage = get_post( $homepage_id );
		if ( $homepage ) {
			$homepage_content = saiap_strip_block_comments( $homepage->post_content );
		}
	}

	// Get site description
	$site_description = get_bloginfo( 'description' );

	// Get post limits from settings
	$post_limit = absint( get_option( 'saiap_context_post_limit', 50 ) );
	$post_age   = absint( get_option( 'saiap_context_post_age', 365 ) );

	// Get all public post types instead of just the configured one
	$public_post_types = get_post_types( array( 'public' => true ), 'names' );
	// Exclude attachments as they're not typically useful for content analysis
	if ( isset( $public_post_types['attachment'] ) ) {
		unset( $public_post_types['attachment'] );
	}

	// Get recent posts from all public post types
	$args = array(
		'post_type'        => array_values( $public_post_types ),  // Use all public post types
		'posts_per_page'   => $post_limit,
		'post_status'      => array( 'publish', 'draft' ),
		'orderby'          => 'date',
		'order'            => 'DESC',
		'date_query'       => array(
			array(
				'after'     => $post_age . ' days ago',
				'inclusive' => true,
			),
		),
		'suppress_filters' => false,
	);

	$query = new WP_Query( $args );

	$formatted_posts = array();
	if ( $query->have_posts() ) {
		while ( $query->have_posts() ) {
			$query->the_post();
			$post              = get_post();
			$post_date         = get_post_time( 'c', true, $post );
			$post_modified     = get_post_modified_time( 'c', true, $post );
			$post_type         = get_post_type( $post );
			
			// Dynamically get all taxonomies for the current post type
			$all_taxonomies = get_object_taxonomies( $post_type, 'objects' );
			$taxonomy_data = array();

            

			foreach ( $all_taxonomies as $tax_slug => $taxonomy ) {
                
				
				$terms = wp_get_post_terms( $post->ID, $tax_slug, array( 'fields' => 'all' ) );

                

				if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
					// Pass raw term data
					$raw_term_data = array();
					foreach ( $terms as $term ) {
						$raw_term_data[] = array(
							'term_id' => $term->term_id,
							'name' => $term->name,
							'slug' => $term->slug,
							'parent' => $term->parent,
							'description' => $term->description
						);
					}

					$taxonomy_data[ $tax_slug ] = array(
						'terms'        => $raw_term_data,
						'hierarchical' => $taxonomy->hierarchical,
					);
					
                    
				} else {
                    
				}
			}

            
			
			$formatted_posts[] = array(
				'ID'           => $post->ID,
				'title'        => $post->post_title,
				'content'      => saiap_strip_block_comments( $post->post_content ),
				'published_at' => $post_date,
				'modified_at'  => $post_modified,
				'post_type'    => $post_type,
				'taxonomy_data' => $taxonomy_data,
				'permalink'    => get_permalink( $post->ID ),
				'post_status'  => $post->post_status,
			);
		}
		wp_reset_postdata();
	}

	// Aggregate post type details for quick reference
	$post_types_overview = array();
	foreach ( $public_post_types as $pt_slug ) {
		$obj                             = get_post_type_object( $pt_slug );
		$count_obj                       = wp_count_posts( $pt_slug );
		$post_types_overview[ $pt_slug ] = array(
			'label' => $obj && isset( $obj->labels->name ) ? $obj->labels->name : ucfirst( $pt_slug ),
			'count' => isset( $count_obj->publish ) ? (int) $count_obj->publish : 0,
		);
	}

	// Aggregate taxonomy details
	$public_taxonomies   = get_taxonomies( array( 'public' => true ), 'objects' );
	$taxonomies_overview = array();
	foreach ( $public_taxonomies as $tax_slug => $tax_obj ) {
		$terms = get_terms(
			array(
				'taxonomy'   => $tax_slug,
				'hide_empty' => false,
				'fields'     => 'names',
			)
		);
		if ( is_wp_error( $terms ) ) {
			$terms = array();
		}
		$taxonomies_overview[ $tax_slug ] = array(
			'label' => $tax_obj->label,
			'count' => count( $terms ),
			'terms' => $terms,
		);
	}

	$context = array(
		'site_data'  => array(
			'domain'              => saiap_get_server_host(),
			'homepage_content'    => $homepage_content,
			'site_description'    => $site_description,
			'permalink_structure' => get_option( 'permalink_structure', '' ),
		),
		'posts'      => $formatted_posts,
		'postTypes'  => $post_types_overview,
		'taxonomies' => $taxonomies_overview,
	);

	// Include any manually stored custom context (editable by the admin)
	$stored_custom_context = get_option( 'saiap_custom_site_context', '' );
	if ( ! empty( $stored_custom_context ) ) {
		$context['customContext'] = $stored_custom_context;
	}

	return $context;
}

/**
 * Update the site context for content generation
 *
 * This function updates the site context for content generation by collecting the latest posts and site data.
 * It then sends the context to the premium API for storage and retrieval.
 *
 * @return void
 */
function saiap_update_site_context() {
	$license_key = get_option( 'saiap_license_key' );

	$context = saiap_get_site_context();

	// Prepare posts for API and collect present IDs
	$posts_for_api = array_map(
		function ( $post ) {
			return array(
				'ID'           => $post['ID'],
				'title'        => $post['title'],
				'content'      => $post['content'],
				'published_at' => $post['published_at'],
				'modified_at'  => $post['modified_at'],
				'post_type'    => $post['post_type'],
				'taxonomy_data' => isset( $post['taxonomy_data'] ) ? $post['taxonomy_data'] : null,
				'permalink'    => isset( $post['permalink'] ) ? $post['permalink'] : null,
				'post_status'  => isset( $post['post_status'] ) ? $post['post_status'] : null,
			);
		},
		$context['posts']
	);
	$present_post_ids = array_map(
		function( $p ) { return $p['ID']; },
		$posts_for_api
	);

	// Build batches using a byte-budget (2MB) with 10% overhead
	$target_bytes = 2000000;
	$batches      = array();
	$current_batch = array();
	$current_bytes = 0;

	foreach ( $posts_for_api as $post_payload ) {
		$post_bytes = strlen( wp_json_encode( $post_payload ) );
		$with_overhead = (int) ceil( $post_bytes * 1.10 );
		if ( ( $current_bytes + $with_overhead ) <= $target_bytes ) {
			$current_batch[] = $post_payload;
			$current_bytes  += $with_overhead;
		} else {
			if ( ! empty( $current_batch ) ) {
				$batches[] = $current_batch;
				$current_batch = array( $post_payload );
				$current_bytes = $with_overhead;
			} else {
				// Single-post floor: allow one large post up to ~9MB; otherwise skip for now
				if ( $with_overhead <= 9000000 ) {
					$batches[] = array( $post_payload );
				}
				$current_batch = array();
				$current_bytes = 0;
			}
		}
	}
	if ( ! empty( $current_batch ) ) {
		$batches[] = $current_batch;
	}

    // Send batches (aggregate errors, don't early return), with split-and-retry on 413
    $partial_errors    = array();
    $successful_chunks = 0;
    $queue             = $batches;
    $total_chunks      = count( $batches );
    $processed_index   = 0;

    while ( ! empty( $queue ) ) {
        $chunk_posts = array_shift( $queue );
        $processed_index++;

		$partial_body = wp_json_encode(
			array(
				'license_key' => $license_key,
				'domain'      => $context['site_data']['domain'],
				'site_data'   => array(
					'homepage_content' => $context['site_data']['homepage_content'],
					'site_description' => $context['site_data']['site_description'],
				),
				'posts'       => $chunk_posts,
				'is_partial'  => true,
				// Include aggregated metadata for richer context on the premium side
				'post_types'  => $context['postTypes'],
				'taxonomies'  => $context['taxonomies'],
				'customContext' => isset( $context['customContext'] ) ? $context['customContext'] : null,
			)
		);

	$response = wp_remote_post(
		'https://saiap.gopurposego.com/api/context/update',
		array(
			'headers' => array(
				'Content-Type' => 'application/json',
				'Accept'       => 'application/json',
			),
			'body'    => $partial_body,
			'timeout' => 180,
		)
	);

        if ( is_wp_error( $response ) ) {
            $partial_errors[] = array(
                'chunk'   => $processed_index,
                'total'   => $total_chunks,
                'message' => $response->get_error_message(),
                'status'  => null,
            );
            continue;
        }

        $status_code = wp_remote_retrieve_response_code( $response );
        if ( $status_code === 413 ) {
            $body_err = wp_remote_retrieve_body( $response );
            $data_err = json_decode( $body_err, true );
            // Split roughly in half and requeue if possible
            if ( count( $chunk_posts ) > 1 ) {
                $mid = (int) floor( count( $chunk_posts ) / 2 );
                $first_half  = array_slice( $chunk_posts, 0, $mid );
                $second_half = array_slice( $chunk_posts, $mid );
                array_unshift( $queue, $second_half, $first_half );
                // Do not count as error yet; allow retry
                continue;
            } else {
                // Single item still too large; record error
                $partial_errors[] = array(
                    'chunk'   => $processed_index,
                    'total'   => $total_chunks,
                    'message' => 'Payload too large for single item',
                    'status'  => 413,
                );
                continue;
            }
        }

        if ( $status_code !== 200 ) {
            $body_err     = wp_remote_retrieve_body( $response );
            $data_err     = json_decode( $body_err, true );
            $error_detail = ( $data_err && isset( $data_err['error'] ) ) ? $data_err['error'] : 'Server returned status code: ' . $status_code;
            $partial_errors[] = array(
                'chunk'   => $processed_index,
                'total'   => $total_chunks,
                'message' => $error_detail,
                'status'  => $status_code,
            );
            continue;
        }

        $successful_chunks++;
	}

	// Final prune request with IDs only
	$prune_body = wp_json_encode(
		array(
			'license_key'       => $license_key,
			'domain'            => $context['site_data']['domain'],
			'present_post_ids'  => $present_post_ids,
		)
	);

	$response = wp_remote_post(
		'https://saiap.gopurposego.com/api/context/update',
		array(
			'headers' => array(
				'Content-Type' => 'application/json',
				'Accept'       => 'application/json',
			),
			'body'    => $prune_body,
			'timeout' => 180,
		)
	);

    if ( is_wp_error( $response ) ) {
        $aggregate_note = '';
        if ( ! empty( $partial_errors ) ) {
            $aggregate_note = ' Partial errors: ' . wp_json_encode( $partial_errors );
        }
        return new WP_Error( 'api_error', 'Failed to finalize context update: ' . $response->get_error_message() . $aggregate_note );
    }

	$status_code = wp_remote_retrieve_response_code( $response );
	$body        = wp_remote_retrieve_body( $response );
	$data        = json_decode( $body, true );

    if ( $status_code !== 200 ) {
        $error_message = 'Failed to finalize context update. ';
        if ( $data && isset( $data['error'] ) ) {
            $error_message .= $data['error'];
        } else {
            $error_message .= 'Server returned status code: ' . $status_code;
        }
        if ( ! empty( $partial_errors ) ) {
            $error_message .= ' Partial errors: ' . wp_json_encode( $partial_errors );
        }
        return new WP_Error( 'api_error', $error_message );
    }

    // If all chunks failed but prune succeeded, surface aggregated error
    if ( $successful_chunks === 0 && $total_chunks > 0 ) {
        return new WP_Error( 'api_error', 'Failed to update context: all ' . $total_chunks . ' chunk(s) failed. Details: ' . wp_json_encode( $partial_errors ) );
    }

	// Store the last update timestamp
	$timestamp = time();
	update_option( 'saiap_context_last_updated', $timestamp );

	$has_failures = false;
	$has_changes  = true; // Default to true for backward compatibility

	// Check if the response includes information about changes
	if ( isset( $data['syncResult'] ) && isset( $data['syncResult']['hasChanges'] ) ) {
		$has_changes = $data['syncResult']['hasChanges'];
	}

	// Set appropriate message based on changes and failures
    if ( ! $has_changes ) {
		$message = 'No changes detected. Site context remains the same.';
	} else {
        $message = 'Site context updated successfully.';

        if ( isset( $data['syncResult'] ) && isset( $data['syncResult']['failedCount'] ) && $data['syncResult']['failedCount'] > 0 ) {
			$has_failures = true;
			$message     .= ' However, ' . $data['syncResult']['failedCount'] . ' posts failed to sync.';
		}
	}

    // Reflect any transport-level chunk failures in the flags/message
    if ( ! empty( $partial_errors ) ) {
        $has_failures = true;
        $message     .= ' Some chunks failed during upload.';
    }

	// Update cache if context is in the response
	if ( isset( $data['context'] ) ) {
		update_option( 'saiap_context_cache', $data['context'] );
	}

    return array(
		'message'      => $message,
		'has_failures' => $has_failures,
		'has_changes'  => $has_changes,
		'sync_result'  => isset( $data['syncResult'] ) ? $data['syncResult'] : null,
		'timestamp'    => $timestamp,
        'partial_errors' => ! empty( $partial_errors ) ? $partial_errors : null,
	);
}

/**
 * Wrapper function for WP Cron to handle the site context update
 */
function saiap_cron_update_site_context() {
	$result = saiap_update_site_context();
}

// Update context daily via WP Cron
add_action( 'saiap_daily_context_update', 'saiap_cron_update_site_context' );

/**
 * Schedule daily context updates
 */
function saiap_schedule_context_updates() {
	if ( ! wp_next_scheduled( 'saiap_daily_context_update' ) ) {
		wp_schedule_event( time(), 'daily', 'saiap_daily_context_update' );
	}
}
add_action( 'wp_loaded', 'saiap_schedule_context_updates' );

/**
 * AJAX handler for updating site context automatically
 */
function saiap_ajax_update_context() {
	// Check nonce
	if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'saiap_update_context' ) ) {
		wp_send_json_error( 'Invalid security token' );
		return;
	}

	// Check if user has permission
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'You do not have permission to perform this action' );
		return;
	}

	// Check if user has premium access (license key or active trial).
	if ( ! saiap_has_premium_access() ) {
		wp_send_json_error( 'Premium access required (license key or active trial)' );
		return;
	}

	// Update site context with error catching
	try {
		$result = saiap_update_site_context();
	} catch ( Exception $e ) {
		wp_send_json_error( 'An unexpected error occurred: ' . $e->getMessage() );
		return;
	} catch ( Error $e ) {
		wp_send_json_error( 'A fatal error occurred: ' . $e->getMessage() );
		return;
	}

	if ( is_wp_error( $result ) ) {
		wp_send_json_error( $result->get_error_message() );
	} elseif ( ! is_array( $result ) ) {
		wp_send_json_error( 'Unexpected response from context update' );
	} else {
		// Store the context in the cache for immediate display
		if ( isset( $result['context'] ) ) {
			update_option( 'saiap_context_cache', $result['context'] );
			// Invalidate transient cache so next fetch reflects latest context
			delete_transient( 'saiap_site_context_data' );
			// Optionally set fresh transient to avoid extra network fetch
			set_transient( 'saiap_site_context_data', $result['context'], 24 * HOUR_IN_SECONDS );
		} else {
			// No context returned; ensure stale transient is cleared
			delete_transient( 'saiap_site_context_data' );
		}

		// Ensure the last updated timestamp is set for immediate UI reflection
		update_option( 'saiap_context_last_updated', time() );

		// Get formatted timestamp for response
		$last_updated           = get_option( 'saiap_context_last_updated', 0 );
		$last_updated_formatted = $last_updated ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $last_updated ) : __( 'Never', 'clearpost-simple-ai-auto-post' );

		// Add the formatted timestamp to the response
		$result['last_updated'] = $last_updated_formatted;

		// Normalize sync_result key to syncResult for JavaScript
		if ( isset( $result['sync_result'] ) ) {
			$result['syncResult'] = $result['sync_result'];
			unset( $result['sync_result'] );
		}

		if ( function_exists( 'saiap_premium_onboarding_mark_step_complete' ) ) {
			saiap_premium_onboarding_mark_step_complete( 1 );
		}

		wp_send_json_success( $result );
	}
}
// Add the action hook to register the AJAX handler
add_action( 'wp_ajax_saiap_update_context', 'saiap_ajax_update_context' );

/**
 * AJAX handler for updating wizard data (edit mode).
 *
 * This is called when the user edits their business information from the Site Context tab.
 * Unlike the initial wizard submission, this does NOT trigger automated setup.
 */
function saiap_ajax_update_wizard_data() {
	check_ajax_referer( 'saiap_update_context', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied.', 'clearpost-simple-ai-auto-post' ) ) );
	}

	// Require license key (premium only feature).
	$license_key = get_option( 'saiap_license_key', '' );
	if ( empty( $license_key ) ) {
		wp_send_json_error( array( 'message' => __( 'License key not found.', 'clearpost-simple-ai-auto-post' ) ) );
	}

	// Sanitize wizard data fields (same sanitization as initial wizard submission).
	$site_name        = isset( $_POST['site_name'] ) ? sanitize_text_field( wp_unslash( $_POST['site_name'] ) ) : '';
	$site_description = isset( $_POST['site_description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['site_description'] ) ) : '';
	$niche            = isset( $_POST['niche'] ) ? sanitize_text_field( wp_unslash( $_POST['niche'] ) ) : '';
	$target_audience  = isset( $_POST['target_audience'] ) ? sanitize_textarea_field( wp_unslash( $_POST['target_audience'] ) ) : '';
	$seed_topics      = isset( $_POST['seed_topics'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['seed_topics'] ) ) : array();
	$locations        = isset( $_POST['locations'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['locations'] ) ) : array();
	$competitor_urls  = isset( $_POST['competitor_urls'] ) ? array_map( 'esc_url_raw', wp_unslash( $_POST['competitor_urls'] ) ) : array();

	// Filter empty values.
	$seed_topics     = array_filter( $seed_topics );
	$locations       = array_filter( $locations );
	$competitor_urls = array_filter( $competitor_urls );

	// Validate minimum requirements.
	if ( empty( $site_description ) ) {
		wp_send_json_error( array( 'message' => __( 'Please describe what your site is about.', 'clearpost-simple-ai-auto-post' ) ) );
	}

	if ( empty( $niche ) ) {
		wp_send_json_error( array( 'message' => __( 'Please enter your niche or industry.', 'clearpost-simple-ai-auto-post' ) ) );
	}

	if ( count( $seed_topics ) < 3 ) {
		wp_send_json_error( array( 'message' => __( 'Please enter at least 3 seed topics.', 'clearpost-simple-ai-auto-post' ) ) );
	}

	// Build wizard data.
	$wizard_data = array(
		'site_name'        => $site_name,
		'site_description' => $site_description,
		'niche'            => $niche,
		'target_audience'  => $target_audience,
		'seed_topics'      => array_values( $seed_topics ),
		'locations'        => array_values( $locations ),
		'competitor_urls'  => array_values( $competitor_urls ),
	);

	// Update local option.
	update_option( 'saiap_onboarding_wizard_data', $wizard_data );

	// Sync to backend.
	$domain        = wp_parse_url( home_url(), PHP_URL_HOST );
	$save_response = wp_remote_post(
		SAIAP_PREMIUM_API_URL . '/api/trial/wizard-data',
		array(
			'timeout' => 30,
			'body'    => wp_json_encode(
				array(
					'domain'      => $domain,
					'license_key' => $license_key,
					'wizard_data' => $wizard_data,
				)
			),
			'headers' => array(
				'Content-Type' => 'application/json',
			),
		)
	);

	// Track backend sync errors (local save succeeded, so user data is safe).
	if ( is_wp_error( $save_response ) && function_exists( 'saiap_track_event' ) ) {
		saiap_track_event(
			'wizard_data_sync_failed',
			array(
				'error' => $save_response->get_error_message(),
			)
		);
	}

	wp_send_json_success(
		array(
			'message'     => __( 'Site overview updated successfully.', 'clearpost-simple-ai-auto-post' ),
			'wizard_data' => $wizard_data,
		)
	);
}
add_action( 'wp_ajax_saiap_update_wizard_data', 'saiap_ajax_update_wizard_data' );

/**
 * Recursively sanitize context fields array
 *
 * @param mixed $value The value to sanitize
 * @return mixed The sanitized value
 */
function saiap_sanitize_context_fields( $value ) {
	if ( is_array( $value ) ) {
		return array_map( 'saiap_sanitize_context_fields', $value );
	}
	return sanitize_text_field( $value );
}

/**
 * Handle permalink structure changes.
 * When the user changes their permalink structure, we need to refresh all permalinks
 * stored in the backend database.
 *
 * @param mixed $old_value The old permalink structure.
 * @param mixed $new_value The new permalink structure.
 */
function saiap_on_permalink_structure_change( $old_value, $new_value ) {
	// Only process if the value actually changed.
	if ( $old_value === $new_value ) {
		return;
	}

	// Need either a license key or an active trial.
	$license_key = get_option( 'saiap_license_key' );
	$has_trial   = function_exists( 'saiap_is_trial_active' ) && saiap_is_trial_active();

	if ( empty( $license_key ) && ! $has_trial ) {
		return;
	}

	$domain = saiap_get_server_host();

	// Call the premium service to refresh permalinks.
	$refresh_url = SAIAP_PREMIUM_API_URL . '/api/sync/refresh-permalinks';

	$request_body = array(
		'domain'              => $domain,
		'permalink_structure' => $new_value,
	);
	if ( ! empty( $license_key ) ) {
		$request_body['license_key'] = $license_key;
	}

	// Fire async request (don't wait for response).
	wp_remote_post(
		$refresh_url,
		array(
			'method'    => 'POST',
			'headers'   => array( 'Content-Type' => 'application/json' ),
			'body'      => wp_json_encode( $request_body ),
			'timeout'   => 1,
			'blocking'  => false,
		)
	);
}
add_action( 'update_option_permalink_structure', 'saiap_on_permalink_structure_change', 10, 2 );

