<?php

class Facet_Wp_Remote_Data_User {

	const META_KEY_FAVORITES = 'saved_favorite_properties';
	const META_KEY_SAVED_SEARCHES = 'saved_searches';

	public function register_user_rest_api_routes() {
		// Favorite Listings
		register_rest_route(
			'sw-facetwp/v1',
			'/favorites',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_favorites' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
			]
		);

		register_rest_route(
			'sw-facetwp/v1',
			'/favorites',
			[
				'methods'             => 'POST',
				'callback'            => [ $this, 'add_favorite' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
				'args' => [
					'property_id' => [
						'required' => true,
						'type'     => 'integer',
					],
				],
			]
		);

		register_rest_route(
			'sw-facetwp/v1',
			'/favorites/(?P<property_id>\d+)',
			[
				'methods'             => 'DELETE',
				'callback'            => [ $this, 'remove_favorite' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
			]
		);

		// Saved Searches
		register_rest_route(
			'sw-facetwp/v1',
			'/searches',
			[
				'methods'             => 'POST',
				'callback'            => [ $this, 'save_search' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
				'args' => [
					'title' => [
						'required' => true,
						'type'     => 'string',
					],
					'url' => [
						'required' => true,
						'type'     => 'string',
					],
				],
			]
		);

		register_rest_route(
			'sw-facetwp/v1',
			'/searches',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_searches' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
			]
		);

		register_rest_route(
			'sw-facetwp/v1',
			'/searches/(?P<index>\d+)',
			[
				'methods'             => 'DELETE',
				'callback'            => [ $this, 'delete_search' ],
				'permission_callback' => [ $this, 'check_user_auth' ],
			]
		);
	}

	public function check_user_auth() {
		return is_user_logged_in();
	}

	public static function force_update_favorites_cache() {
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
			WP_CLI::log( 'Facet_Wp_Remote_Data_User::force_update_favorites_cache()' );
		}

		add_filter( 'facetwp_remote_data_skip_cache', '__return_true' );

		return ( new self )->get_favorites();
	}

	public function get_favorites( WP_REST_Request $request = null ) {
		$user_id = get_current_user_id();

		$favorite_properties = get_user_meta( $user_id, self::META_KEY_FAVORITES, true ) ?: [];

		if ( ! empty( $favorite_properties ) ) {
			$transient_key = Facet_Wp_Remote_Data_Cache::property_posts_remote_site_data( $favorite_properties );

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

			$properties = ! $skip_cache
				? Facet_Wp_Remote_Data_Cache::get( $transient_key )
				: false;

			if ( false === $properties ) {
				$properties = ( new Facet_Wp_Remote_Data_Handler() )->get_remote_site_posts( $favorite_properties );

				if ( ! empty( $properties ) ) {
					Facet_Wp_Remote_Data_Cache::set( $transient_key, $properties );
				}
			}
		}

		return rest_ensure_response( [
			'success' => true,
			'data' => ! empty( $properties ) ? $properties : [],
		] );
	}

	public function add_favorite( WP_REST_Request $request ) {
		$user_id = get_current_user_id();
		$property_id = (int) $request->get_param( 'property_id' );

		if ( ! $property_id ) {
			return new WP_REST_Response( [
				'success' => false,
				'message' => 'Missing or invalid property_id.',
			], 400 );
		}

		$favorites = get_user_meta( $user_id, self::META_KEY_FAVORITES, true ) ?: [];

		if ( ! in_array( $property_id, $favorites, true ) ) {
			$favorites[] = $property_id;

			update_user_meta( $user_id, self::META_KEY_FAVORITES, $favorites );

			Facet_Wp_Remote_Data_User::force_update_favorites_cache();
		}

		return rest_ensure_response( [
			'success' => true,
			'data' => $favorites,
		] );
	}

	public function remove_favorite( WP_REST_Request $request ) {
		$user_id = get_current_user_id();
		$property_id = (int) $request->get_param( 'property_id' );

		if ( ! $property_id ) {
			return new WP_REST_Response( [
				'success' => false,
				'message' => 'Missing or invalid property_id.',
			], 400 );
		}

		$favorites = get_user_meta( $user_id, self::META_KEY_FAVORITES, true ) ?: [];

		$updated = array_filter(
			$favorites,
			fn ( $id ) => $id !== $property_id
		);

		if ( count( $favorites ) === count( $updated ) ) {
			return new WP_REST_Response( [
				'success' => false,
				'message' => 'Property not found in favorites.',
			], 404 );
		}

		update_user_meta( $user_id, self::META_KEY_FAVORITES, array_values( $updated ) );

		Facet_Wp_Remote_Data_User::force_update_favorites_cache();

		return rest_ensure_response( [
			'success' => true,
			'data' => array_values( $updated ),
		] );
	}

	public function save_search( WP_REST_Request $request ) {
		$user_id = get_current_user_id();
		$title = sanitize_text_field( $request->get_param( 'title' ) );
		$url = esc_url_raw( $request->get_param( 'url' ) );

		if ( empty( $title ) || empty( $url ) ) {
			return new WP_REST_Response( [
				'success' => false,
				'message' => 'Both title and url are required.',
			], 400 );
		}

		$timestamp = current_time( 'timestamp' );

		$searches = get_user_meta( $user_id, self::META_KEY_SAVED_SEARCHES, true ) ?: [];

		$searches[] = [
			'title' => $title,
			'timestamp' => $timestamp,
			'url' => $url,
		];

		update_user_meta( $user_id, self::META_KEY_SAVED_SEARCHES, $searches );

		return rest_ensure_response( [
			'success' => true,
			'data' => $searches,
		] );
	}

	public function get_searches( WP_REST_Request $request ) {
		$user_id = get_current_user_id();
		$searches = get_user_meta( $user_id, self::META_KEY_SAVED_SEARCHES, true ) ?: [];

		foreach ( $searches as &$search ) {
			$search['formatted_date'] = date_i18n( 'l, F jS, Y \a\t g:ia', $search['timestamp'] );
		}

		return rest_ensure_response( [
			'success' => true,
			'data' => $searches,
		] );
	}

	public function delete_search( WP_REST_Request $request ) {
		$user_id = get_current_user_id();
		$search_id = (int) $request->get_param( 'search_id' );

		$searches = get_user_meta( $user_id, self::META_KEY_SAVED_SEARCHES, true ) ?: [];

		if ( ! isset( $searches[ $search_id ] ) ) {
			return new WP_REST_Response( [
				'success' => false,
				'message' => 'Search not found at given index.',
			], 404 );
		}

		unset( $searches[ $search_id ] );

		update_user_meta( $user_id, self::META_KEY_SAVED_SEARCHES, array_values( $searches ) );

		return rest_ensure_response( [
			'success' => true,
			'data' => array_values( $searches ),
		] );
	}
}
