<?php
/**
 * Backend settings controller.
 */

namespace BoostsiteAIContentGenerator\Api;

use BoostsiteAIContentGenerator\Boostsite;

if ( ! class_exists( 'PostController' ) ) {

	/**
	 * Backend settings controller.
	 */
	class PostController extends \WP_REST_Controller {

		/**
		 * The application domain.
		 *
		 * @var string
		 */
		private $prefix;

		/**
		 * Initialize this class.
		 */
		public function __construct() {
			$this->prefix    = \BoostsiteAIContentGenerator\Main::PREFIX;
			$this->namespace = $this->prefix . '/v1';
			$this->rest_base = 'posts';
		}

		/**
		 * Register the routes.
		 *
		 * @return void
		 */
		public function register_routes() {
			// Register get posts route.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base,
				array(
					array(
						'methods'             => \WP_REST_Server::READABLE,
						'callback'            => array( $this, 'get_posts' ),
						'permission_callback' => array( $this, 'manage_posts_permissions_check' ),
						'args'                => array(),
					),
				)
			);

			// Register delete post route.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base,
				array(
					array(
						'methods'             => \WP_REST_Server::DELETABLE,
						'callback'            => array( $this, 'delete_posts' ),
						'permission_callback' => array( $this, 'manage_posts_permissions_check' ),
						'args'                => array(
							'ids' => array(
								'required'          => true,
								'validate_callback' => function ( $param, $request, $key ) {
									return is_array( $param ) && ! empty( $param );
								},
							),
						),
					),
				)
			);

			// Register regenate post route.
			register_rest_route(
				$this->namespace,
				'/' . $this->rest_base . '/regenerate',
				array(
					array(
						'methods'             => \WP_REST_Server::CREATABLE,
						'callback'            => array( $this, 'regenerate_posts' ),
						'permission_callback' => array( $this, 'manage_posts_permissions_check' ),
						'args'                => array(
							'ids' => array(
								'required'          => true,
								'validate_callback' => function ( $param, $request, $key ) {
									return is_array( $param ) && ! empty( $param );
								},
							),
						),
					),
				)
			);
		}

		/**
		 * Get the endpoint.
		 *
		 * @return string the full endpoint
		 */
		public function get_endpoint() {
			// example: myplugin/v1/settings.
			return $this->namespace . '/' . $this->rest_base;
		}

		/**
		 * Get all posts generated by Boostsite API with pagination.
		 *
		 * @param WP_REST_Request $request Full details about the request.
		 *
		 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
		 */
		public function get_posts( $request ) {
			// Get pagination parameters from the request.
			$page     = $request->get_param( 'page' ) ? (int) $request->get_param( 'page' ) : 1;
			$per_page = $request->get_param( 'page' ) ? (int) $request->get_param( 'per_page' ) : 10;

			// Get search from the request.
			$search = sanitize_text_field( $request->get_param( 'search' ) );

			// Fetch paginated posts.
			$query_args = array(
				'post_status'    => 'any',
				'orderby'        => 'date',
				'order'          => 'DESC',
				'meta_query'     => array(
					'relation' => 'AND', // Ensure all conditions must be met.
					array(
						'key'     => 'wp_autopost_ai_post',
						'value'   => true,
						'compare' => '=',
					),
				),
				'posts_per_page' => $per_page,
				'paged'          => $page,
			);

			// Add search parameter if exists.
			if ( ! empty( $search ) ) {
				$query_args['s'] = $search;
			}

			// Add status if exists.
			$status = $request->get_param( 'status' ) ? $request->get_param( 'status' ) : '';

			if ( ! empty( $status ) ) {
				// Ensure it's an array.
				$statuses                   = explode( ',', $status );
				$query_args['meta_query'][] = array(
					'key'     => 'wp_autopost_ai_post_status',
					'value'   => $statuses,
					'compare' => 'IN',
				);
			}

			// Add keeywords if exists.
			$keywords = $request->get_param( 'keywords' ) ? $request->get_param( 'keywords' ) : '';

			if ( ! empty( $keywords ) ) {
				// Ensure it's an array.
				$keywords = explode( ',', $keywords );

				// Prepare a meta query for each keyword.
				$keyword_meta_query = array( 'relation' => 'OR' );

				foreach ( $keywords as $keyword ) {
					$keyword_meta_query[] = array(
						'key'     => 'wp_autopost_ai_post_keywords',
						'value'   => $keyword,
						'compare' => 'LIKE',
					);
				}

				// Add to meta_query.
				$query_args['meta_query'][] = $keyword_meta_query;
			}

			$query = new \WP_Query( $query_args );

			// Error handling.
			if ( is_wp_error( $query->posts ) ) {
				return new \WP_Error(
					'no_posts',
					__( 'Unable to retrieve posts.', 'boostsite-ai-content-generator' ),
					array( 'status' => 500 )
				);
			}

			$nonce = wp_create_nonce( 'wp_rest' );

			// Prepare the data.
			$data = array(
				'posts'        => array(),
				'total_posts'  => $query->found_posts,
				'total_pages'  => $query->max_num_pages,
				'current_page' => $page,
			);

			foreach ( $query->posts as $post ) {
				$data['posts'][] = array(
					'id'           => $post->ID,
					'title'        => $post->post_title,
					'status'       => get_post_meta( $post->ID, 'wp_autopost_ai_post_status', true ),
					'publish_date' => gmdate( 'd F Y H:i', strtotime( $post->post_date ) ),
					'post_link'    => get_admin_url() . 'post.php?post=' . $post->ID . '&action=edit',
					'keywords'     => explode( ',', get_post_meta( $post->ID, 'wp_autopost_ai_post_keywords', true ) ),
				);
			}

			// Return the post data.
			$response = array(
				'data'    => $data,
				'success' => true,
				'nonce'   => $nonce,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Delete a post by ID.
		 *
		 * @param WP_REST_Request $request Full details about the request.
		 *
		 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
		 */
		public function delete_posts( $request ) {
			$ids = $request->get_param( 'ids' );

			// Show errors if exists.
			$deleted = array();
			$errors  = array();

			// Delete each article.
			foreach ( $ids as $id ) {
				$result = wp_delete_post( (int) $id, true );

				if ( $result ) {
					$deleted[] = $id;
				} else {
					$errors[] = $id;
				}
			}

			$nonce = wp_create_nonce( 'wp_rest' );

			// Return the response.
			$response = array(
				'success'      => true,
				'post_success' => $deleted,
				'post_errors'  => $errors,
				'nonce'        => $nonce,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Regenerate posts by ID using Boostsite API.
		 *
		 * @param WP_REST_Request $request Full details about the request.
		 *
		 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
		 */
		public function regenerate_posts( $request ) {
			$ids = $request->get_param( 'ids' );

			if ( ! is_array( $ids ) || empty( $ids ) ) {
				return new \WP_Error( 'invalid_ids', __( 'Invalid or missing IDs.', 'boostsite-ai-content-generator' ), array( 'status' => 400 ) );
			}

			// Show errors if exists.
			$regenerated = array();
			$errors      = array();

			// Call Boostsite function for each article.
			$boostsite = new Boostsite();
			foreach ( $ids as $id ) {
				$result = $boostsite->regenerate_post( (int) $id );

				if ( $result ) {
					$regenerated[] = $id;
				} else {
					$errors[] = $id;
				}
			}

			$nonce = wp_create_nonce( 'wp_rest' );

			// Return the response.
			$response = array(
				'success'      => true,
				'post_success' => $regenerated,
				'post_errors'  => $errors,
				'nonce'        => $nonce,
			);

			return rest_ensure_response( $response );
		}

		/**
		 * Checks if a given request has access to read the items.
		 *
		 * @param  WP_REST_Request $request Full details about the request.
		 *
		 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
		 */
		public function manage_posts_permissions_check( $request ) {
			// optional: check nonce
			// https://via.studio/journal/wordpress-rest-api-secure-ajax-calls-custom-endpoints
			// example: /wp-json/me/v1/endpoint/?_wpnonce=${nonce}
			// check_ajax_referer('wp_rest', '_wpnonce', true)
			// 3rd parameter (die=true) to kill rest of execution.

			// Check the nonce for security.
			$nonce = $request->get_header( 'X-WP-Nonce' );
			if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
				return new \WP_Error( 'rest_forbidden', __( 'Invalid nonce.', 'boostsite-ai-content-generator' ), array( 'status' => 403 ) );
			}

			if ( ! current_user_can( 'edit_posts' ) ) {
				return new \WP_Error( 'rest_forbidden', __( 'Sorry, you cannot update settings.', 'boostsite-ai-content-generator' ), array( 'status' => 403 ) );
			}

			// since success, we response with next noonce.
			header( 'X-WP-Nonce: ' . wp_create_nonce( 'wp_rest' ) );

			return true;
		}
	}
}
