<?php

namespace Fotogenic_AI;

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

final class Rest_Router {
	private static ?Rest_Router $instance = null;

	/** @var object[] */
	private array $handlers;

	/**
	 * @param object[] $handlers Route handlers exposing register_routes().
	 */
	private function __construct( array $handlers ) {
		$this->handlers = $handlers;
	}

	/**
	 * @param object[] $handlers Route handlers exposing register_routes().
	 */
	public static function instance( array $handlers ): Rest_Router {
		if ( null === self::$instance ) {
			self::$instance = new self( $handlers );
		}

		return self::$instance;
	}

	public function register_routes(): void {
		foreach ( $this->handlers as $handler ) {
			$handler->register_routes( $this );
		}
	}

	public function register_route( string $namespace, string $route, array $args ): void {
		register_rest_route( $namespace, $route, $args );
	}

	public function permissions_admin( \WP_REST_Request $request ) {
		$nonce_error = $this->check_rest_nonce( $request );
		if ( is_wp_error( $nonce_error ) ) {
			return $nonce_error;
		}

		return $this->user_has_plugin_cap();
	}

	public function permissions_generate( \WP_REST_Request $request ) {
		$nonce_error = $this->check_rest_nonce( $request );
		if ( is_wp_error( $nonce_error ) ) {
			return $nonce_error;
		}

		return $this->user_has_plugin_cap();
	}

	public function permissions_generate_upload( \WP_REST_Request $request ) {
		$nonce_error = $this->check_rest_nonce( $request );
		if ( is_wp_error( $nonce_error ) ) {
			return $nonce_error;
		}

		return $this->user_has_plugin_cap( true );
	}

	private function user_has_plugin_cap( bool $require_upload = false ): bool {
		if ( ! fotogenic_ai_user_can_access() ) {
			return false;
		}
		if ( $require_upload && ! current_user_can( 'upload_files' ) ) {
			return false;
		}

		return true;
	}

	private function check_rest_nonce( \WP_REST_Request $request ) {
		$nonce = sanitize_text_field( (string) $request->get_header( 'X-WP-Nonce' ) );
		$nonce = trim( $nonce );
		if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return Messages::error( 'invalid_nonce', 403 );
		}

		return true;
	}
}
