<?php
/**
 * Postomatic Plugin - Blog Analyzer class.
 *
 * PHP Version 5.6
 *
 * @package  Postomatic
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 */

namespace Postomatic\Api;

use Postomatic\Constants;
use Postomatic\Core\Activator;
use Postomatic\Utils;

/**
 * Blog Analyzer class.
 *
 * This class handles the blog analysis functionality.
 *
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 */
class Blog_Analyzer {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'wp_ajax_postomatic_analyze_blog', array( $this, 'analyze_blog' ) );
	}

	/**
	 * Analyze blog posts.
	 *
	 * This method fetches blog post titles from the selected category
	 * and sends them to the API for analysis.
	 *
	 * @return void
	 */
	public function analyze_blog() {
		// Check nonce for security.
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'postomatic_admin_nonce' ) ) {
			wp_send_json_error( 'Invalid nonce.', 403 );

			return;
		}

		// Check if user has permission.
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( 'Permission denied' );

			return;
		}

		// Get category ID from request.
		$category_id = isset( $_POST['category'] ) ? intval( $_POST['category'] ) : 0;

		// Get author information from request.
		$author_id   = isset( $_POST['wordpress_author_id'] ) ? sanitize_text_field( wp_unslash( $_POST['wordpress_author_id'] ) ) : '';
		$author_name = isset( $_POST['wordpress_author_name'] ) ? sanitize_text_field( wp_unslash( $_POST['wordpress_author_name'] ) ) : '';

		// Fetch post titles.
		$titles = $this->get_post_titles( $category_id );

		if ( empty( $titles ) ) {
			wp_send_json_error( 'No posts found in the selected category' );

			return;
		}

		// Send titles to API for analysis.
		$analysis_result = $this->send_titles_to_api( $titles, $author_id, $author_name );

		if ( is_wp_error( $analysis_result ) ) {
			wp_send_json_error( $analysis_result->get_error_message() );

			return;
		}

		wp_send_json_success( array( 'keywords' => $analysis_result['data']['keywords'] ) );
	}

	/**
	 * Get post titles from the specified category.
	 *
	 * @param  int $category_id The category ID.
	 * @return array An array of post titles.
	 */
	private function get_post_titles( $category_id ) {
		$args = array(
			'posts_per_page' => 100, // Get a reasonable number of titles.
			'post_status'    => array( 'publish', 'draft' ), // Include both published and draft posts.
			'orderby'        => 'date',
			'order'          => 'DESC',
			'fields'         => 'ids', // Only get post IDs for efficiency.
		);

		// Add category filter if specified.
		if ( $category_id > 0 ) {
			$args['cat'] = $category_id;
		}

		// Get post IDs.
		$post_ids = get_posts( $args );
		$titles   = array();

		// Get titles for each post.
		foreach ( $post_ids as $post_id ) {
			$titles[] = get_the_title( $post_id );
		}

		return $titles;
	}

	/**
	 * Get content of the last 10 posts.
	 *
	 * @return array An array of post contents.
	 */
	private function get_last_50_post_contents() {
		$args = array(
			'posts_per_page' => 50,
			'post_status'    => 'publish',
			'orderby'        => 'date',
			'order'          => 'DESC',
		);

		$posts    = get_posts( $args );
		$contents = array();

		foreach ( $posts as $post ) {
			$contents[] = array(
				'id'      => $post->ID,
				'title'   => $post->post_title,
				'content' => get_the_excerpt( $post ),
			);
		}

		return $contents;
	}

	/**
	 * Send post titles to the API for analysis.
	 *
	 * @param  array  $titles      An array of post titles.
	 * @param  string $author_id   The WordPress author ID.
	 * @param  string $author_name The WordPress author name.
	 * @param  int    $retry_count Number of retry attempts (default: 0).
	 * @return array|WP_Error The API response or WP_Error on failure.
	 */
	private function send_titles_to_api( $titles, $author_id = '', $author_name = '', $retry_count = 0 ) {
		// Get the last 10 post contents.
		$last_10_post_contents = $this->get_last_50_post_contents();

		// Prepare the data to send to the API.
		$data = array(
			'titles'                => $titles,
			'last_10_post_contents' => $last_10_post_contents,
		);

		// Add author information if provided.
		if ( ! empty( $author_id ) ) {
			$data['wordpress_author_id'] = $author_id;
		}
		if ( ! empty( $author_name ) ) {
			$data['wordpress_author_name'] = $author_name;
		}

		// Get API key.
		$api_key = Utils::get_api_service_key();

		// Use API_BASE_URL instead of API_BASE_URL_FRONT (via API_BLOG_ANALYSIS_EXTERNAL).
		$api_url = Constants::API_BLOG_ANALYSIS_EXTERNAL;

		// Send request to API (blocking must be true to get the response).
		$response = wp_remote_post(
			$api_url,
			array(
				'method'      => 'POST',
				'timeout'     => 45,
				'redirection' => 5,
				'httpversion' => '1.0',
				'blocking'    => true, // Changed from false to true.
				'headers'     => array(
					'Content-Type' => 'application/json',
					'Accept'       => 'application/json',
					'Api-Key'      => $api_key,
				),
				'body'        => wp_json_encode( $data ),
				'data_format' => 'body', // Ensure data is sent as raw body content.
				'cookies'     => array(),
			)
		);

		// Check for errors.
		if ( is_wp_error( $response ) ) {
			// Include error message and error data if available.
			$error_message = $response->get_error_message();
			$error_data    = $response->get_error_data();
			if ( ! empty( $error_data ) ) {
				$error_message .= ' (' . wp_json_encode( $error_data ) . ')';
			}

			return new \WP_Error( 'http_request_failed', $error_message );
		}

		// Get response code.
		$response_code = wp_remote_retrieve_response_code( $response );

		// Check for 401 Unauthorized error.
		if ( 401 === $response_code ) {
			// Call Activator::activate() to refresh the API key.
			Activator::activate();

			// Sleep for 15 seconds.
			sleep( 10 );

			// Retry up to 2 times (retry_count < 2).
			if ( $retry_count < 2 ) {
				// Retry the request with incremented retry count and refreshed API key.
				return $this->send_titles_to_api( $titles, $author_id, $author_name, $retry_count + 1 );
			}

			// If we've already retried twice, return an error.
			return new \WP_Error(
				'authorization_failed',
				esc_html__( 'Authorization failed after multiple attempts.', 'postomatic' )
			);
		}

		// Get response body.
		$body   = wp_remote_retrieve_body( $response );
		$result = json_decode( $body, true );

		// Check if response is successful.
		if ( 200 !== $response_code ) {
			// Try to extract error message from API response.
			$api_error = '';
			if ( is_array( $result ) && isset( $result['error'] ) ) {
				$api_error = $result['error'];
			} elseif ( is_array( $result ) && isset( $result['message'] ) ) {
				$api_error = $result['message'];
			}
			$error_message = 'API returned error: ' . $response_code;
			if ( ! empty( $api_error ) ) {
				$error_message .= ' - ' . $api_error;
			}

			return new \WP_Error(
				'api_error',
				$error_message
			);
		}

		if ( JSON_ERROR_NONE !== json_last_error() ) {
			return new \WP_Error(
				'json_error',
				'Invalid JSON response from API'
			);
		}

		return $result;
	}
}

// Initialize the class.
new Blog_Analyzer();
