<?php
/**
 * MaplePress API Client - handles communication with MaplePress backend.
 *
 * @package    MaplePress
 * @subpackage MaplePress/includes
 */

class MaplePress_API_Client {

	/**
	 * API base URL.
	 *
	 * @var string
	 */
	private $api_url;

	/**
	 * API key.
	 *
	 * @var string
	 */
	private $api_key;

	/**
	 * Constructor.
	 *
	 * @param string $api_url API base URL.
	 * @param string $api_key API key.
	 */
	public function __construct( $api_url, $api_key ) {
		$this->api_url = trailingslashit( $api_url );
		$this->api_key = $api_key;
	}

	/**
	 * Verify API connection and API key.
	 *
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	public function verify_connection() {
		return $this->request( 'GET', 'api/v1/plugin/status' );
	}

	/**
	 * Trigger domain verification via DNS TXT record check.
	 *
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	public function verify_domain() {
		error_log( 'MaplePress API: verify_domain() called' );
		$result = $this->request( 'POST', 'api/v1/plugin/verify' );
		error_log( 'MaplePress API: verify_domain() result = ' . print_r( $result, true ) );
		return $result;
	}

	/**
	 * Send a request to the MaplePress API.
	 *
	 * @param string $method  HTTP method (GET, POST, PUT, DELETE).
	 * @param string $endpoint API endpoint (relative to base URL).
	 * @param array  $body    Optional. Request body data.
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	private function request( $method, $endpoint, $body = array() ) {
		$url = $this->api_url . ltrim( $endpoint, '/' );

		// Debug logging (only enable when WP_DEBUG is true)
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log( "MaplePress API: Making $method request to: $url" );
		}

		$args = array(
			'method'  => $method,
			'headers' => array(
				'Authorization' => 'Bearer ' . $this->api_key,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 15,
		);

		if ( ! empty( $body ) && in_array( $method, array( 'POST', 'PUT', 'PATCH' ), true ) ) {
			$args['body'] = wp_json_encode( $body );
		}

		$response = wp_remote_request( $url, $args );

		if ( is_wp_error( $response ) ) {
			return $response;
		}

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

		if ( $status_code >= 400 ) {
			$error_message = isset( $data['message'] ) ? $data['message'] : __( 'Unknown API error', 'maplepress' );

			// Log full response for debugging
			error_log( 'MaplePress API Error Response:' );
			error_log( 'Status Code: ' . $status_code );
			error_log( 'Raw Body: ' . $body );
			error_log( 'Parsed Data: ' . print_r( $data, true ) );

			// Determine error code based on status
			$error_code = 'maplepress_api_error';
			if ( $status_code === 429 ) {
				$error_code = 'maplepress_rate_limited';
			} elseif ( $status_code === 403 ) {
				$error_code = 'maplepress_forbidden';
			} elseif ( $status_code === 404 ) {
				$error_code = 'maplepress_not_found';
			}

			return new WP_Error(
				$error_code,
				sprintf(
					/* translators: 1: HTTP status code, 2: error message */
					__( 'API Error (%1$d): %2$s', 'maplepress' ),
					$status_code,
					$error_message
				),
				array( 'status' => $status_code )
			);
		}

		return $data;
	}

	/**
	 * Sync pages to MaplePress backend.
	 *
	 * @param array $pages Array of page data to sync.
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	public function sync_pages( $pages ) {
		$data = array(
			'pages' => $pages,
		);

		return $this->request( 'POST', 'api/v1/plugin/pages/sync', $data );
	}

	/**
	 * Index a post in MaplePress (single page).
	 *
	 * @param int $post_id Post ID.
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	public function index_post( $post_id ) {
		$post = get_post( $post_id );

		if ( ! $post ) {
			return new WP_Error( 'invalid_post', __( 'Post not found', 'maplepress' ) );
		}

		// Format page data for API
		$page_data = $this->format_page_data( $post );

		// Sync single page
		return $this->sync_pages( array( $page_data ) );
	}

	/**
	 * Format post/page data for API sync.
	 *
	 * @param WP_Post $post Post object.
	 * @return array Formatted page data.
	 */
	private function format_page_data( $post ) {
		// Format timestamps in RFC3339 format (ISO 8601)
		// Use actual GMT time if available, otherwise use server time converted to GMT
		$published_at = '';
		if ( $post->post_date_gmt && $post->post_date_gmt !== '0000-00-00 00:00:00' ) {
			$published_at = gmdate( 'Y-m-d\TH:i:s\Z', strtotime( $post->post_date_gmt . ' UTC' ) );
		}

		$modified_at = '';
		if ( $post->post_modified_gmt && $post->post_modified_gmt !== '0000-00-00 00:00:00' ) {
			$modified_at = gmdate( 'Y-m-d\TH:i:s\Z', strtotime( $post->post_modified_gmt . ' UTC' ) );
		}

		return array(
			'page_id'      => (string) $post->ID,
			'title'        => $post->post_title,
			'content'      => wp_strip_all_tags( $post->post_content ),
			'excerpt'      => ! empty( $post->post_excerpt ) ? $post->post_excerpt : wp_trim_words( $post->post_content, 55, '...' ),
			'url'          => get_permalink( $post->ID ),
			'status'       => $post->post_status,
			'post_type'    => $post->post_type,
			'author'       => get_the_author_meta( 'display_name', $post->post_author ),
			'published_at' => $published_at,
			'modified_at'  => $modified_at,
		);
	}

	/**
	 * Remove a post from MaplePress index.
	 *
	 * @param int $post_id Post ID.
	 * @return array|WP_Error Response data or WP_Error on failure.
	 */
	public function delete_post( $post_id ) {
		return $this->request( 'DELETE', 'api/v1/plugin/index/' . $post_id );
	}

	/**
	 * Search using MaplePress API.
	 *
	 * @param string $query Search query.
	 * @param array  $args  Optional. Additional search parameters.
	 * @return array|WP_Error Search results or WP_Error on failure.
	 */
	public function search( $query, $args = array() ) {
		$params = array_merge(
			array(
				'query'  => $query,
				'limit'  => 10,
				'offset' => 0,
			),
			$args
		);

		return $this->request( 'POST', 'api/v1/plugin/pages/search', $params );
	}
}
