<?php
/**
 * App-level REST endpoints.
 *
 * @package JOCBM
 */

namespace JOCBM\Rest;

use JOCBM\Database\Schema;
use JOCBM\Settings;
use JOCBM\Services\IconRegistry;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

defined( 'ABSPATH' ) || exit;

/**
 * Class AppController
 */
final class AppController {

	use RestPermissions;

	/**
	 * Register routes.
	 */
	public function register_routes(): void {
		register_rest_route(
			RestApi::NAMESPACE,
			'/welcome/dismiss',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'dismiss_welcome' ),
				'permission_callback' => array( $this, 'can_manage' ),
			)
		);

		register_rest_route(
			RestApi::NAMESPACE,
			'/dashboard',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'dashboard' ),
				'permission_callback' => array( $this, 'can_manage' ),
			)
		);

		register_rest_route(
			RestApi::NAMESPACE,
			'/system/reset-data',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'reset_data' ),
				'permission_callback' => array( $this, 'can_manage_options' ),
			)
		);

		register_rest_route(
			RestApi::NAMESPACE,
			'/system/settings',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_settings' ),
					'permission_callback' => array( $this, 'can_manage_options' ),
				),
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_settings' ),
					'permission_callback' => array( $this, 'can_manage_options' ),
				),
			)
		);

		register_rest_route(
			RestApi::NAMESPACE,
			'/system/icon-libraries/scan',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'scan_icon_stylesheet' ),
				'permission_callback' => array( $this, 'can_manage_options' ),
				'args'                => array(
					'stylesheetUrl' => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
					'classTemplate' => array(
						'type'              => 'string',
						'required'          => false,
						'default'           => 'fa-solid fa-{id}',
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);

		register_rest_route(
			RestApi::NAMESPACE,
			'/icons/svg',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_icon_svg' ),
				'permission_callback' => array( $this, 'can_manage' ),
				'args'                => array(
					'library' => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_key',
					),
					'id'      => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);
	}

	/**
	 * Resolve one inline SVG for the editor/admin icon picker (on demand).
	 *
	 * @param WP_REST_Request $request Request.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_icon_svg( WP_REST_Request $request ) {
		$library = (string) $request->get_param( 'library' );
		$icon_id = (string) $request->get_param( 'id' );
		$lib     = IconRegistry::get_library( $library );

		if ( ! $lib || empty( $lib['enabled'] ) || 'svg-inline' !== ( $lib['type'] ?? '' ) ) {
			return new WP_Error(
				'jocbm_icon_not_found',
				__( 'Icon library not available.', 'joc-blockora-morph' ),
				array( 'status' => 404 )
			);
		}

		$raw = IconRegistry::resolve_inline_svg( $library, $icon_id );
		if ( '' === $raw ) {
			return new WP_Error(
				'jocbm_icon_not_found',
				__( 'Icon not found.', 'joc-blockora-morph' ),
				array( 'status' => 404 )
			);
		}

		$html = IconRegistry::decorate_inline_svg( $raw, 'bm-icon bm-icon--svg', '' );

		return new WP_REST_Response(
			array(
				'library' => $library,
				'id'      => $icon_id,
				'svg'     => $html,
			),
			200
		);
	}

	/**
	 * Scan a font-icon stylesheet and return a catalog of icon ids.
	 *
	 * @param WP_REST_Request $request Request.
	 * @return WP_REST_Response|WP_Error
	 */
	public function scan_icon_stylesheet( WP_REST_Request $request ) {
		$result = IconRegistry::scan_stylesheet_catalog(
			(string) $request->get_param( 'stylesheetUrl' ),
			(string) $request->get_param( 'classTemplate' )
		);

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return new WP_REST_Response( $result, 200 );
	}

	/**
	 * Plugin system settings.
	 */
	public function get_settings(): WP_REST_Response {
		return new WP_REST_Response( Settings::get_system_settings(), 200 );
	}

	/**
	 * Update plugin system settings.
	 *
	 * @param WP_REST_Request $request Request.
	 */
	public function update_settings( WP_REST_Request $request ): WP_REST_Response {
		if ( null !== $request->get_param( 'frontendEditor' ) ) {
			Settings::set_frontend_editor_enabled(
				(bool) $request->get_param( 'frontendEditor' )
			);
		}

		if ( null !== $request->get_param( 'iconLibraries' ) ) {
			$libs = $request->get_param( 'iconLibraries' );
			if ( is_array( $libs ) ) {
				IconRegistry::save_libraries( $libs );
			}
		}

		return new WP_REST_Response( Settings::get_system_settings(), 200 );
	}

	/**
	 * Mark welcome as seen.
	 */
	public function dismiss_welcome(): WP_REST_Response {
		update_option( 'jocbm_welcome_seen', true );

		return new WP_REST_Response( array( 'success' => true ), 200 );
	}

	/**
	 * Dashboard summary counts.
	 */
	public function dashboard(): WP_REST_Response {
		global $wpdb;

		$system = $wpdb->prefix . 'blockora_morph_boc_system_blocks';
		$user   = $wpdb->prefix . 'blockora_morph_boc_user_blocks';
		$content = $wpdb->prefix . 'blockora_morph_boc_user_contents';
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Plugin tables from Schema::table().
		$cats   = $wpdb->prefix . 'blockora_morph_boc_categories';

		return new WP_REST_Response(
			array(
				'counts' => array(
					'categories'   => Schema::count_rows( 'categories' ),
					'systemBlocks' => Schema::count_rows( 'system_blocks' ),
					'userBlocks'   => Schema::count_rows( 'user_blocks' ),
					'userContents' => Schema::count_rows( 'user_contents' ),
				),
			),
			200
		);
	}

	/**
	 * Wipe all Blockora Morph data and re-seed the library.
	 *
	 * @param WP_REST_Request $request Request.
	 * @return WP_REST_Response|WP_Error
	 */
	public function reset_data( WP_REST_Request $request ) {
		$confirm = sanitize_text_field( (string) $request->get_param( 'confirm' ) );
		if ( 'DELETE' !== $confirm ) {
			return new WP_Error(
				'jocbm_confirm_required',
				__( 'Type DELETE to confirm wiping all Blockora Morph data.', 'joc-blockora-morph' ),
				array( 'status' => 400 )
			);
		}

		$result = Schema::reset_all_data();
		$counts = $result['counts'] ?? $result;

		return new WP_REST_Response(
			array(
				'success'     => true,
				'welcomeSeen' => false,
				'removed'     => array(
					'categories'   => $counts['categories'] ?? 0,
					'systemBlocks' => $counts['system_blocks'] ?? 0,
					'userBlocks'   => $counts['user_blocks'] ?? 0,
					'userContents' => $counts['user_contents'] ?? 0,
				),
				'themeConfig' => $result['themeConfig'] ?? \JOCBM\Rest\ThemeConfigController::get_config_with_fonts(),
				'message'     => __(
					'All Blockora Morph data was deleted. Global settings were restored to defaults and the block library has been re-seeded.',
					'joc-blockora-morph'
				),
			),
			200
		);
	}
}
