<?php
/**
 * AJAX handlers for MindWebConcierge.
 *
 * @package MindWebConcierge
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}


add_action( 'wp_ajax_mindweco_index_all_items', 'mindweco_plugin_index_items' );

function mindweco_plugin_index_items() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	global $wpdb;

	$options       = get_option( 'mindweco_plugin_options', array() );
	$options       = is_array( $options ) ? $options : array();
	$base_url      = sanitize_text_field( $options['base_url'] ?? '' );
	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );
	$chunk_size    = get_option( 'mindweco_chunk_size' );
	$chunk_overlap = get_option( 'mindweco_chunk_overlap' );
	$header_levels = get_option( 'mindweco_header_levels' );

	$category = get_option( 'mindweco_plugin_category', null );
	if ( ! $category || empty( $category['id'] ) ) {
		wp_send_json_error( 'Category not set. Please login first.' );
		return;
	}

	$category_id = absint( $category['id'] );

	if ( empty( $base_url ) || empty( $token ) || ! $category_id ) {
		wp_send_json_error( 'Missing required configuration: Base URL, Token, or Category ID' );
		return;
	}

	$fresh_token = mindweco_plugin_refresh_token();
	if ( $fresh_token ) {
		$token = $fresh_token;
	}

	$wpdb->query(
		$wpdb->prepare(
			"UPDATE `{$wpdb->prefix}mindweco_indexed_items`
			SET status = %s, updated_at = NOW()
			WHERE status = %s
			AND created_at < DATE_SUB(NOW(), INTERVAL 5 MINUTE)",
			'failed',
			'in_progress'
		)
	);

	$all_posts = get_posts(
		array(
			'numberposts'      => -1,
			'post_type'        => array( 'post', 'page' ),
			'post_status'      => 'publish',
			'suppress_filters' => false,
		)
	);

	$selected_ids = get_option( 'mindweco_selected_ids', null );

	// Cast all saved IDs to integers to ensure strict comparison works
	if ( ! is_null( $selected_ids ) ) {
		$selected_ids = array_map( 'intval', (array) $selected_ids );
	}

	$all_posts = array_filter(
		$all_posts,
		function ( $post ) use ( $selected_ids ) {
			if ( get_post_status( $post->ID ) !== 'publish' ) {
				return false;
			}
			if ( is_null( $selected_ids ) ) {
				return true;
			}
			return in_array( (int) $post->ID, $selected_ids, true );
		}
	);

	if ( empty( $all_posts ) ) {
		wp_send_json_error( 'No posts matched the selection. Please go to Index Selection tab and save your selection first.' );
		return;
	}

	$results = array();

	foreach ( $all_posts as $post ) {
		$existing = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT item_id, category_id, status FROM `{$wpdb->prefix}mindweco_indexed_items` WHERE post_id = %d LIMIT 1",
				$post->ID
			)
		);

		$author      = get_userdata( $post->post_author );
		$author_name = $author ? sanitize_text_field( $author->display_name ) : 'Unknown';

		if ( $existing && 'indexed' === $existing->status ) {
			$results[] = array(
				'post_id'     => $post->ID,
				'item_id'     => $existing->item_id,
				'category_id' => $category_id,
				'status'      => 'already_indexed',
				'url'         => get_permalink( $post->ID ),
				'title'       => $post->post_title,
				'post_name'   => $post->post_name,
				'author'      => $author_name,
			);
			continue;
		}

		if ( $existing && 'in_progress' === $existing->status ) {
			$results[] = array(
				'post_id'     => $post->ID,
				'item_id'     => null,
				'category_id' => $category_id,
				'status'      => 'in_progress_skip',
				'url'         => get_permalink( $post->ID ),
				'title'       => $post->post_title,
				'post_name'   => $post->post_name,
				'author'      => $author_name,
			);
			continue;
		}

		$wpdb->query(
			$wpdb->prepare(
				"INSERT INTO `{$wpdb->prefix}mindweco_indexed_items`
					(post_id, item_id, category_id, status, created_at, updated_at)
				VALUES (%d, %s, %d, 'in_progress', %s, %s)
				ON DUPLICATE KEY UPDATE
					status     = 'in_progress',
					updated_at = VALUES(updated_at)",
				$post->ID,
				'',
				$category_id,
				current_time( 'mysql' ),
				current_time( 'mysql' )
			)
		);

		$rest_url = rest_url( 'wp/v2/' . $post->post_type . 's/' . $post->ID );
		$response = wp_remote_get( $rest_url, array( 'timeout' => 15 ) );

		if ( is_wp_error( $response ) ) {
			$wp_json = array();
		} else {
			$wp_json = json_decode( wp_remote_retrieve_body( $response ), true );
		}

		$post_categories = wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) );
		$post_tags       = wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) );
		$meta            = array(
			'categories' => $post_categories,
			'tags'       => $post_tags,
		);
		$local_item_id   = '';

		$api_response = mindweco_plugin_api_index_items(
			$base_url,
			$token,
			$category_id,
			$chunk_size,
			$chunk_overlap,
			get_permalink( $post->ID ),
			$wp_json,
			$header_levels,
			$meta,
			$local_item_id
		);

		if ( isset( $api_response['error'] ) ) {
			$wpdb->query(
				$wpdb->prepare(
					"UPDATE `{$wpdb->prefix}mindweco_indexed_items` SET status = 'failed', updated_at = %s WHERE post_id = %d",
					current_time( 'mysql' ),
					$post->ID
				)
			);

			$results[] = array(
				'post_id'     => $post->ID,
				'item_id'     => null,
				'category_id' => $category_id,
				'status'      => 'failed',
				'error'       => sanitize_text_field( $api_response['error'] ),
				'url'         => get_permalink( $post->ID ),
				'title'       => $post->post_title,
				'post_name'   => $post->post_name,
				'author'      => $author_name,
			);
			continue;
		}

		$new_item_id = $api_response['item_id'] ?? null;

		if ( empty( $new_item_id ) ) {
			$wpdb->query(
				$wpdb->prepare(
					"UPDATE `{$wpdb->prefix}mindweco_indexed_items` SET status = 'failed', updated_at = %s WHERE post_id = %d",
					current_time( 'mysql' ),
					$post->ID
				)
			);

			$results[] = array(
				'post_id'     => $post->ID,
				'item_id'     => null,
				'category_id' => $category_id,
				'status'      => 'failed',
				'error'       => 'No item_id returned from API',
				'url'         => get_permalink( $post->ID ),
				'title'       => $post->post_title,
				'post_name'   => $post->post_name,
				'author'      => $author_name,
			);
			continue;
		}

		$updated = $wpdb->query(
			$wpdb->prepare(
				"UPDATE `{$wpdb->prefix}mindweco_indexed_items`
				SET item_id = %s, category_id = %d, status = 'indexed', updated_at = %s
				WHERE post_id = %d",
				$new_item_id,
				$category_id,
				current_time( 'mysql' ),
				$post->ID
			)
		);

		if ( false === $updated ) {
			$results[] = array(
				'post_id'     => $post->ID,
				'item_id'     => $new_item_id,
				'category_id' => $category_id,
				'status'      => 'failed',
				'error'       => 'Database update failed',
				'url'         => get_permalink( $post->ID ),
				'title'       => $post->post_title,
				'post_name'   => $post->post_name,
				'author'      => $author_name,
			);
			continue;
		}

		$results[] = array(
			'post_id'     => $post->ID,
			'item_id'     => $new_item_id,
			'category_id' => $category_id,
			'status'      => 'success',
			'url'         => get_permalink( $post->ID ),
			'title'       => $post->post_title,
			'post_name'   => $post->post_name,
			'author'      => $author_name,
		);
	}

	wp_send_json_success( $results );
}

add_action( 'wp_ajax_mindweco_delete_indexed_item', 'mindweco_plugin_delete_indexed_item' );


function mindweco_plugin_delete_indexed_item() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	global $wpdb;

	$item_id     = sanitize_text_field( wp_unslash( $_POST['item_id'] ?? '' ) );
	$category_id = absint( $_POST['category_id'] ?? 0 );

	if ( empty( $item_id ) || ! $category_id ) {
		wp_send_json_error( array( 'message' => 'Invalid item_id or category_id' ) );
		return;
	}

	$table        = $wpdb->prefix . 'mindweco_indexed_items';
	$count_before = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is derived from $wpdb->prefix, not user input.

	$options  = get_option( 'mindweco_plugin_options', array() );
	$options  = is_array( $options ) ? $options : array();
	$base_url = sanitize_text_field( $options['base_url'] ?? '' );
	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );

	if ( empty( $base_url ) || empty( $token ) ) {
		wp_send_json_error( array( 'message' => 'Missing Base URL or Access Token' ) );
		return;
	}

	$api_response = mindweco_plugin_api_delete_indexed_items( $base_url, $token, $category_id, $item_id );

	if ( isset( $api_response['http_code'] ) && 401 === (int) $api_response['http_code'] ) {
		$new_token = mindweco_plugin_refresh_token();
		if ( $new_token ) {
			$api_response = mindweco_plugin_api_delete_indexed_items( $base_url, $new_token, $category_id, $item_id );
		}
	}

	$deleted = $wpdb->delete(
		$table,
		array(
			'item_id'     => $item_id,
			'category_id' => $category_id,
		),
		array( '%s', '%d' )
	);

	$count_after = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is derived from $wpdb->prefix, not user input.

	if ( false === $deleted ) {
		wp_send_json_error( array( 'message' => 'Database delete failed' ) );
		return;
	}

	wp_send_json_success(
		array(
			'message'      => $deleted > 0 ? 'Item unindexed successfully' : 'Item removed from API but was not in local database',
			'deleted_rows' => $deleted,
			'count_before' => $count_before,
			'count_after'  => $count_after,
		)
	);
}

add_action( 'wp_ajax_mindweco_get_stats', 'mindweco_plugin_get_stats' );

function mindweco_get_indexing_dashboard_stats() {
	global $wpdb;

	$selected_ids        = get_option( 'mindweco_selected_ids', null );
	$has_saved_selection = ! is_null( $selected_ids );

	if ( $has_saved_selection ) {
		$selected_ids = array_values( array_unique( array_filter( array_map( 'absint', (array) $selected_ids ) ) ) );
		$total        = count( $selected_ids );
	} else {
		$total_posts = (int) wp_count_posts( 'post' )->publish;
		$total_pages = (int) wp_count_posts( 'page' )->publish;
		$total       = $total_posts + $total_pages;
	}

	$table_name   = $wpdb->prefix . 'mindweco_indexed_items';
	$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );
	$indexed_count = 0;

	if ( $table_exists && ( ! $has_saved_selection || ! empty( $selected_ids ) ) ) {
		$sql    = "SELECT COUNT(DISTINCT i.post_id)
			FROM `{$table_name}` i
			INNER JOIN `{$wpdb->posts}` p ON p.ID = i.post_id
			WHERE i.status = %s
			AND p.post_type IN ('post', 'page')
			AND p.post_status = %s";
		$params = array( 'indexed', 'publish' );

		if ( $has_saved_selection ) {
			$placeholders = implode( ',', array_fill( 0, count( $selected_ids ), '%d' ) );
			$sql         .= " AND i.post_id IN ({$placeholders})";
			$params       = array_merge( $params, $selected_ids );
		}

		$indexed_count = (int) $wpdb->get_var( $wpdb->prepare( $sql, $params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
	}

	$to_index = max( 0, $total - $indexed_count );
	$progress = $total > 0 ? min( 100, max( 0, round( ( $indexed_count / $total ) * 100 ) ) ) : 0;

	return array(
		'total'    => $total,
		'indexed'  => $indexed_count,
		'to_index' => $to_index,
		'progress' => $progress,
	);
}

function mindweco_plugin_get_stats() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	global $wpdb;
	$wpdb->flush();

	wp_send_json_success(
		mindweco_get_indexing_dashboard_stats()
	);
}

add_action( 'wp_ajax_mindweco_get_indexed_table', 'mindweco_plugin_get_indexed_table' );

function mindweco_plugin_get_indexed_table() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	global $wpdb;

	$selected_ids        = get_option( 'mindweco_selected_ids', null );
	$has_saved_selection = ! is_null( $selected_ids );
	$selected_ids        = $has_saved_selection
		? array_values( array_unique( array_filter( array_map( 'absint', (array) $selected_ids ) ) ) )
		: array();

	$results = array();

	if ( ! $has_saved_selection || ! empty( $selected_ids ) ) {
		$sql = "SELECT i.id, i.item_id, i.post_id, i.category_id, i.status,
			p.post_title, p.post_name, p.post_status, p.post_author,
			u.display_name
		FROM `{$wpdb->prefix}mindweco_indexed_items` i
		JOIN `{$wpdb->prefix}posts` p ON i.post_id = p.ID
		JOIN `{$wpdb->prefix}users` u ON p.post_author = u.ID
		WHERE i.status = %s
		AND p.post_status = %s";

		$params = array( 'indexed', 'publish' );

		if ( $has_saved_selection ) {
			$placeholders = implode( ',', array_fill( 0, count( $selected_ids ), '%d' ) );
			$sql         .= " AND i.post_id IN ({$placeholders})";
			$params       = array_merge( $params, $selected_ids );
		}

		$sql .= ' ORDER BY i.id ASC';

		$results = $wpdb->get_results( $wpdb->prepare( $sql, $params ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
	}

	$html = '';
	if ( $results ) {
		foreach ( $results as $result ) {
			$html .= '<tr>
				<td class="text-danger">' . esc_html( $result->id ) . '</td>
				<td>' . esc_html( $result->item_id ) . '</td>
				<td>' . esc_html( $result->post_id ) . '</td>
				<td>' . esc_html( $result->category_id ) . '</td>
				<td>' . esc_html( $result->display_name ) . '</td>
				<td>' . esc_html( $result->post_title ) . '</td>
				<td>' . esc_html( $result->post_name ) . '</td>
				<td>' . esc_html( $result->post_status ) . '</td>
				<td>
					<button class="button button-small button-link-delete unindex-item"
						data-item-id="' . esc_attr( $result->item_id ) . '"
						data-category-id="' . esc_attr( $result->category_id ) . '">
						<span class="dashicons dashicons-trash"></span> UnIndex
					</button>
				</td>
			</tr>';
		}
	}

	wp_send_json_success( $html );
}

add_action( 'wp_ajax_mindweco_unindex_all_items', 'mindweco_plugin_unindex_all_items' );

function mindweco_plugin_unindex_all_items() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	global $wpdb;

	$options  = get_option( 'mindweco_plugin_options', array() );
	$options  = is_array( $options ) ? $options : array();
	$base_url = sanitize_text_field( $options['base_url'] ?? '' );

	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );

	$fresh_token = mindweco_plugin_refresh_token();
	if ( $fresh_token ) {
		$token = $fresh_token;
	}

	$table     = $wpdb->prefix . 'mindweco_indexed_items';
	$all_items = $wpdb->get_results(
		$wpdb->prepare( "SELECT item_id, category_id FROM `{$table}` WHERE status = %s", 'indexed' ) // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	);

	$remote_warning = null;

	if ( ! $base_url || ! $token ) {
		$remote_warning = 'API items may not have been deleted remotely. Missing Base URL or Access Token.';
	} elseif ( $all_items ) {
		foreach ( $all_items as $item ) {
			mindweco_plugin_api_delete_indexed_items( $base_url, $token, $item->category_id, $item->item_id );
		}
	}

	// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- TRUNCATE does not support placeholders.
	$deleted = $wpdb->query( "TRUNCATE TABLE `{$table}`" );

	if ( false !== $deleted ) {
		$response = array( 'message' => 'All indexed items have been deleted.' );
		if ( $remote_warning ) {
			$response['warning'] = $remote_warning;
		}
		wp_send_json_success( $response );
	} else {
		wp_send_json_error( array( 'message' => 'Failed to delete items from database.' ) );
	}
}

add_action( 'wp_ajax_mindweco_refresh_access_token', 'mindweco_handle_refresh_token' );

function mindweco_handle_refresh_token() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	$new_token = mindweco_plugin_refresh_token();

	if ( $new_token ) {
		wp_send_json_success( array( 'message' => 'Token refreshed successfully' ) );
	} else {
		wp_send_json_error( 'Failed to refresh token. Please check your credentials.' );
	}
}

add_action( 'wp_ajax_mindweco_check_indexed_items', 'mindweco_check_indexed_items' );
add_action( 'wp_ajax_nopriv_mindweco_check_indexed_items', 'mindweco_check_indexed_items' );

function mindweco_check_indexed_items() {
	check_ajax_referer( 'mindweco_frontend_nonce', 'nonce' );

	global $wpdb;

	$table_name   = $wpdb->prefix . 'mindweco_indexed_items';
	$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );

	if ( $table_exists !== $table_name ) {
		wp_send_json_error( array( 'message' => 'Indexed items table does not exist.' ) );
		return;
	}

	$count = (int) $wpdb->get_var(
		$wpdb->prepare( "SELECT COUNT(*) FROM `{$table_name}` WHERE status = %s", 'indexed' ) // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	);

	wp_send_json_success(
		array(
			'has_items' => ( $count > 0 ),
			'count'     => $count,
		)
	);
}

add_action( 'wp_ajax_mindweco_check_indexed_products', 'mindweco_check_indexed_products' );
add_action( 'wp_ajax_nopriv_mindweco_check_indexed_products', 'mindweco_check_indexed_products' );

function mindweco_check_indexed_products() {
	check_ajax_referer( 'mindweco_product_catalog_nonce', 'nonce' );

	global $wpdb;

	$table_name   = $wpdb->prefix . 'mindweco_indexed_products';
	$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );

	if ( $table_exists !== $table_name ) {
		wp_send_json_success( array( 'has_products' => false, 'count' => 0 ) );
		return;
	}
	
	$count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table_name}`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared

	wp_send_json_success(
		array(
			'has_products' => ( $count > 0 ),
			'count'        => $count,
		)
	);
}

add_action( 'wp_ajax_mindweco_create_attach_llm_config_to_indexing', 'mindweco_create_attach_llm_config_to_indexing' );

function mindweco_create_attach_llm_config_to_indexing() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	$name         = sanitize_text_field( wp_unslash( $_POST['name'] ?? '' ) );
	$llm_base_url = sanitize_text_field( wp_unslash( $_POST['llm_base_url'] ?? '' ) );

	if ( ! empty( $llm_base_url ) && ! filter_var( $llm_base_url, FILTER_VALIDATE_URL ) ) {
		wp_send_json_error( array( 'message' => 'Invalid LLM Base URL format.' ) );
		return;
	}

	$model_name = sanitize_text_field( wp_unslash( $_POST['model_name'] ?? '' ) );
	$provider   = sanitize_text_field( wp_unslash( $_POST['provider'] ?? '' ) );
	$api_key    = sanitize_textarea_field( wp_unslash( $_POST['api_key'] ?? '' ) );

	$missing = array();
	if ( empty( $name ) )         $missing[] = 'name';
	if ( empty( $llm_base_url ) ) $missing[] = 'llm_base_url';
	if ( empty( $model_name ) )   $missing[] = 'model_name';
	if ( empty( $provider ) )     $missing[] = 'provider';
	if ( empty( $api_key ) )      $missing[] = 'api_key';

	if ( ! empty( $missing ) ) {
		wp_send_json_error( array( 'message' => 'All fields are required. Missing: ' . implode( ', ', $missing ) ) );
		return;
	}

	$mindweco_options = get_option( 'mindweco_plugin_options', array() );
	$mindweco_options = is_array( $mindweco_options ) ? $mindweco_options : array();
	$base_url        = sanitize_text_field( $mindweco_options['base_url'] ?? '' );
	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );

	$indexing_options = get_option( 'mindweco_plugin_indexing', array() );
	if ( is_string( $indexing_options ) ) {
		$indexing_options = maybe_unserialize( $indexing_options );
	}
	$indexing_options = is_array( $indexing_options ) ? $indexing_options : array();
	$indexing_id      = $indexing_options['id'] ?? null;

	$config_missing = array();
	if ( empty( $base_url ) )    $config_missing[] = 'base_url';
	if ( empty( $token ) )       $config_missing[] = 'token';
	if ( empty( $indexing_id ) ) $config_missing[] = 'indexing_id';

	if ( ! empty( $config_missing ) ) {
		wp_send_json_error( array( 'message' => 'Missing configuration: ' . implode( ', ', $config_missing ) . '. Please ensure you are logged in and indexing is set up.' ) );
		return;
	}

	$result = mindweco_plugin_create_attach_llm_to_config(
		$base_url,
		$token,
		$name,
		$llm_base_url,
		$model_name,
		$provider,
		$api_key,
		$indexing_id
	);

	if ( isset( $result['error'] ) ) {
		wp_send_json_error( array( 'message' => 'API Error: ' . sanitize_text_field( $result['error'] ) ) );
		return;
	}

	if ( empty( $result ) ) {
		wp_send_json_error( array( 'message' => 'API returned an empty response.' ) );
		return;
	}

	update_option( 'mindweco_api_llm_name', $name );
	update_option( 'mindweco_api_base_url_llm', $llm_base_url );
	update_option( 'mindweco_api_model_name', $model_name );
	update_option( 'mindweco_api_provider', $provider );

	update_option( 'mindweco_api_key', mindweco_encrypt_api_key( $api_key ) );

	$llm_config_id = $result['indexing']['llm_config_id']
		?? $result['indexing']['llm_config']['id']
		?? null;

	if ( $llm_config_id ) {
		update_option( 'mindweco_llm_config_id', $llm_config_id );

		$indexing_options                  = get_option( 'mindweco_plugin_indexing', array() );
		if ( is_string( $indexing_options ) ) {
			$indexing_options = maybe_unserialize( $indexing_options );
		}
		$indexing_options                  = is_array( $indexing_options ) ? $indexing_options : array();
		$indexing_options['llm_config_id'] = $llm_config_id;
		update_option( 'mindweco_plugin_indexing', $indexing_options );
	}

	wp_send_json_success(
		array(
			'message' => 'LLM Configuration successfully created and attached!',
			'data'    => $result,
		)
	);
}

add_action( 'wp_ajax_mindweco_update_llm_config', 'mindweco_update_llm_config_ajax' );

function mindweco_update_llm_config_ajax() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	$name         = sanitize_text_field( wp_unslash( $_POST['name'] ?? '' ) );
	$llm_base_url = sanitize_text_field( wp_unslash( $_POST['llm_base_url'] ?? '' ) );

	if ( ! empty( $llm_base_url ) && ! filter_var( $llm_base_url, FILTER_VALIDATE_URL ) ) {
		wp_send_json_error( array( 'message' => 'Invalid LLM Base URL format.' ) );
		return;
	}

	$model_name = sanitize_text_field( wp_unslash( $_POST['model_name'] ?? '' ) );
	$provider   = sanitize_text_field( wp_unslash( $_POST['provider'] ?? '' ) );
	$api_key    = sanitize_textarea_field( wp_unslash( $_POST['api_key'] ?? '' ) );

	$missing = array();
	if ( empty( $name ) )         $missing[] = 'name';
	if ( empty( $llm_base_url ) ) $missing[] = 'llm_base_url';
	if ( empty( $model_name ) )   $missing[] = 'model_name';
	if ( empty( $provider ) )     $missing[] = 'provider';
	if ( empty( $api_key ) )      $missing[] = 'api_key';

	if ( ! empty( $missing ) ) {
		wp_send_json_error( array( 'message' => 'All fields are required. Missing: ' . implode( ', ', $missing ) ) );
		return;
	}

	$mindweco_options  = get_option( 'mindweco_plugin_options', array() );
	$mindweco_options  = is_array( $mindweco_options ) ? $mindweco_options : array();
	$base_url         = sanitize_text_field( $mindweco_options['base_url'] ?? '' );
	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );
	$llm_config_id    = get_option( 'mindweco_llm_config_id' );
	$indexing_options = get_option( 'mindweco_plugin_indexing', array() );
	$indexing_options = is_array( $indexing_options ) ? $indexing_options : array();
	$user_id          = $indexing_options['user_id'] ?? null;

	if ( empty( $base_url ) || empty( $token ) || empty( $llm_config_id ) || empty( $user_id ) ) {
		wp_send_json_error( array( 'message' => 'Missing configuration or LLM not created yet.' ) );
		return;
	}

	$result = mindweco_plugin_update_llm_config(
		$base_url,
		$token,
		$llm_config_id,
		$name,
		$api_key,
		$llm_base_url,
		$model_name,
		$user_id
	);

	if ( isset( $result['error'] ) ) {
		wp_send_json_error( array( 'message' => 'API Error: ' . sanitize_text_field( $result['error'] ) ) );
		return;
	}

	if ( empty( $result ) ) {
		wp_send_json_error( array( 'message' => 'API returned empty response' ) );
		return;
	}

	update_option( 'mindweco_api_llm_name', $name );
	update_option( 'mindweco_api_base_url_llm', $llm_base_url );
	update_option( 'mindweco_api_model_name', $model_name );
	update_option( 'mindweco_api_provider', $provider );
	update_option( 'mindweco_api_key', mindweco_encrypt_api_key( $api_key ) );

	$indexing_options['llm_config_id'] = $llm_config_id;
	update_option( 'mindweco_plugin_indexing', $indexing_options );
	update_option( 'mindweco_llm_config_id', $llm_config_id );

	wp_send_json_success(
		array(
			'message' => 'LLM configuration successfully updated!',
			'data'    => $result,
		)
	);
}

add_action( 'wp_ajax_mindweco_delete_llm_config_ajax', 'mindweco_delete_llm_config_ajax' );

function mindweco_delete_llm_config_ajax() {
	check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

	if ( ! current_user_can( 'manage_options' ) ) {
		wp_send_json_error( 'Unauthorized' );
		return;
	}

	$mindweco_options = get_option( 'mindweco_plugin_options', array() );
	$mindweco_options = is_array( $mindweco_options ) ? $mindweco_options : array();
	$base_url        = sanitize_text_field( $mindweco_options['base_url'] ?? '' );
	$token = mindweco_decrypt_api_key( get_option( 'mindweco_plugin_access_token', '' ) );
	$llm_config_id   = get_option( 'mindweco_llm_config_id' );

	if ( empty( $base_url ) || empty( $token ) || empty( $llm_config_id ) ) {
		wp_send_json_error( array( 'message' => 'Missing configuration or LLM config ID.' ) );
		return;
	}

	$result = mindweco_plugin_delete_llm_config( $base_url, $token, $llm_config_id );

	if ( isset( $result['error'] ) ) {
		wp_send_json_error( array( 'message' => 'API Error: ' . sanitize_text_field( $result['error'] ) ) );
		return;
	}

	delete_option( 'mindweco_api_llm_name' );
	delete_option( 'mindweco_api_base_url_llm' );
	delete_option( 'mindweco_api_model_name' );
	delete_option( 'mindweco_api_provider' );
	delete_option( 'mindweco_api_key' );
	delete_option( 'mindweco_llm_config_id' );

	wp_send_json_success( array( 'message' => 'LLM configuration disconnected successfully!' ) );
}

add_action( 'admin_enqueue_scripts', 'mindweco_enqueue_llm_script' );

function mindweco_enqueue_llm_script( $hook ) {
    if ( strpos( $hook, 'mind-web_page_mind-web-model-usage' ) === false ) {
        return;
    }

    wp_enqueue_script(
        'mindweco-bootstrap-js',
        plugin_dir_url( __DIR__ ) . 'assets/js/bootstrap.bundle.min.js',
        array( 'jquery' ),
        '5.3.8',
        true
    );

    if ( ! wp_script_is( 'mindweco-modal', 'enqueued' ) ) {
        wp_enqueue_script(
            'mindweco-modal',
            plugin_dir_url( __DIR__ ) . 'assets/js/components/Modal.js',
            array( 'jquery' ),
            '1.1.2',
            true
        );
    }

    wp_enqueue_script(
        'mindweco-llm-config',
        plugin_dir_url( __DIR__ ) . 'assets/js/mindweco_create_attach_llm_config.js',
        array( 'jquery', 'mindweco-modal' ),
        '2.0.0',
        true
    );

    $llm_config_id = get_option( 'mindweco_llm_config_id', '' );

    wp_localize_script(
        'mindweco-llm-config',
        'mindwecoLLMConfig',
        array(
            'ajax_url'      => admin_url( 'admin-ajax.php' ),
            'nonce'         => wp_create_nonce( 'mindweco_login_nonce' ),
            'llm_config_id' => $llm_config_id,
            'llm_name'      => get_option( 'mindweco_api_llm_name', '' ),
            'llm_base_url'  => get_option( 'mindweco_api_base_url_llm', '' ),
            'model_name'    => get_option( 'mindweco_api_model_name', '' ),
            'provider'      => get_option( 'mindweco_api_provider', '' ),
        )
    );
}
/**
 * Encrypt an API key before storing it in wp_options.
 *
 * @param  string $api_key Plain-text API key.
 * @return string          Encrypted value safe to store.
 */
