<?php
/**
 * Matador / REST API / Jobs Namespace / Taxonomies Endpoint
 *
 * @link        https://matadorjobs.com/
 * @since       3.9.0
 *
 * @package     Matador Jobs Board
 * @subpackage  REST API
 * @author      Matador Software LLC, Jeremy Scott, Paul Bearne
 * @copyright   (c) 2024, Matador Software, LLC
 *
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 */

namespace matador\MatadorJobs\Rest\Endpoint\Jobs;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

use matador\Matador;
use matador\Job_Taxonomies;
use matador\MatadorJobs\Rest\Endpoint\EndpointAbstract;
use matador\MatadorJobs\Core\Logger;
use matador\MatadorJobs\Core\Severity;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Job Taxonomies Endpoint Class
 *
 * @since 3.9.0
 */
class Taxonomies extends EndpointAbstract {

	/**
	 * Class Name
	 *
	 * @var string
	 *
	 * @since 3.9.0
	 */
	protected static $class = __CLASS__;

	/**
	 * Routes
	 *
	 * Called in a WordPress rest_api_init action to add the routes.
	 *
	 * @since 3.9.0
	 *
	 * @return void
	 */
	public static function routes(): void {

		// INDEX
		register_rest_route( self::rest_namespace(), '/jobs/taxonomies', [
			'methods' => WP_REST_Server::READABLE,
			'callback' => [ __CLASS__, 'index' ],
			'permission_callback' => '__return_true',
		] );

		// SHOW
		// @todo 3.9.0 possible issue with internationalized URLs
		register_rest_route( self::rest_namespace(), '/jobs/taxonomies/(?P<taxonomy>[a-zA-Z0-9-_^/]+)', [
			'methods' => WP_REST_Server::READABLE,
			'callback' => [ __CLASS__, 'show' ],
			'permission_callback' => '__return_true',
		] );
	}

	/**
	 * Index
	 *
	 * Returns a list of Taxonomies for the Matador Jobs post type.
	 *
	 * @since 3.9.0
	 *
	 * @param WP_REST_Request $request
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public static function index( WP_REST_Request $request ): WP_REST_Response|WP_Error {

		$taxonomies = Job_Taxonomies::taxonomies_list();

		if ( ! empty( $taxonomies ) ) {

			foreach ( $taxonomies as $name => $taxonomy ) {
				unset( $taxonomies[ $name ]['args'] );
			}

			return new WP_REST_Response( $taxonomies, 200 );
		}

		$code    = 'rest-job-taxonomies-retrieval-error';
		$message = __( 'Failed to retrieve taxonomies for the job post type.', 'matador-jobs' );

		Logger::entry( $code, $message, Severity::ERROR );

		return new WP_Error(
			$code,
			$message,
			[ 'status' => 500 ]
		);
	}

	/**
	 * Show
	 *
	 * Returns details for the requested Taxonomy for the Matador Jobs post type.
	 *
	 * @since 3.9.0
	 *
	 * @param WP_REST_Request $request
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public static function show( WP_REST_Request $request ): WP_REST_Response|WP_Error {

		$taxonomies = Job_Taxonomies::taxonomies_list();

		if ( empty( $taxonomies ) ) {

			$code    = 'rest-job-taxonomy-retrieval-error';
			$message = __( 'Failed to retrieve taxonomy for the job post type due to internal error.', 'matador-jobs' );

			Logger::entry( $code, $message, Severity::ERROR );

			return new WP_Error(
				$code,
				$message,
				[ 'status' => 500 ]
			);
		}

		$taxonomy = sanitize_title( $request->get_param( 'taxonomy' ) );

		if ( array_key_exists( $taxonomy, $taxonomies ) ) {

			$taxonomy = $taxonomies[ $taxonomy ];

		} else {

			$found = false;

			foreach ( $taxonomies as $taxonomy_args ) {
				if ( $taxonomy === $taxonomy_args['key'] ) {

					$taxonomy = $taxonomy_args;
					$found    = true;
					break;
				}

				if ( $taxonomy === $taxonomy_args['plural'] ) {

					$taxonomy = $taxonomy_args;
					$found    = true;
					break;
				}
			}

			if ( ! $found ) {
				$code    = 'rest-job-taxonomy-not-found';
				$message = __( 'Taxonomy for the job post type not found.', 'matador-jobs' );

				return new WP_Error(
					$code,
					$message,
					[ 'status' => 404 ]
				);
			}
		}

		unset( $taxonomy['args'] );

		// @todo 3.9.0 Add the URL for the Taxonomy, which can vary between a taxonomy archive or a search results page

		return new WP_REST_Response( $taxonomy, 200 );
	}
}
