<?php

/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://statenweb.com
 * @since      1.0.0
 *
 * @package    Facet_Wp_Remote_Data
 * @subpackage Facet_Wp_Remote_Data/admin
 */

/**
 * The admin-specific functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the admin-specific stylesheet and JavaScript.
 *
 * @package    Facet_Wp_Remote_Data
 * @subpackage Facet_Wp_Remote_Data/admin
 * @author     Marko Bader <marko@statenweb.com>
 */
class Facet_Wp_Remote_Data_Admin {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $plugin_name    The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $version    The current version of this plugin.
	 */
	private $version;

    public const AJAX_INDEX_TABLE_SYNC_RUNNING_OPTION_KEY = 'sw_facet_ajax_index_table_sync_running';

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $plugin_name       The name of this plugin.
	 * @param      string    $version    The version of this plugin.
	 */
	public function __construct( $plugin_name, $version ) {

		$this->plugin_name = $plugin_name;
		$this->version = $version;

	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles() {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Facet_Wp_Remote_Data_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Facet_Wp_Remote_Data_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */

		wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/facet-wp-remote-data-admin.css', array(), $this->version, 'all' );

	}

	/**
	 * Register the JavaScript for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Facet_Wp_Remote_Data_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Facet_Wp_Remote_Data_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */

		wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/facet-wp-remote-data-admin.js', array( 'jquery' ), $this->version, false );

		wp_localize_script( $this->plugin_name,
            'swFacetWp',
            [
                'ajax_url' => admin_url( 'admin-ajax.php' ),
                'nonce'    => wp_create_nonce( 'facetwp_sw_facetwp_admin_ajax_nonce' ),
		    ]
        );

	}

	public function add_plugin_admin_menu() {
		add_options_page(
			__( 'FacetWP Remote Site Settings' ),
			__( 'FacetWP Remote Settings' ),
			'manage_options',
			'facetwp-remote-data-settings',
			[ $this, 'display_settings_page' ]
		);
	}

	public function display_settings_page() {
		?>
        <div class="wrap">
            <h1><?php esc_html_e( 'FacetWP Remote Site Settings' ); ?></h1>
            <form method="post" action="options.php">
				<?php
                    settings_fields( 'facetwp_remote_data_settings_group' );
                    do_settings_sections( 'facetwp-remote-data-settings' );
                    submit_button();
				?>
            </form>

            <!-- Sync Button -->
            <p>
                Retrieve and sync FacetWP settings from the remote (main) site.
                <br>
                <strong>Warning:</strong> This will overwrite the current FacetWP settings on this site.
            </p>
            <button id="sync-facetwp-settings" class="button button-primary">
				<?php esc_html_e( 'Sync FacetWP Settings' ); ?>
            </button>

            <p id="sync-message" style="display: none; color: green;"></p>

            <div style="margin-top: 30px;"></div>

            <!-- Clear Cache -->
            <p>
                Clear cache (delete all transients).
                <br>
                <strong>Warning:</strong> This will clear the cached FacetWP data on this site.
            </p>
            <button id="delete-facetwp-cache" class="button button-primary">
		        <?php esc_html_e( 'Clear FacetWP Cache' ); ?>
            </button>

            <p id="delete-message" style="display: none; color: green;"></p>
        </div>
		<?php
	}

