<?php
defined( 'ABSPATH' ) || exit;

class BW_WebP_Rest {

	const NAMESPACE = 'bw-webp/v1';

	private BW_WebP_Manifest $manifest;
	private BW_WebP_Settings $settings;
	private BW_WebP_Queue $queue;

	public function __construct( BW_WebP_Manifest $manifest, BW_WebP_Settings $settings, BW_WebP_Queue $queue ) {
		$this->manifest = $manifest;
		$this->settings = $settings;
		$this->queue    = $queue;
	}

	public function register_hooks(): void {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	public function register_routes(): void {
		$cap = array( $this, 'cap_check' );

		register_rest_route( self::NAMESPACE, '/status',   array( 'methods' => 'GET',  'callback' => array( $this, 'status' ),   'permission_callback' => $cap ) );
		register_rest_route( self::NAMESPACE, '/scan',     array( 'methods' => 'POST', 'callback' => array( $this, 'scan' ),     'permission_callback' => $cap ) );
		register_rest_route( self::NAMESPACE, '/convert',  array( 'methods' => 'POST', 'callback' => array( $this, 'convert' ),  'permission_callback' => $cap ) );
		register_rest_route( self::NAMESPACE, '/progress', array( 'methods' => 'GET',  'callback' => array( $this, 'progress' ), 'permission_callback' => $cap ) );
		register_rest_route( self::NAMESPACE, '/clear',    array( 'methods' => 'POST', 'callback' => array( $this, 'clear' ),    'permission_callback' => $cap ) );
	}

	public function cap_check(): bool {
		return current_user_can( 'manage_options' );
	}

	public function status(): WP_REST_Response {
		try {
			$converter = BW_WebP_Converter_Factory::detect( $this->settings->get()['converter'] )->name();
		} catch ( Throwable $e ) {
			$converter = null;
		}

		return rest_ensure_response( array(
			'converter' => $converter,
			'available' => BW_WebP_Converter_Factory::available(),
			'counts'    => $this->manifest->counts(),
			'settings'  => $this->settings->get(),
		) );
	}

	public function scan(): WP_REST_Response {
		$pending = $this->queue->scan();
		return rest_ensure_response( array( 'pending' => $pending, 'counts' => $this->manifest->counts() ) );
	}

	public function convert( WP_REST_Request $req ): WP_REST_Response {
		$workers = $req->get_param( 'workers' );
		$workers = ( null !== $workers ) ? max( 1, min( 8, (int) $workers ) ) : null;

		$this->queue->scan();
		$started = $this->queue->enqueue_bulk( $workers );

		return rest_ensure_response( array( 'started_workers' => $started, 'counts' => $this->manifest->counts() ) );
	}

	public function progress(): WP_REST_Response {
		return rest_ensure_response( array( 'counts' => $this->manifest->counts() ) );
	}

	public function clear(): WP_REST_Response {
		$this->manifest->clear();
		return rest_ensure_response( array( 'ok' => true, 'counts' => $this->manifest->counts() ) );
	}
}