function mindweco_encrypt_api_key( $api_key ) {
	if ( ! function_exists( 'openssl_encrypt' ) ) {
		return base64_encode( $api_key ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
	}

	$secret = substr( hash( 'sha256', AUTH_KEY . SECURE_AUTH_KEY ), 0, 32 );
	$iv     = openssl_random_pseudo_bytes( 16 );
	$enc    = openssl_encrypt( $api_key, 'AES-256-CBC', $secret, 0, $iv );

	return base64_encode( $iv . $enc ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
}

/**
 * Decrypt an API key retrieved from wp_options.
 *
 * @param  string $stored Encrypted value from the database.
 * @return string         Plain-text API key, or empty string on failure.
 */
function mindweco_decrypt_api_key( $stored ) {
	if ( ! function_exists( 'openssl_decrypt' ) ) {
		return base64_decode( $stored ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
	}

	$decoded = base64_decode( $stored ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode

	if ( strlen( $decoded ) <= 16 ) {
		return '';
	}

	$iv     = substr( $decoded, 0, 16 );
	$enc    = substr( $decoded, 16 );
	$secret = substr( hash( 'sha256', AUTH_KEY . SECURE_AUTH_KEY ), 0, 32 );
	$result = openssl_decrypt( $enc, 'AES-256-CBC', $secret, 0, $iv );

	return $result ? $result : '';
}

add_action( 'wp_ajax_mindweco_get_selection', 'mindweco_get_selection' );

function mindweco_get_selection() {
    check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
        return;
    }

    $all_posts = get_posts( array(
        'numberposts' => -1,
        'post_type'   => array( 'post', 'page' ),
        'post_status' => 'publish',
    ) );

    $saved_ids = get_option( 'mindweco_selected_ids', null );
    $is_first_time = is_null( $saved_ids );
    $saved_ids     = $is_first_time ? array() : (array) $saved_ids;

    $posts_data = array_map( function( $post ) use ( $saved_ids, $is_first_time ) {
        return array(
            'id'       => $post->ID,
            'title'    => $post->post_title,
            'slug'     => $post->post_name,
            'type'     => $post->post_type,
            'selected' => $is_first_time ? true : in_array( $post->ID, $saved_ids, true ),
        );
    }, $all_posts );

    wp_send_json_success( array(
        'posts'         => $posts_data,
        'is_first_time' => $is_first_time,
    ) );
}

add_action( 'wp_ajax_mindweco_save_selection', 'mindweco_save_selection' );

function mindweco_save_selection() {
    check_ajax_referer( 'mindweco_login_nonce', 'nonce' );

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Unauthorized' );
        return;
    }

    $raw_ids      = isset( $_POST['selected_ids'] ) ? (array) $_POST['selected_ids'] : array();
    $selected_ids = array_values( array_filter( array_map( 'absint', $raw_ids ) ) );

    update_option( 'mindweco_selected_ids', $selected_ids );

    wp_send_json_success( array(
        'message'      => 'Selection saved successfully.',
        'selected_ids' => $selected_ids,
        'count'        => count( $selected_ids ),
    ) );
}

add_action('wp_ajax_mindweco_regenerate_welcome', 'mindweco_regenerate_welcome');

function mindweco_regenerate_welcome() {

	check_ajax_referer('mindweco_login_nonce', 'nonce');

	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized');
		return;
	}

	$options  = get_option('mindweco_plugin_options', array());
	$options  = is_array($options) ? $options : array();

	$base_url = sanitize_text_field($options['base_url'] ?? '');

	$token_raw = get_option('mindweco_plugin_access_token', '');
	if (is_array($token_raw)) {
		$token_raw = reset($token_raw);
	}

	$token = mindweco_decrypt_api_key($token_raw);

	$category = get_option('mindweco_plugin_category', null);

	if (!$category || empty($category['id'])) {
		wp_send_json_error('Category not set. Please login first.');
		return;
	}

	$category_id = absint($category['id']);
	$sitemap_xml = mindweco_get_sitemap_xml();

	$language = mindweco_get_locale_code();

	if (empty($base_url) || empty($token) || !$category_id) {
		wp_send_json_error('Missing required configuration');
		return;
	}

	$fresh_token = mindweco_plugin_refresh_token();
	if ($fresh_token) {
		$token = $fresh_token;
	}

	$response = mindweco_plugin_regenerate_welcome_message(
		$base_url,
		$token,
		$category_id,
		$sitemap_xml,
		$language
	);

	if (is_array($response) && !empty($response['welcome_text'])) {

		update_option(
			'mindweco_summary',
			sanitize_textarea_field($response['welcome_text'])
		);

		wp_send_json_success([
			'welcome_text' => $response['welcome_text']
		]);
		return;
	}

	wp_send_json_error($response);
}

add_action('wp_ajax_mindweco_delete_service', 'mindweco_delete_service');

function mindweco_delete_service() {

	check_ajax_referer('mindweco_login_nonce', 'nonce');

	if (!current_user_can('manage_options')) {
		wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized.', 'mind-web-concierge' ) ) );
	}

	$row_id   = isset( $_POST['row_id'] ) ? absint( wp_unslash( $_POST['row_id'] ) ) : -1;
	$services = get_option( 'mindweco_service_links', array() );

	if ( $row_id < 0 || ! array_key_exists( $row_id, $services ) ) {
		wp_send_json_error( array( 'message' => esc_html__( 'Invalid service row.', 'mind-web-concierge' ) ) );
	}

	unset( $services[ $row_id ] );
	$services = array_values( $services );

	update_option( 'mindweco_service_links', $services );
	update_option( 'mindweco_services_count', count( $services ) );
	update_option( 'mindweco_calendly_url', ! empty( $services[0]['url'] ) ? $services[0]['url'] : '' );

	wp_send_json_success( array( 'message' => esc_html__( 'Service deleted successfully.', 'mind-web-concierge' ) ) );

}