	public function register_settings() {
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_remote_site_username' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_remote_site_password' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_remote_site_url' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_site_owner_office_name' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_enable_auto_sync' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_only_show_property_types' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_excluded_property_types' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_default_sort_option' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_latest_listings_within_weeks' );
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_remove_duplicate_addresses' );
		register_setting(
            'facetwp_remote_data_settings_group',
            'facetwp_remote_data_selected_pages',
            [
                'type' => 'array',
                'sanitize_callback' => function( $input ) {
                    return array_map( 'absint', (array) $input );
                }
            ]
        );
		register_setting(
			'facetwp_remote_data_settings_group',
			'facetwp_remote_data_selected_cpts',
			[
				'type' => 'array',
				'sanitize_callback' => function( $input ) {
					return array_map( 'sanitize_text_field', (array) $input );
				}
			]
		);
		register_setting( 'facetwp_remote_data_settings_group', 'facetwp_remote_data_google_api_key' );
		register_setting(
			'facetwp_remote_data_settings_group',
			'facetwp_remote_data_skipped_local_facets',
			[
				'type' => 'array',
			]
		);

		add_settings_section(
			'facetwp_remote_data_settings_section',
			__( 'API Credentials' ),
			null,
			'facetwp-remote-data-settings'
		);

		add_settings_section(
			'facetwp_remote_data_property_type_section',
			__( 'Property Type Filters' ),
			function() {
				echo '<p>';
				echo esc_html__( 'Control which property types are shown in results by default.' );
				echo '<br>';
				echo esc_html__( 'If "Show Only These Property Types" is selected, "Globally Excluded Property Types" will be ignored.' );
				echo '</p>';
			},
			'facetwp-remote-data-settings'
		);

		add_settings_section(
			'facetwp_remote_data_latest_listings_section',
			__( 'Latest Listings Configuration' ),
			null,
			'facetwp-remote-data-settings'
		);

		add_settings_section(
			'facetwp_remote_data_remove_duplicate_addresses_section',
			__( 'Duplicate Addresses Configuration' ),
			null,
			'facetwp-remote-data-settings'
		);

		add_settings_section(
			'facetwp_remote_data_advanced_section',
			__( 'Advanced Configuration' ),
			null,
			'facetwp-remote-data-settings'
		);

		add_settings_field(
			'facetwp_remote_data_remote_site_username',
			__( 'Username' ),
			[$this, 'username_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_remote_site_password',
			__( 'Password' ),
			[$this, 'password_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_remote_site_url',
			__( 'Remote Site URL' ),
			[$this, 'site_url_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_site_owner_office_name',
			__( 'Site Owner Office Name' ),
			[$this, 'office_name_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_enable_auto_sync',
			__( 'Enable Automatic Syncing' ),
			[$this, 'auto_sync_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_only_show_property_types',
			__( 'Show Only These Property Types' ),
			function () {
				$this->render_property_types_checkbox_field(
					'facetwp_remote_data_only_show_property_types',
					'Only show these property types by default. All others will be excluded unless manually selected.'
				);
			},
			'facetwp-remote-data-settings',
			'facetwp_remote_data_property_type_section'
		);

        add_settings_field(
			'facetwp_remote_data_excluded_property_types',
			__( 'Globally Excluded Property Types' ),
	        function () {
		        $this->render_property_types_checkbox_field(
			        'facetwp_remote_data_excluded_property_types',
			        'Exclude properties by default. They will only appear in results if explicitly selected in the filters.'
		        );
	        },
			'facetwp-remote-data-settings',
			'facetwp_remote_data_property_type_section'
		);

		add_settings_field(
			'facetwp_remote_data_default_sort_option',
			__( 'Default Sorting Option' ),
			[$this, 'default_sort_option_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_property_type_section'
		);

		add_settings_field(
			'facetwp_remote_data_latest_listings_within_weeks',
			__( 'Latest Listings Time Frame' ),
			[$this, 'latest_listings_within_weeks_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_latest_listings_section'
		);

		add_settings_field(
			'facetwp_remote_data_remove_duplicate_addresses',
			__( 'Do not show duplicate addresses' ),
			[$this, 'duplicate_addresses_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_remove_duplicate_addresses_section'
		);

		add_settings_field(
			'facetwp_remote_data_selected_pages',
			__( 'Select Pages' ),
			[$this, 'selected_pages_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_advanced_section'
		);

        add_settings_field(
			'facetwp_remote_data_selected_cpts',
			__( 'Select CPTs' ),
			[$this, 'selected_cpts_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_advanced_section'
		);

		add_settings_field(
			'facetwp_remote_data_google_api_key',
			__( 'Google API Key' ),
			[$this, 'google_api_key_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_settings_section'
		);

		add_settings_field(
			'facetwp_remote_data_skipped_local_facets',
			__( 'Facets That Should Not Be Synced' ),
			[$this, 'skipped_local_facets_field_callback'],
			'facetwp-remote-data-settings',
			'facetwp_remote_data_advanced_section'
		);
	}

	public function username_field_callback() {
		$username = get_option( 'facetwp_remote_data_remote_site_username', '' );

		echo '<input type="text" name="facetwp_remote_data_remote_site_username" value="' . esc_attr( $username ) . '" class="regular-text">';
	}

	public function password_field_callback() {
		$password = get_option( 'facetwp_remote_data_remote_site_password', '' );

		echo '<input type="password" name="facetwp_remote_data_remote_site_password" value="' . esc_attr( $password ) . '" class="regular-text">';
	}

	public function site_url_field_callback() {
		$site_url = get_option( 'facetwp_remote_data_remote_site_url', '' );

		echo '<input type="url" name="facetwp_remote_data_remote_site_url" value="' . esc_attr( $site_url ) . '" class="regular-text">';
	}

	public function office_name_field_callback() {
		$office_name = get_option( 'facetwp_remote_data_site_owner_office_name', '' );

		echo '<input type="text" name="facetwp_remote_data_site_owner_office_name" value="' . esc_attr( $office_name ) . '" class="regular-text">';
	}

	public function auto_sync_field_callback() {
		$checked = get_option( 'facetwp_remote_data_enable_auto_sync', false );

		echo '<input type="checkbox" name="facetwp_remote_data_enable_auto_sync" value="1" ' . checked( 1, $checked, false ) . '>';
		echo '<p class="description">When checked, if FacetWP settings on the main site are updated, the settings on this subsite will be automatically updated.</p>';
	}

	public function render_property_types_checkbox_field( $option_name, $description = '' ) {
		$selected = (array) get_option( $option_name, [] );

		$facet_with_choices = ( new Facet_Wp_Remote_Data_Neighborhood_Page )->get_facets_with_choices();

		$property_types_facet = ! empty( $facet_with_choices )
			? array_filter(
				$facet_with_choices,
				fn ( $facet ) => $facet['name'] === 'property_type'
			)
			: [];

		if ( ! empty( $description ) ) {
			echo "<p class='description' style='margin-bottom: 20px;'>{$description}</p>";
		}

		$choices = current( $property_types_facet )['choices'] ?? [];

		foreach ( $choices as $choice ) {
			$value = esc_attr( $choice['value'] );
			$label = esc_html( $choice['label'] );
			$checked = in_array( $value, $selected, true ) ? 'checked' : '';

			echo "<label><input type='checkbox' name='{$option_name}[]' value='{$value}' {$checked}> {$label}</label><br>";
		}
	}

	public function default_sort_option_field_callback() {
		$selected = get_option( 'facetwp_remote_data_default_sort_option', '' );

		$choices = $this->get_sort_facet_choices();

		echo '<p class="description" style="margin-bottom: 20px;">Select the default sorting when no sort option is selected manually.</p>';

		echo '<select name="facetwp_remote_data_default_sort_option">';
		echo '<option value="">— Use default FacetWP behavior —</option>';

		foreach ( $choices as $choice ) {
			$value = esc_attr( $choice['value'] );
			$label = esc_html( $choice['label'] );
			$is_selected = selected( $selected, $value, false );
			echo "<option value='{$value}' {$is_selected}>{$label}</option>";
		}

		echo '</select>';
	}

	public function latest_listings_within_weeks_field_callback() {
		$latest_listings_within_weeks = get_option( 'facetwp_remote_data_latest_listings_within_weeks', '' );

		echo '<p class="description" style="margin-bottom: 20px;">Specify how many weeks back the system should look when showing listings from the site owner office. This helps prioritize newer listings. If not set, 4 weeks will be used.</p>';

		echo '<input type="number" name="facetwp_remote_data_latest_listings_within_weeks" value="' . esc_attr( $latest_listings_within_weeks ) . '" class="regular-text">';
	}

	public function duplicate_addresses_field_callback() {
		$checked = get_option( 'facetwp_remote_data_remove_duplicate_addresses', false );

		echo '<input type="checkbox" name="facetwp_remote_data_remove_duplicate_addresses" value="1" ' . checked( 1, $checked, false ) . '>';
		echo '<p class="description">When enabled, results that share the same address are collapsed into a single listing.</p>';
	}

	public function get_sort_facet_choices() {
		$facet_settings = get_option( 'facetwp_settings' );

		if ( empty( $facet_settings ) ) return [];

		$facet_settings = json_decode( $facet_settings, true );

		$facets = $facet_settings['facets'] ?? [];

		foreach ( $facets as $facet ) {
			if ( $facet['type'] === 'sort' ) {
				$sort_options = $facet['sort_options'] ?? [];

				return array_map( function( $option ) {
					return [
						'value' => $option['name'] ?? '',
						'label' => $option['label'] ?? '',
					];
				}, $sort_options );
			}
		}

		return [];
	}

	public function selected_pages_field_callback() {
		$selected_pages = get_option( 'facetwp_remote_data_selected_pages' );

		if ( ! is_array( $selected_pages ) ) {
			$selected_pages = wp_list_pluck( get_pages(), 'ID' );
		}

		$pages = get_pages();

		if ( empty( $pages ) ) {
			echo '<p>No pages found.</p>';

			return;
		}

		echo '<p class="description" style="margin-bottom: 20px;">If a page is selected, the plugin will use FacetWP data from the main site for that page.</p>';

		echo '<ul>';

		foreach ( $pages as $page ) {
			$checked = in_array( $page->ID, (array) $selected_pages ) ? 'checked' : '';
			echo '<li>';
			echo '<label>';
			echo '<input type="checkbox" name="facetwp_remote_data_selected_pages[]" value="' . esc_attr( $page->ID ) . '" ' . $checked . '> ';
			echo esc_html( $page->post_title );
			echo '</label>';
			echo '</li>';
		}

		echo '</ul>';
	}

    public function selected_cpts_field_callback() {
		$selected_cpts = get_option( 'facetwp_remote_data_selected_cpts' );

		$cpts = get_post_types( ['public' => true, '_builtin' => false] );

		if ( empty( $cpts ) ) {
			echo '<p>No CPTs found.</p>';

			return;
		}

	    echo '<p class="description" style="margin-bottom: 20px;">If a CPT is selected, the plugin will use FacetWP data from the main site for that CPT page.</p>';

		echo '<ul>';

		foreach ( $cpts as $cpt ) {
			$checked = in_array( $cpt, (array) $selected_cpts ) ? 'checked' : '';
			echo '<li>';
			echo '<label>';
			echo '<input type="checkbox" name="facetwp_remote_data_selected_cpts[]" value="' . esc_attr( $cpt ) . '" ' . $checked . '> ';
			echo esc_html( $cpt );
			echo '</label>';
			echo '</li>';
		}

		echo '</ul>';
	}

    public function google_api_key_field_callback() {
	    $google_api_key = get_option( 'facetwp_remote_data_google_api_key', '' );

	    echo '<p class="description" style="margin-bottom: 20px;">Add your Google API key to display a Google Map with the property location on the single property page template.</p>';
	    echo '<input type="password" name="facetwp_remote_data_google_api_key" value="' . esc_attr( $google_api_key ) . '" class="regular-text">';
    }

	public function skipped_local_facets_field_callback() {
		$facets_to_skip_syncing = get_option( 'facetwp_remote_data_skipped_local_facets' );

		$facet_settings = get_option( 'facetwp_settings' );
		$facet_settings_decoded = ! empty( $facet_settings ) ? json_decode( $facet_settings, true ) : [];

		$facets = ! empty( $facet_settings_decoded['facets'] ) ? $facet_settings_decoded['facets'] : [];

		if ( empty( $facets ) ) {
			echo '<p>No facets found. Please sync facets.</p>';

			return;
		}

		echo '<p class="description" style="margin-bottom: 20px;">If a facet is selected, the plugin will skip syncing data from the main site for that facet, allowing you to maintain custom facets locally.</p>';

		echo '<ul>';

		foreach ( $facets as $facet ) {
			$checked = in_array( $facet['name'], (array) $facets_to_skip_syncing ) ? 'checked' : '';
			echo '<li>';
			echo '<label>';
			echo '<input type="checkbox" name="facetwp_remote_data_skipped_local_facets[]" value="' . esc_attr( $facet['name'] ) . '" ' . $checked . '> ';
			echo esc_html( $facet['label'] );
			echo '</label>';
			echo '</li>';
		}

		echo '</ul>';
	}

    public function add_meta_boxes() {
	    add_meta_box(
		    'sw_facetwp_page_listing_template',
		    'FacetWP Listing Template',
		    function ( $post ) {
			    $value = get_post_meta( $post->ID, 'sw_facetwp_page_listing_template', true );
			    wp_nonce_field( 'sw_facetwp_page_listing_template_nonce', 'sw_facetwp_page_listing_template_nonce' );
			    ?>
                <p>
                    <label for="sw_facetwp_page_listing_template"><?php echo esc_html( 'Enter template name:' ); ?></label>
                </p>
                <input type="text" id="sw_facetwp_page_listing_template" name="sw_facetwp_page_listing_template"
                       value="<?php echo esc_attr( $value ); ?>" class="widefat">
                <p class="description"><?php echo esc_html( 'Example: Enter "ny-page-listings" for /themes/[your-theme]/theme/facet-wp-remote-data/ny-page-listings.php' ); ?></p>
                <p class="description"><?php echo esc_html( 'Leave blank to use default template.' ); ?></p>
			    <?php
		    },
		    ['post', 'page'],
		    'side'
	    );
    }

    public function save_post_action( $post_id ) {
	    if ( ! isset( $_POST['sw_facetwp_page_listing_template_nonce'] )
             || ! wp_verify_nonce( $_POST['sw_facetwp_page_listing_template_nonce'], 'sw_facetwp_page_listing_template_nonce' )
        ) {
		    return;
	    }

	    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		    return;
	    }

	    if ( isset( $_POST['sw_facetwp_page_listing_template'] ) ) {
		    update_post_meta( $post_id, 'sw_facetwp_page_listing_template', sanitize_text_field( $_POST['sw_facetwp_page_listing_template'] ) );
	    } else {
		    delete_post_meta( $post_id, 'sw_facetwp_page_listing_template' );
	    }
    }

    public function wp_ajax_sync_facetwp_settings_callback() {
        check_ajax_referer( 'facetwp_sw_facetwp_admin_ajax_nonce', 'nonce' );

	    $result = self::sync_facetwp_settings();

	    if ( is_wp_error( $result ) ) {
		    wp_send_json_error( $result->get_error_message() );
	    } else {
		    wp_send_json_success( $result );
	    }

        exit();
    }

	public static function sync_facetwp_settings() {
		$remote_site_url = get_option( 'facetwp_remote_data_remote_site_url' );

		if ( empty( $remote_site_url ) ) {
			return new WP_Error( 'no_remote_url', 'Remote site URL is not set.', ['status' => 400] );
		}

		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

		if ( empty( $auth_header ) ) {
			return new WP_Error( 'no_credentials', 'Remote site credentials are not set.', ['status' => 403] );
		}

		$response = wp_remote_get(
			$remote_site_url . '/wp-json/sw-facetwp/v1/get-facetwp-settings',
			[
				'headers' => [
					'Authorization' => 'Basic ' . $auth_header,
					'Subsite-Url' => get_bloginfo( 'url' )
				],
				'timeout' => 30,
				'sslverify' => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
			]
		);

		if ( is_wp_error( $response ) ) {
			error_log( "ERROR fetching remote site FacetWP settings data. " . $response->get_error_message() );
			return new WP_Error( 'http_error', $response->get_error_message(), ['status' => 500] );
		}

		$http_code = wp_remote_retrieve_response_code( $response );
		$body_json = wp_remote_retrieve_body( $response );
		$body = json_decode( $body_json, true );

		if ( $http_code !== 200 || empty( $body['facetwp_settings'] ) ) {
			error_log( "ERROR fetching remote site FacetWP settings. Raw: " . print_r( $body, true ) );
			return new WP_Error( 'invalid_data', 'Invalid settings from main site.', ['status' => $http_code] );
		}

		$new_settings = json_decode( $body['facetwp_settings'], true );

		if ( empty( $new_settings['facets'] ) ) {
			return new WP_Error( 'empty_data', 'No facets found in settings.', ['status' => 204] );
		}

		update_option( 'facetwp_settings', json_encode( $new_settings ) );

		return [ 'success' => true, 'message' => 'FacetWP settings synced successfully.' ];
	}

    public static function sync_facetwp_index_table() {
        $handler = new Facet_Wp_Remote_Data_Handler();

        if (
            $handler->background_process->is_queued()
            || get_option( self::AJAX_INDEX_TABLE_SYNC_RUNNING_OPTION_KEY )
        ) {
            error_log( "Syncing skipped: index table is currently being updated." );

            return;
        }

	    $remote_site_url = get_option( 'facetwp_remote_data_remote_site_url' );
	    $auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

	    $response = wp_remote_get(
		    $remote_site_url . '/wp-json/sw-facetwp/v1/facet-index-table-count',
		    [
			    'headers' => [
				    'Authorization' => 'Basic ' . $auth_header,
				    'Subsite-Url'   => get_bloginfo( 'url' )
			    ],
			    'timeout'    => 60,
			    'sslverify'  => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
		    ]
	    );

	    if ( is_wp_error( $response ) ) {
		    error_log( "ERROR fetching remote site FacetWP settings data. " . $response->get_error_message() );
		    return new WP_Error( 'http_error', $response->get_error_message(), ['status' => 500] );
	    }

	    $http_code = wp_remote_retrieve_response_code( $response );
	    $body_json = wp_remote_retrieve_body( $response );
	    $body = json_decode( $body_json, true );

	    if ( $http_code !== 200 || empty( $body['total_batches'] ) ) {
		    error_log( "ERROR fetching remote site FacetWP settings. Raw: " . print_r( $body, true ) );
		    return new WP_Error( 'invalid_data', 'Invalid settings from main site.', ['status' => $http_code] );
	    }

	    if ( empty( $body['total_batches'] ) ) {
		    error_log( 'Facet index total_batches is missing or invalid.' );
		    return;
	    }

	    $handler->set_index_table_background_job( $body['total_batches'] );

        return true;
    }

	public static function sync_index_batch( $batch = 1 ) {
		global $wpdb;

		$remote_site_url = get_option( 'facetwp_remote_data_remote_site_url' );
		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();
		$main_table = "{$wpdb->prefix}facetwp_index";
		$temp_table = "{$wpdb->prefix}facetwp_index_temp";
		$old_table = "{$main_table}_old";

		if ( 1 === (int) $batch ) {
			self::ensure_facetwp_index_table_exists();

			$wpdb->query( "DROP TABLE IF EXISTS $temp_table" );
			$wpdb->query( "CREATE TABLE $temp_table LIKE $main_table" );
		}

		$response = wp_remote_get(
			$remote_site_url . '/wp-json/sw-facetwp/v1/get-facetwp-index-table?batch=' . $batch,
			[
				'headers' => [
					'Authorization' => 'Basic ' . $auth_header,
					'Subsite-Url'   => get_bloginfo( 'url' )
				],
				'timeout'    => 60,
				'sslverify'  => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
			]
		);

		if ( is_wp_error( $response ) ) {
			return new WP_Error( 'http_error', $response->get_error_message(), ['status' => 500] );
		}

		$http_code = wp_remote_retrieve_response_code( $response );
		$body_json = wp_remote_retrieve_body( $response );
		$body = json_decode( $body_json, true );

		if ( $http_code !== 200 || empty( $body ) ) {
			return new WP_Error( 'http_error', $response->get_error_message(), ['status' => 500] );
		}

		$index_rows = $body['facetwp_index'] ?? [];
		$total_batches = $body['total_batches'] ?? null;

		if ( is_null( $total_batches ) || 0 === (int) $total_batches ) {
			return new WP_Error( 'sync_error', 'Missing total_batches in API response', ['status' => 500] );
		}

		// Skip if temp table doesn't exist
		if ( ! $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $temp_table ) ) ) {
			return new WP_Error( 'missing_temp_table', "Temp table does not exist for batch $batch", ['status' => 500] );
		}

		// Insert batch into temp table
		if ( ! empty( $index_rows ) ) {
			$allowed_columns = [
				'post_id', 'facet_name', 'facet_value', 'facet_display_value',
				'term_id', 'parent_id', 'depth', 'source', 'blog_id'
			];

			foreach ( $index_rows as $row ) {
				$sanitized = array_intersect_key( $row, array_flip( $allowed_columns ) );
				if ( ! empty( $sanitized ) ) {
					$wpdb->insert( $temp_table, $sanitized );
				}
			}
		}

		// If this is the last batch, swap tables
		if ( (int) $batch >= (int) $total_batches ) {
			$wpdb->query( "RENAME TABLE $main_table TO $old_table, $temp_table TO $main_table" );

			// Only drop old table if new table has rows
			$count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM $main_table" );

			if ( $count > 0 ) {
				$wpdb->query( "DROP TABLE IF EXISTS $old_table" );
			} else {
				// Rollback if new table is empty
				$wpdb->query( "RENAME TABLE $old_table TO $main_table" );

				return new WP_Error( 'sync_error', 'Failed to sync facetwp_index: no data inserted', ['status' => 500] );
			}

			return 'done';
		}

		return $batch;
	}

	public static function wp_ajax_sync_index_batch() {
		check_ajax_referer( 'facetwp_sw_facetwp_admin_ajax_nonce', 'nonce' );

		$batch = isset( $_POST['batch'] ) ? intval( $_POST['batch'] ) : 1;
		$attempt = isset( $_POST['attempt'] ) ? intval( $_POST['attempt'] ) : 1;

		$handler = new Facet_Wp_Remote_Data_Handler();

		if ( $handler->background_process->is_queued() ) {
			wp_send_json_error( "Syncing skipped: index table is currently being updated." );

			return;
		}

        if ( 1 === $batch ) {
	        update_option( self::AJAX_INDEX_TABLE_SYNC_RUNNING_OPTION_KEY, true );
        }

		$result = self::sync_index_batch( $batch );

        if (
            'done' === $result
            || ( is_wp_error( $result ) && $attempt >= 3 )
        ) {
	        delete_option( self::AJAX_INDEX_TABLE_SYNC_RUNNING_OPTION_KEY );
        }

		if ( 'done' === $result ) {
			do_action( 'facet_remote_data_index_table_sync_completed' );
		}

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( $result->get_error_message() );
		} else {
			wp_send_json_success([
				'message' => "Batch $batch processed.",
				'next_batch' => 'done' === $result ? false : $batch + 1
			]);
		}
	}

	private static function ensure_facetwp_index_table_exists() {
		global $wpdb;

		$table_name = $wpdb->prefix . 'facetwp_index';

		if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) ) === $table_name ) {
			return;
		}

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';

		$sql = "
            CREATE TABLE {$table_name} (
                id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
                post_id int(10) UNSIGNED DEFAULT NULL,
                facet_name varchar(50) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
                facet_value varchar(50) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
                facet_display_value varchar(200) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
                term_id int(10) UNSIGNED DEFAULT 0,
                parent_id int(10) UNSIGNED DEFAULT 0,
                depth int(10) UNSIGNED DEFAULT 0,
                variation_id int(10) UNSIGNED DEFAULT 0,
                PRIMARY KEY (id),
                KEY post_id (post_id),
                KEY facet_name (facet_name),
                KEY facet_value (facet_value),
                KEY term_id (term_id)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
        ";

		dbDelta( $sql );
	}

	public function wp_ajax_delete_facetwp_cache_callback() {
		check_ajax_referer( 'facetwp_sw_facetwp_admin_ajax_nonce', 'nonce' );

		$result = Facet_Wp_Remote_Data_Cache::delete_cache();

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( $result->get_error_message() );
		} else {
			wp_send_json_success( [ 'message' => "FacetWP cache cleared!", 'deleted' => true ] );
		}

		exit();
	}

}
