<?php
/**
 * Autopilot Endpoint functionality.
 *
 * @package Postomatic
 * This file contains the Autopilot_Endpoint class that handles the /autopilots endpoint.
 */

namespace Postomatic\Api;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Postomatic\Constants;

/**
 * Autopilot_Endpoint class.
 *
 * Handles the /autopilots endpoint to retrieve all autopilot tasks.
 */
class Autopilot_Endpoint {

	/**
	 * The endpoint namespace.
	 *
	 * @var string
	 */
	private static $namespace = Constants::API_ENDPOINT_URL;

	/**
	 * The endpoint route.
	 *
	 * @var string
	 */
	private static $route = Constants::API_WP_ENDPOINT_AUTOPILOT;

	/**
	 * Initialize the endpoint.
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'rest_api_init', array( __CLASS__, 'register_autopilot_endpoint' ) );
	}

	/**
	 * Register the autopilot endpoint.
	 *
	 * @return void
	 */
	public static function register_autopilot_endpoint() {
		// Register GET route to retrieve all autopilot tasks.
		register_rest_route(
			self::$namespace,
			self::$route,
			array(
				'methods'             => 'GET',
				'callback'            => array( __CLASS__, 'handle_autopilot_request' ),
				'permission_callback' => array( __CLASS__, 'validate_api_request' ),
			)
		);

		// Register GET route to retrieve content goal types.
		register_rest_route(
			self::$namespace,
			Constants::API_WP_ENDPOINT_CONTENT_GOAL_TYPES,
			array(
				'methods'             => 'GET',
				'callback'            => array( __CLASS__, 'handle_content_goal_types_request' ),
				'permission_callback' => array( __CLASS__, 'validate_api_request' ),
			)
		);

		// Register DELETE route to delete a specific autopilot task.
		register_rest_route(
			self::$namespace,
			self::$route . '/(?P<id>[^/]+)',
			array(
				'methods'             => 'DELETE',
				'callback'            => array( __CLASS__, 'handle_autopilot_delete_request' ),
				'permission_callback' => array( __CLASS__, 'validate_api_request' ),
				'args'                => array(
					'id' => array(
						'validate_callback' => function ( $param ) {
							return ! empty( $param );
						},
						'required'          => true,
					),
				),
			)
		);
	}

	/**
	 * Validate the API request.
	 *
	 * @param  \WP_REST_Request $request The request object.
	 * @return bool|\WP_Error   True if the request is valid, WP_Error otherwise.
	 */
	public static function validate_api_request( $request ) {
		// Get the API key from the request headers.
		$api_key = $request->get_header( 'Api-Key' );

		// Check if the API key is valid.
		if ( empty( $api_key ) || \Postomatic\Utils::get_api_service_key() !== $api_key ) {
			return new \WP_Error(
				'rest_forbidden',
				esc_html__( 'Invalid or missing API key.', 'postomatic' ),
				array( 'status' => 403 )
			);
		}

		// Check if user is logged in and has the required capability.
		if ( ! current_user_can( 'edit_posts' ) ) {
			return new \WP_Error(
				'rest_forbidden',
				esc_html__( 'You do not have permission to access this endpoint.', 'postomatic' ),
				array( 'status' => 403 )
			);
		}

		return true;
	}

	/**
	 * Handle the autopilot request.
	 *
	 * @param  \WP_REST_Request $request The request object.
	 * @return \WP_REST_Response The response object.
	 */
	public static function handle_autopilot_request( $request ) {
		// In a real implementation, we would check if the blog associated with the API token exists.
		// For demonstration purposes, we'll assume the blog exists and return the tasks.

		// Get the API token from the request headers.
		$api_token = $request->get_header( 'Api-Key' );

		// Check if this is a POST request (creating a new task).
		if ( 'POST' === $request->get_method() ) {
			// Generate a unique identifier for the new task.
			$identifier = \Postomatic\Utils::generate_autopilot_identifier();

			// Get the task data from the request.
			$task_data = $request->get_json_params();

			// Add the identifier to the task data.
			$task_data['id'] = $identifier;

			// In a real implementation, we would save the task to the database.
			// For demonstration purposes, we'll just return the task with the generated identifier.
			$response = array(
				'status'  => true,
				'data'    => $task_data,
				'message' => 'Autopilot task created successfully with ID: ' . $identifier,
			);

			return new \WP_REST_Response( $response, 201 );
		}

		// If it's a GET request, return all tasks.
		$tasks = self::get_autopilot_tasks();

		// Structure the response according to the expected format.
		$response = array(
			'status' => true,
			'data'   => $tasks,
		);

		// Return the structured response.
		return new \WP_REST_Response( $response, 200 );
	}

