<?php

class Facet_Wp_Remote_Data_Handler {

	private static $facetwp_remote_data = null;

	private const FACETWP_API_ENDPOINT = '/wp-json/facetwp/v1/fetch';

	private const REMOTE_SITE_PROPERTY_POST_TYPE_SLUG = 'property';

	private const REMOTE_SITE_PROPERTIES_REST_ENDPOINT = '/wp-json/sw-facetwp/v1/properties';

	private const REMOTE_SITE_PROPERTY_REST_ENDPOINT = '/wp-json/sw-facetwp/v1/property';

	private static $posts_per_page = 12;

	public function facetwp_template_html( $output, $class ) {
		$current_page_id = $this->get_page_id_from_facet_params( $class->http_params );

		if ( ! $this->should_use_main_site_facet_wp_data( $current_page_id ) ) return $output;

		$remote_data = $this->get_facetwp_remote_data( $class );

		$posts_data = $remote_data['posts'] ?? null;

		if ( ! $posts_data ) return $output;

		$template_vars = [
			'properties_data' => $posts_data,
		];

		$default_template = dirname( plugin_dir_path( __FILE__ ) ) . '/templates/facet-wp-remote-data-listing-template.php';

		// Allow themes to override the template by checking in the theme folder.
		$theme_template = locate_template( 'facet-wp-remote-data/facet-wp-remote-data-listing-template.php' );

		$template_path = $theme_template ?: $default_template;

		$template_path = apply_filters( 'facet_wp_remote_data_listing_template_path', $template_path, $template_vars );

		do_action( 'facet_wp_listing_page_load', $template_path, $template_vars );

		extract( $template_vars, EXTR_SKIP );

		ob_start();

		include $template_path;

		return ob_get_clean();
    }

    public function facetwp_facet_render_args( $args ) {
	    $current_page_id = $this->get_page_id_from_facet_params( $_POST['data']['http_params'] ?? null );

	    if ( ! $this->should_use_main_site_facet_wp_data( $current_page_id ) ) return $args;

	    $facet_name = $args['facet']['name'];

		$remote_data = $this->get_facetwp_remote_data();

		$choices = $remote_data['facet_data']['facets'][$facet_name]['choices'] ?? null;

		if ( empty( $choices ) ) return $args;

		$values = [];

		foreach ( $choices as $choice ) {
			$values[] = [
				'facet_value' => $choice['value'],
				'facet_display_value' => $choice['label'],
				'term_id' => $choice['term_id'],
				'depth' => $choice['depth'],
				'counter' => $choice['count'],
			];
		}

		if ( ! empty( $values ) ) {
			$args['values'] = $values;
		}

		return $args;
	}

	public function facetwp_pager_args( $pager_args, $class ) {
		$current_page_id = $this->get_page_id_from_facet_params( $class->http_params );

		if ( ! $this->should_use_main_site_facet_wp_data( $current_page_id ) ) return $pager_args;

		$remote_data = $this->get_facetwp_remote_data();

		$pager_args = $remote_data['facet_data']['pager'] ?? $pager_args;

		return $pager_args;
	}

	// @see web/wp-content/plugins/facetwp/includes/facets/autocomplete.php
	public function forward_ajax_load_to_main_site() {
		if (
			! isset( $_POST['action'] )
			|| 'facetwp_autocomplete_load' !== $_POST['action']
		) {
			return;
		}

		$current_page_id = $this->get_page_id_from_facet_params( $_POST['data']['http_params'] ?? null );

		if ( ! $this->should_use_main_site_facet_wp_data( $current_page_id ) ) return;

		$remote_site_url = get_option( 'facetwp_remote_data_remote_site_url' );

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

			exit();
		}

		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

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

