<?php
declare( strict_types=1 );

namespace FiboFilters\API;

use FiboFilters\Config\Env;
use FiboFilters\Settings\Settings as PluginSettings;
use WP_REST_Server;

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

/**
 * Class API
 */
class API {
	/** @var Filters */
	private $filters;

	/** @var Index */
	private $index;

	/** @var PluginSettings */
	private $plugin_settings;

	/** @var Settings */
	private $settings;

	/** @var SettingsController */
	private $settings_controller;

	/** @var Troubleshooting */
	private $troubleshooting;

	/** @var SEORules */
	private $seo_rules;

	public function __construct( Filters $filters, Index $index, PluginSettings $plugin_settings, Settings $settings, SettingsController $settings_controller, Troubleshooting $troubleshooting, SEORules $seo_rules ) {
		$this->filters             = $filters;
		$this->index               = $index;
		$this->plugin_settings     = $plugin_settings;
		$this->settings            = $settings;
		$this->settings_controller = $settings_controller;
		$this->troubleshooting     = $troubleshooting;
		$this->seo_rules           = $seo_rules;
	}

	public function init(): void {
		/**
		 * Skip API initialization in WP-CLI context
		 *
		 * This is to prevent unnecessary loading of settings in CLI commands,
		 * specifically when running `wp eval "do_action('fibofilters/install/maybe_install_without_reindexing');"`
		 * during plugin testing.
		 */
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
			return;
		}

		$this->register_routes();

		$this->plugin_settings->ensure_loaded();
		$this->settings_controller->register_routes();
	}

	private function register_routes(): void {
		$minimum_capability = apply_filters( 'fibofilters/shop_manager_has_access', false ) ? 'manage_woocommerce' : 'manage_options';

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/index/status',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->index, 'status' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/index/cancel',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->index, 'cancel' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/index/build',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->index, 'build' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/settings/fields',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->settings, 'get_fields' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/settings/sources',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->settings, 'get_sources' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/settings/disable-source-analyzer',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->settings, 'disable_source_analyzer' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/settings/finish-onboarding',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->settings, 'finish_onboarding' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/filters/descriptors',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->filters, 'descriptors' ],
				'permission_callback' => '__return_true',
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/filters/updated-descriptors',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->filters, 'updated_descriptors' ],
				'permission_callback' => '__return_true',
				'args'                => [
					'date_start' => [
						'required' => false,
						'type'     => 'string',
						'format'   => 'date-time',
						'default'  => '1970-01-01 00:00:02',
					],
					'date_end'   => [
						'required' => true,
						'type'     => 'string',
						'format'   => 'date-time',
					],
				],
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/troubleshooting/test',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->troubleshooting, 'test' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
				'args'                => [
					'test' => [
						'required' => true,
						'type'     => 'string',
					],
					'type' => [
						'required' => false,
						'type'     => 'string',
						'default'  => 'async',
						'enum'     => [ 'async', 'direct' ],
					],
				],
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/troubleshooting/save-test-result',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->troubleshooting, 'save_test_result' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
				'args'                => [
					'test_result' => [
						'required' => true,
						'type'     => 'object',
					],
				],
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/troubleshooting/action',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->troubleshooting, 'do_action' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
				'args'                => [
					'action' => [
						'required' => true,
						'type'     => 'string',
					],
					'args'   => [
						'required' => false,
						'type'     => 'object',
					],
				],
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/seo-rules/filter-values',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this->seo_rules, 'get_filter_values' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
				'args'                => [
					'filter' => [
						'required' => true,
						'type'     => 'string',
					],
				],
			]
		);

		register_rest_route(
			Env::$plugin_slug . '/v1',
			'/seo-rules/base-view-values',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this->seo_rules, 'get_base_view_values' ],
				'permission_callback' => function () use ( $minimum_capability ): bool {
					return current_user_can( $minimum_capability );
				},
			]
		);
	}
}