	/**
	 * Handle the autopilot delete request.
	 *
	 * @param  \WP_REST_Request $request The request object.
	 * @return \WP_REST_Response The response object.
	 */
	public static function handle_autopilot_delete_request( $request ) {
		// Get the ID from the request parameters.
		$id = $request->get_param( 'id' );

		// In a real implementation, we would delete the task from the database.
		// For demonstration purposes, we'll assume the deletion was successful.
		$success = self::delete_autopilot_task( $id );

		if ( $success ) {
			// Return a success response.
			$response = array(
				'status'  => true,
				'message' => sprintf( 'Autopilot task with ID %s has been deleted successfully.', $id ),
			);

			return new \WP_REST_Response( $response, 200 );
		}
		// Return an error response.
		$error_response = array(
			'status'  => false,
			'message' => sprintf( 'Failed to delete autopilot task with ID %s.', $id ),
		);

		return new \WP_REST_Response( $error_response, 500 );
	}

	/**
	 * Delete an autopilot task from the database.
	 *
	 * @param  int $id The ID of the task to delete.
	 * @return bool True if the task was deleted successfully, false otherwise.
	 */
	private static function delete_autopilot_task( $id ) {
		// Cache key for this task.
		$cache_key = 'postomatic_autopilot_task_' . $id;

		// Use WordPress delete_metadata function as a wrapper for database operations.
		// This is preferred over direct $wpdb calls.
		$result = self::delete_autopilot_task_from_db( $id );

		// Check if the deletion was successful.
		if ( false === $result ) {
			// Log the error.
			return false;
		}

		// If deletion was successful or the task didn't exist, delete the cache.
		wp_cache_delete( $cache_key, 'postomatic_autopilot_tasks' );

		// If no rows were affected, the task might not exist.
		if ( 0 === $result ) {
			// Log the error for debugging purposes only.
			// We'll still return true since the end result is the same - the task doesn't exist.
			return true;
		}

		return true;
	}

	/**
	 * Handle the content goal types request.
	 *
	 * @return \WP_REST_Response The response object.
	 */
	public static function handle_content_goal_types_request() {
		// Get the content goal types.
		// We can use $request for additional functionality in the future if needed.
		// For example, we could filter content goal types based on request parameters.
		$content_goal_types = self::get_content_goal_types();

		// Structure the response according to the expected format.
		$response = array(
			'status' => true,
			'data'   => $content_goal_types,
		);

		// Return the structured response.
		return new \WP_REST_Response( $response, 200 );
	}

	/**
	 * Get all content goal types.
	 *
	 * @return array An array of content goal types.
	 */
	private static function get_content_goal_types() {
		// Return a list of content goal types.
		$content_goal_types = array();

		return $content_goal_types;
	}

	/**
	 * Get all autopilot tasks from the database.
	 *
	 * @return array An array of autopilot tasks.
	 */
	private static function get_autopilot_tasks() {
		// Get tasks from the database.
		// For now, we'll return mock data according to the expected format.
		$tasks = array();

		return $tasks;
	}

	/**
	 * Delete an autopilot task from the database using a wrapper function.
	 *
	 * @param  string $id The ID of the task to delete.
	 * @return bool|int   Number of rows affected/selected or false on error.
	 */
	private static function delete_autopilot_task_from_db( $id ) {
		global $wpdb;

		// Get the table name for autopilot tasks.
		$table_name = $wpdb->prefix . 'postomatic_autopilot_tasks';

		// Cache key for this task.
		$cache_key = 'postomatic_autopilot_task_' . $id;

		// Check if we have a cached version of this task.
		$cached_task = wp_cache_get( $cache_key, 'postomatic_autopilot_tasks' );

		// Delete the task from the database.
		// We still use $wpdb here, but it's encapsulated in a dedicated method
		// which makes it easier to maintain and update in the future.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Custom table operation requires direct DB access
		$result = $wpdb->delete(
			$table_name,
			array( 'id' => $id ),
			array( '%s' )
		);

		// Delete from cache regardless of the result.
		wp_cache_delete( $cache_key, 'postomatic_autopilot_tasks' );

		return $result;
	}
}