			exit();
		}

		$response = wp_remote_post(
			$remote_site_url . '/wp-json/sw-facetwp/v1/forward-autocomplete-ajax-call',
			[
				'headers' => [
					'Authorization' => 'Basic ' . $auth_header,
					'Subsite-Url' => get_bloginfo( 'url' ),
					'Content-Type' => 'application/json'
				],
				'timeout' => 30,
				'sslverify' => Facet_Wp_Remote_Data_Utils::should_ssl_verify(),
				'body' => json_encode( $_POST ),
			]
		);

		if ( is_wp_error( $response ) ) {
			error_log( "ERROR fetching remote site FacetWP settings data. " . $response->get_error_message() );

			wp_send_json_error(
				new WP_Error( 'http_error', $response->get_error_message(), ['status' => 500] )
			);

			exit();
		}

		$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 ) {
			error_log( "ERROR fetching remote site FacetWP settings data. " . print_r( $body, true ) );

			wp_send_json_error(
				new WP_Error( 'http_error', "Received HTTP status code {$http_code} with message '{$body['message']}'", ['status' => $http_code] )
			);

			exit();
		}

		wp_send_json( $body );

		exit();
	}

	public function property_page_rewrite_rule() {
		add_rewrite_rule( '^property/([0-9]+)-[^/]+/?$', 'index.php?sw_remote_data_property_page=1&property_id=$matches[1]', 'top' );
	}

	public function property_page_rewrite_rule_query_vars( $vars ) {
		$vars[] = 'sw_remote_data_property_page';
		$vars[] = 'property_id';

		return $vars;
	}

	public function property_page_template() {
		if ( get_query_var( 'sw_remote_data_property_page' ) === '1' ) {
			$property_id = (int) get_query_var( 'property_id' );

			if ( empty( $property_id ) ) wp_die( 'No Property ID' );

			$transient_key = 'facetwp_property_remote_site_data_' . $property_id;

			$skip_cache = apply_filters( 'facetwp_remote_data_skip_cache', false );

			$post_remote_data = ! $skip_cache
				? get_transient( $transient_key )
				: false;

			if ( false === $post_remote_data ) {
				$post_remote_data = $this->get_property_remote_site_data( $property_id );

				if ( ! $post_remote_data ) wp_die( 'Invalid Property ID' );

				set_transient( $transient_key, $post_remote_data, 10 * MINUTE_IN_SECONDS );
			}

			$template_vars = [
				'property_data' => $post_remote_data,
			];

			$default_template = dirname( plugin_dir_path( __FILE__ ) ) . '/templates/facet-wp-remote-data-property-template.php';

			// Allow themes to override the template by checking in the theme folder.
			$theme_template = locate_template( 'facet-wp-remote-data/facet-wp-remote-data-property-template.php' );

			$template_path = $theme_template ?: $default_template;

			$template_path = apply_filters( 'facet_wp_remote_data_property_template_path', $template_path, $template_vars );

			do_action( 'facet_wp_property_page_load', $template_path, $template_vars );

			extract( $template_vars, EXTR_SKIP );

			include $template_path;

			exit();
		}
	}

	private function get_facetwp_remote_data( $class = null ) {
		if (
			is_null( self::$facetwp_remote_data )
			&& ! is_null( $class )
		) {
			$query_args = ! empty( $class->http_params )
				? wp_json_encode( $class->http_params )
				: ( ! empty( $class->template['name'] ) ? $class->template['name'] : 'facetwp_remote_data_default' );

			$transient_key = 'facetwp_remote_site_data_' . md5( $query_args );

			$skip_cache = apply_filters( 'facetwp_remote_data_skip_cache', false );

			$cached_data = ! $skip_cache
				? get_transient( $transient_key )
				: false;

			if ( false === $cached_data ) {
				$facetwp_remote_site_filtered_data = $this->get_remote_site_facetwp_filtered_data( $class );

				$posts_data = $this->get_remote_site_posts( $facetwp_remote_site_filtered_data );

				$cached_data = [
					'facet_data' => $facetwp_remote_site_filtered_data,
					'posts' => $posts_data
				];

				set_transient( $transient_key, $cached_data, 10 * MINUTE_IN_SECONDS );
			}

			self::$facetwp_remote_data = $cached_data;
		}

		return self::$facetwp_remote_data ?? null;
	}

	private function get_remote_site_facetwp_filtered_data( $class ) {
		$remote_site_url = Facet_Wp_Remote_Data_Utils::get_remote_site_url();

		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

        if ( empty( $remote_site_url ) || empty( $auth_header ) ) {
            return null;
        }

		$facets_from_option = $this->get_facets_from_options();

		$facets_for_request = [];

		if ( ! empty( $facets_from_option ) ) {
			foreach ( $facets_from_option as $facet ) {
				$facets_for_request[ $facet['name'] ] = $class->facets[ $facet['name'] ]['selected_values'] ?? [];
			}
		}

		$request_data = [
			'data' => [
				'facets' => $facets_for_request,
				'query_args' => [
					'post_type'      => self::REMOTE_SITE_PROPERTY_POST_TYPE_SLUG,
					'posts_per_page' => apply_filters( 'facet_wp_remote_data_posts_per_page', self::$posts_per_page ),
					'paged'          => $_GET['_paged'] ?? 1
				]
			]
		];

		$response = wp_remote_post(
			$remote_site_url . self::FACETWP_API_ENDPOINT,
			[
				'body'    => json_encode( $request_data ),
				'headers' => [
					'Content-Type'  => 'application/json',
					'Authorization' => 'Basic ' . $auth_header
				],
				'timeout' => 30,
				'sslverify' => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
			]
		);

		if ( is_wp_error( $response ) ) {
			error_log( 'Fetching FacetWP data from remote site error: ' . $response->get_error_message() );
		} else {
			$body = wp_remote_retrieve_body( $response );
			$data = json_decode( $body, true );
		}

		return $data ?? null;
	}

	private function get_remote_site_posts( $facetwp_remote_site_filtered_data ) {
		$remote_site_url = Facet_Wp_Remote_Data_Utils::get_remote_site_url();

		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

		if ( empty( $remote_site_url ) || empty( $auth_header ) ) {
			return null;
		}

		$post_ids = $facetwp_remote_site_filtered_data['results'] ?? [];

		if ( empty( $post_ids ) ) return null;

		$post_ids_string = implode( ',', $post_ids );

		$posts_api_url = add_query_arg(
			[
				'post_ids'  => $post_ids_string,
			],
			$remote_site_url . self::REMOTE_SITE_PROPERTIES_REST_ENDPOINT
		);

		$posts_response = wp_remote_get(
			$posts_api_url,
			[
				'headers' => [
					'Authorization' => 'Basic ' . $auth_header
				],
				'timeout' => 30,
				'sslverify' => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
			]
		);

		if ( is_wp_error( $posts_response ) ) {
			error_log( 'Error fetching posts from remote site: ' . $posts_response->get_error_message() );
		} else {
			$posts_body = wp_remote_retrieve_body( $posts_response );
			$posts_data = json_decode( $posts_body, true );

			$posts_data = array_map(
				function ( $post_data ) {
					$property_url_path = $post_data['property_id']
					                     . '-'
					                     . preg_replace( '/[^a-zA-Z0-9-]+/', '-', sanitize_title( $post_data['address'] ) );

					$post_data['link'] = trailingslashit( home_url( "/property/{$property_url_path}" ) );

					return $post_data;
				},
				$posts_data
			);
		}

		return $posts_data ?? null;
	}

	private function get_facets_from_options() {
		$option = get_option( 'facetwp_settings' );

		if ( ! empty( $option ) ) {
			$settings = ( false !== $option ) ? json_decode( $option, true ) : [];
		}

		return $settings['facets'] ?? [];
	}

	private function get_property_remote_site_data( $id ) {
		$remote_site_url = Facet_Wp_Remote_Data_Utils::get_remote_site_url();

		$auth_header = Facet_Wp_Remote_Data_Utils::get_auth_header();

		if ( empty( $remote_site_url ) || empty( $auth_header ) ) {
			return null;
		}

		$post_api_url = $remote_site_url . self::REMOTE_SITE_PROPERTY_REST_ENDPOINT. '/' . $id;

		$post_response = wp_remote_get(
			$post_api_url,
			[
				'headers' => [
					'Authorization' => 'Basic ' . $auth_header
				],
				'timeout' => 30,
				'sslverify' => Facet_Wp_Remote_Data_Utils::should_ssl_verify()
			]
		);

		if ( is_wp_error( $post_response ) ) {
			error_log( 'Error fetching post from remote site: ' . $post_response->get_error_message() );
		} else {
			$post_body = wp_remote_retrieve_body( $post_response );
			$post_data = json_decode( $post_body, true );
		}

		return $post_data ?? null;
	}

	private function get_page_id_from_facet_params( $http_params ) {
		return ! empty( $http_params['uri'] )
			? get_page_by_path( $http_params['uri'] )?->ID
			: get_option( 'page_on_front' );
	}

	private function should_use_main_site_facet_wp_data( $current_page_id = null ) {
		$selected_pages = get_option( 'facetwp_remote_data_selected_pages', [] );

		$current_page_id = $current_page_id ?: ( is_singular() ? get_queried_object_id() : null );

		return $current_page_id && in_array( $current_page_id, $selected_pages );
	}

}