<?php
/**
 * Abstract API Endpoint Class
 *
 * Provides a base implementation for REST API endpoints.
 *
 * @package RedFoxWP\RedFoxTabManager
 * @since 1.0.0
 */

namespace RedFoxWP\RedFoxTabManager\Abstracts;

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

/**
 * Abstract API Endpoint class
 *
 * This class provides a standard base implementation for REST API endpoints
 * with common functionality like permission checking and response formatting.
 *
 * @abstract
 * @since 1.0.0
 */
abstract class Abstract_API_Endpoint {

	/**
	 * API namespace for all REST endpoints.
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 *
	 * @var string
	 */
	const NAMESPACE = 'redfox-tab-manager/v1';

	/**
	 * Register the API routes for this endpoint
	 *
	 * @since 1.0.0
	 * @access public
	 * @abstract
	 *
	 * @return void
	 */
	abstract public function register_routes();

	/**
	 * Get the route base for this endpoint
	 *
	 * @since 1.0.0
	 * @access public
	 * @abstract
	 *
	 * @return string The route base (e.g., 'products', 'tabs')
	 */
	abstract public function get_route_base();

	/**
	 * Check permissions for API requests
	 *
	 * Default implementation requires edit_posts capability.
	 * Override in child classes for custom permission logic.
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param \WP_REST_Request $request Request object (required for WordPress REST API interface compatibility).
	 * @return bool|\WP_Error
	 */
	public function check_permissions( $request ) {
		// Note: $request parameter required for WordPress REST API interface compatibility.
		unset( $request );

		// Check if user can edit posts.
		if ( ! current_user_can( 'edit_posts' ) ) {
			return new \WP_Error(
				'rest_forbidden',
				__( 'You do not have permission to access this resource.', 'redfox-tab-manager' ),
				array( 'status' => 403 )
			);
		}

		return true;
	}

	/**
	 * Validate numeric parameter
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param mixed $param Parameter value.
	 * @return bool
	 */
	public function validate_numeric( $param ) {
		return is_numeric( $param );
	}

	/**
	 * Validate non-empty parameter
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param mixed $param Parameter value.
	 * @return bool
	 */
	public function validate_non_empty( $param ) {
		return ! empty( $param );
	}

	/**
	 * Sanitize integer parameter
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param mixed $param Parameter value.
	 * @return int
	 */
	public function sanitize_int( $param ) {
		return absint( $param );
	}

	/**
	 * Validate content length
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param mixed $param Parameter value.
	 * @param int   $max_length Optional. Maximum allowed length. Default 50000.
	 * @return bool
	 */
	public function validate_content_length( $param, $max_length = 50000 ) {
		if ( ! is_string( $param ) ) {
			return false;
		}

		return strlen( $param ) <= $max_length;
	}

	/**
	 * Create a success response
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param mixed  $data Response data.
	 * @param string $message Optional success message.
	 * @param int    $status HTTP status code.
	 * @param array  $additional_data Optional additional data to include in response.
	 * @return \WP_REST_Response
	 */
	public function success_response( $data = null, $message = '', $status = 200, $additional_data = array() ) {
		$response_data = array(
			'success' => true,
		);

		if ( ! empty( $message ) ) {
			$response_data['message'] = $message;
		}

		if ( null !== $data ) {
			$response_data['data'] = $data;
		}

		// Merge any additional data into the response.
		if ( ! empty( $additional_data ) && is_array( $additional_data ) ) {
			$response_data = array_merge( $response_data, $additional_data );
		}

		$response = rest_ensure_response( $response_data );
		$response->set_status( $status );
		return $response;
	}

	/**
	 * Create an error response
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param string $code Error code.
	 * @param string $message Error message.
	 * @param int    $status HTTP status code.
	 * @param mixed  $data Additional error data.
	 * @return \WP_Error
	 */
	public function error_response( $code, $message, $status = 400, $data = null ) {
		$error_data = array( 'status' => $status );

		if ( null !== $data ) {
			$error_data['data'] = $data;
		}

		return new \WP_Error( $code, $message, $error_data );
	}

	/**
	 * Get tab ID argument definition for REST API routes
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return array
	 */
	public function get_tab_id_arg() {
		return array(
			'type'              => 'integer',
			'required'          => true,
			'validate_callback' => array( $this, 'validate_numeric' ),
			'sanitize_callback' => array( $this, 'sanitize_int' ),
			'description'       => __( 'Tab ID.', 'redfox-tab-manager' ),
		);
	}
}
