<?php
/**
 * Postomatic Plugin - Content Goal Types Handler 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\Utils;
use Postomatic\Core\Activator;

/**
 * Content Goal Types Handler class.
 *
 * This class handles the content goal types 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 Content_Goal_Types_Handler {

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

	/**
	 * Get content goal types.
	 *
	 * This method returns the content goal types.
	 *
	 * @return void
	 */
	public function get_content_goal_types() {
		// 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.', 403 );

			return;
		}

		// Get content goal types.
		$content_goal_types = $this->get_content_goal_types_data();

		wp_send_json_success( $content_goal_types );
	}

	/**
	 * Get content goal types data.
	 *
	 * @param  int $retry_count Number of retry attempts (default: 0).
	 * @return array An array of content goal types.
	 */
	private function get_content_goal_types_data( $retry_count = 0 ) {
		// Get API key.
		$api_key = Utils::get_api_service_key();

		// Set API URL.
		$api_url = Constants::API_BLOG_AUTOPILOT_GOALS_EXTERNAL;

		// Send request to API.
		$response = wp_remote_get(
			$api_url,
			array(
				'method'      => 'GET',
				'timeout'     => 45,
				'redirection' => 5,
				'httpversion' => '1.1',
				'blocking'    => true,
				'headers'     => array(
					'Content-Type' => 'application/json',
					'Api-Key'      => $api_key,
				),
				'cookies'     => array(),
			)
		);

		// Check for errors.
		if ( is_wp_error( $response ) ) {
			// Log the error for debugging purposes only.

			// Return default content goal types as fallback.
			return $this->get_default_content_goal_types();
		}

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

		/*
		 * Throttled, not unauthorised. Authenticated endpoints allow 120
		 * requests a minute per credential. Returning the fallback keeps the
		 * screen usable, and returning early makes sure a 429 never reaches the
		 * 401 branch below and triggers a key rotation it does not need.
		 */
		if ( 429 === (int) $response_code ) {
			return $this->get_default_content_goal_types();
		}

		// Check for 401 Unauthorized error.
		if ( 401 === $response_code ) {
			// Refresh the API key, waiting only as long as the handshake needs
			// rather than a fixed ten seconds. See Activator::refresh_api_key().
			Activator::refresh_api_key();

			// Retry up to 2 times (retry_count < 2).
			if ( 2 > $retry_count ) {
				// Retry the request with incremented retry count.
				return $this->get_content_goal_types_data( $retry_count + 1 );
			}

			// If we've already retried twice, return default content goal types as fallback.
			return $this->get_default_content_goal_types();
		}

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

		// Check if response is successful.
		if ( 200 !== $response_code || JSON_ERROR_NONE !== json_last_error() ) {
			// Log the error for debugging purposes only.

			// Return default content goal types as fallback.
			return $this->get_default_content_goal_types();
		}

		// Check if the response has the expected structure.
		if ( ! isset( $result['data'] ) || ! is_array( $result['data'] ) ) {
			// Log the error for debugging purposes only.

			// Return default content goal types as fallback.
			return $this->get_default_content_goal_types();
		}

		return $result['data'];
	}

	/**
	 * Get default content goal types.
	 *
	 * This method returns a hardcoded list of content goal types as a fallback.
	 *
	 * @return array An array of default content goal types.
	 */
	private function get_default_content_goal_types() {
		return array(
			array(
				'id'          => 'seo-traffic',
				'title'       => 'SEO Traffic',
				'description' => 'Content focused on generating organic traffic via informational content.',
				'type'        => 'content',
			),
			array(
				'id'          => 'brand-awareness',
				'title'       => 'Brand Awareness',
				'description' => 'Content focused on enhancing brand visibility and trust.',
				'type'        => 'content',
			),
			array(
				'id'          => 'educational',
				'title'       => 'Educational Content',
				'description' => 'Content that informs or teaches the audience.',
				'type'        => 'content',
			),
			array(
				'id'          => 'community-engagement',
				'title'       => 'Community Engagement',
				'description' => 'Content that invites feedback or builds user interaction.',
				'type'        => 'content',
			),
			array(
				'id'          => 'news-announcements',
				'title'       => 'News / Announcements',
				'description' => 'Timely updates or company news.',
				'type'        => 'content',
			),
			array(
				'id'          => 'product-promotion',
				'title'       => 'Product Promotion',
				'description' => 'Content focused on promoting a specific product or service.',
				'type'        => 'product',
			),
			array(
				'id'          => 'product-comparison',
				'title'       => 'Compare Products',
				'description' => 'Content that compares multiple products to help users make informed decisions.',
				'type'        => 'product',
			),
			array(
				'id'          => 'affiliate-marketing',
				'title'       => 'Affiliate Marketing',
				'description' => 'Content focused on promoting affiliate products and earning commissions.',
				'type'        => 'content',
			),
		);
	}
}
