<?php
/**
 * HFE Settings API.
 *
 * @package HFE
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use HFE\WidgetsManager\Base\HFE_Helper;

/**
 * Class HFE_Settings_Api.
 */
class HFE_Settings_Api {

	/**
	 * Instance.
	 *
	 * @access private
	 * @var object Class object.
	 * @since 2.2.1
	 */
	private static $instance;

	/**
	 * Get the singleton instance of the class.
	 *
	 * @return HFE_Settings_Api
	 */
	public static function get_instance() {
		if ( ! isset( self::$instance ) ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 2.2.1
	 * @return void
	 */
	private function __construct() {
		// Log an error message to check if the file is loading.

		add_action( 'rest_api_init', [ $this, 'register_routes' ] );
	}

	/**
	 * Register REST API routes.
	 *
	 * @since 2.2.1
	 * @return void
	 */
	public function register_routes() {

		register_rest_route(
			'hfe/v1',
			'/widgets',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_hfe_widgets' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/plugins',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_plugins_list' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/templates',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_templates_status' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/email-webhook',
			[
				'methods'             => 'POST',
				'callback'            => [ $this, 'send_email_to_webhook_api' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/recommended-plugins',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_recommended_plugins_list' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/mcp-abilities',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'get_mcp_abilities' ],
				'permission_callback' => [ $this, 'get_items_permissions_check' ],
			]
		);

		register_rest_route(
			'hfe/v1',
			'/mcp-settings',
			[
				[
					'methods'             => 'GET',
					'callback'            => [ $this, 'get_mcp_settings' ],
					'permission_callback' => [ $this, 'get_items_permissions_check' ],
				],
				[
					'methods'             => 'POST',
					'callback'            => [ $this, 'update_mcp_settings' ],
					'permission_callback' => [ $this, 'get_items_permissions_check' ],
				],
			]
		);
	}

	/**
	 * Check whether a given request has permission to read notes.
	 *
	 * @since 2.2.1
	 * @return WP_Error|boolean
	 */
	public function get_items_permissions_check() {

		if ( ! current_user_can( 'manage_options' ) ) {
			return new \WP_Error( 'uae_rest_not_allowed', __( 'Sorry, you are not authorized to perform this action.', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		return true;
	}

	/**
	 * Get Starter Templates Status.
	 * 
	 * @param WP_REST_Request $request Request object.
	 */
	public function get_templates_status( WP_REST_Request $request ) {
		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		$templates_status = HFE_Helper::starter_templates_status();

		$response_data = [
			'templates_status' => $templates_status,
		];
	
		if ( 'Activated' === $templates_status ) {
			$response_data['redirect_url'] = HFE_Helper::starter_templates_link();
		}

		return new WP_REST_Response( $response_data, 200 );
	}

	/**
	 * Callback function to return plugins list.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function get_plugins_list( $request ) {

		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		// Fetch branding settings.
		$plugins_list = HFE_Helper::get_bsf_plugins_list();

		if ( ! is_array( $plugins_list ) ) {
			return new WP_REST_Response( [ 'message' => __( 'Plugins list not found', 'header-footer-elementor' ) ], 404 );
		}

		return new WP_REST_Response( $plugins_list, 200 );
		
	}

	/**
	 * 
	 * Callback function to return recommended plugins list.
	 * 
	 * @param WP_REST_Request $request Request object.
	 *
	 * @return WP_REST_Response
	 */
	public function get_recommended_plugins_list( $request ) {

		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		// Fetch recommended plugins list.
		$recommended_plugins_list = HFE_Helper::get_recommended_bsf_plugins_list();

		if ( ! is_array( $recommended_plugins_list ) ) {
			return new WP_REST_Response( [ 'message' => __( 'Recommended plugins list not found', 'header-footer-elementor' ) ], 404 );
		}

		return new WP_REST_Response( $recommended_plugins_list, 200 );
		
	}

	/**
	 * 
	 * Callback function to return widgets list.
	 * 
	 * @param WP_REST_Request $request Request object.
	 *
	 * @return WP_REST_Response
	 */
	public function get_hfe_widgets( $request ) {

		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		// Fetch widgets settings.
		$widgets_list = HFE_Helper::get_all_widgets_list();

		if ( ! is_array( $widgets_list ) ) {
			return new WP_REST_Response( [ 'message' => __( 'Widgets list not found', 'header-footer-elementor' ) ], 404 );
		}

		return new WP_REST_Response( $widgets_list, 200 );
		
	}

	/**
	 * Get the API URL.
	 *
	 * @since 2.3.1
	 * @return string
	 */
	public function get_api_domain() {
		return apply_filters( 'hfe_api_domain', 'https://websitedemos.net/' );
	}

	/**
	 * Send Email to Webhook.
	 * @param WP_REST_Request $request Request object.
	 * 
	 */
	public function send_email_to_webhook_api( WP_REST_Request $request ) {
		$nonce = $request->get_header( 'X-WP-Nonce' );
		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		$email = sanitize_email( $request->get_param( 'email' ) );
		$date  = sanitize_text_field( $request->get_param( 'date' ) );
		$fname  = sanitize_text_field( $request->get_param( 'fname' ) );
		$lname  = sanitize_text_field( $request->get_param( 'lname' ) );
		$isActive = sanitize_text_field( $request->get_param( 'isActive' ) );
		$domain = sanitize_text_field( $request->get_param( 'domain' ) );

		if ( ! empty( $domain ) && false === filter_var( $domain, FILTER_VALIDATE_URL ) ) {
			return new WP_Error( 'invalid_domain', __( 'Invalid domain provided.', 'header-footer-elementor' ), [ 'status' => 400 ] );
		}
		
		$api_domain = trailingslashit( $this->get_api_domain() );
		$api_domain_url = $api_domain . 'wp-json/uaelite/v1/subscribe/';
		$validation_url = esc_url_raw( get_site_url() . '/wp-json/hfe/v1/email-response/' );

		// Append session_id to track requests.
		$body = array(
			'email'          => $email,
			'date'           => $date,
			'fname'          => $fname,
			'lname'          => $lname,
			'isActive'       => $isActive,
			'domain'         => $domain
		);

		$args = array(
			'body'    => $body,
			'timeout' => 30,
		);

		$response = wp_remote_post( $api_domain_url, $args );

		if ( is_wp_error( $response ) ) {
			return new WP_Error( 'webhook_error', __( 'Error calling endpoint', 'header-footer-elementor' ), [ 'status' => 500 ] );
		}

		$response_code = wp_remote_retrieve_response_code( $response );
		$response_body = json_decode( wp_remote_retrieve_body( $response ), true );

		if ( ! in_array( $response_code, [ 200, 201, 204 ], true ) ) {
			error_log( 'HFE webhook API error: ' . ( isset( $response_body['message'] ) ? sanitize_text_field( $response_body['message'] ) : 'Unknown error' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			return new WP_Error( 'webhook_error', __( 'Failed to send email. Please try again later.', 'header-footer-elementor' ), [ 'status' => $response_code ] );
		}

		update_option( 'uaelite_subscription', 'done' );

		return new WP_REST_Response(
			[
				'message'    => 'success'
			],
			200
		);
	}
	
	/**
	 * Get all MCP abilities for the settings UI.
	 *
	 * Returns the ability list with metadata, grouped by namespace,
	 * for the ability toggles section.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function get_mcp_abilities( WP_REST_Request $request ) {
		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		// Get abilities from registry if available.
		$loader = class_exists( 'HFE_Abilities_Loader' ) ? HFE_Abilities_Loader::instance() : null;

		if ( ! $loader || ! method_exists( $loader, 'get_registry' ) ) {
			return new WP_REST_Response( [], 200 );
		}

		// Ensure handlers are populated — wp_abilities_api_init may not have fired yet.
		$loader->ensure_handlers_loaded();

		$registry  = $loader->get_registry();
		$abilities = $registry->get_abilities_info();
		$settings  = get_option( 'uae_mcp_settings', [] );
		$disabled  = ! empty( $settings['disabled_abilities'] ) && is_array( $settings['disabled_abilities'] )
			? $settings['disabled_abilities']
			: [];

		// Add is_enabled flag based on disabled_abilities setting.
		foreach ( $abilities as &$ability ) {
			$ability['is_enabled'] = ! in_array( $ability['name'], $disabled, true )
				&& ! in_array( $ability['full_name'], $disabled, true );
		}
		unset( $ability );

		return new WP_REST_Response( $abilities, 200 );
	}

	/**
	 * Default MCP settings.
	 *
	 * @return array
	 */
	public static function get_mcp_settings_defaults() {
		return [
			'enable_abilities'    => false,
			'allow_modifications' => true,
			'dedicated_server'    => false,
			'angie_enabled'       => false,
			'disabled_abilities'  => [],
		];
	}

	/**
	 * Get MCP settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function get_mcp_settings( WP_REST_Request $request ) {
		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		$defaults = self::get_mcp_settings_defaults();
		$settings = get_option( 'uae_mcp_settings', [] );
		$settings = wp_parse_args( $settings, $defaults );

		// Add computed fields for the UI.
		$settings['is_abilities_api_active'] = function_exists( 'wp_register_ability' );
		$settings['is_mcp_adapter_active']   = class_exists( '\WP\MCP\Core\McpAdapter' );
		$settings['is_angie_active']         = defined( 'ANGIE_VERSION' ) || ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'angie/angie.php' ) );
		$settings['dedicated_server_url']  = rest_url( 'uae/mcp' );
		$settings['total_abilities']       = $this->count_hfe_abilities();

		return new WP_REST_Response( $settings, 200 );
	}

	/**
	 * Update MCP settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_mcp_settings( WP_REST_Request $request ) {
		$nonce = $request->get_header( 'X-WP-Nonce' );

		if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
			return new WP_Error( 'invalid_nonce', __( 'Invalid nonce', 'header-footer-elementor' ), [ 'status' => 403 ] );
		}

		$defaults      = self::get_mcp_settings_defaults();
		$current       = get_option( 'uae_mcp_settings', [] );
		$current       = wp_parse_args( $current, $defaults );
		$allowed_keys  = array_keys( $defaults );
		$params        = $request->get_json_params();

		if ( ! is_array( $params ) ) {
			return new WP_Error( 'invalid_params', __( 'Invalid parameters.', 'header-footer-elementor' ), [ 'status' => 400 ] );
		}

		foreach ( $allowed_keys as $key ) {
			if ( ! isset( $params[ $key ] ) ) {
				continue;
			}

			if ( 'disabled_abilities' === $key ) {
				// Sanitize as array of strings.
				$current[ $key ] = is_array( $params[ $key ] )
					? array_values( array_map( 'sanitize_text_field', $params[ $key ] ) )
					: [];
			} else {
				$current[ $key ] = (bool) $params[ $key ];
			}
		}

		update_option( 'uae_mcp_settings', $current );

		return new WP_REST_Response(
			[
				'success'  => true,
				'settings' => $current,
			],
			200
		);
	}

	/**
	 * Count registered HFE abilities.
	 *
	 * @return int
	 */
	private function count_hfe_abilities() {
		if ( ! function_exists( 'wp_get_abilities' ) ) {
			return 0;
		}

		$all_abilities = wp_get_abilities();
		$count         = 0;

		$prefix = class_exists( 'HFE_Ability_Registry' ) ? HFE_Ability_Registry::PREFIX : 'uae/';

		foreach ( $all_abilities as $ability_name => $ability ) {
			if ( 0 === strpos( $ability_name, $prefix ) ) {
				++$count;
			}
		}

		return $count;
	}
}

// Initialize the HFE_Settings_Api class.
HFE_Settings_Api::get_instance();
