<?php
/**
 * REST API endpoints.
 *
 * @package LoginPageCustomizerAndDesigner
 */

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

/**
 * Class LPCD_Rest_Api
 *
 * Registers REST routes under the lpcd/v1 namespace.
 */
class LPCD_Rest_Api {

	/**
	 * Namespace.
	 *
	 * @var string
	 */
	const NAMESPACE_V1 = 'lpcd/v1';

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	/**
	 * Register all REST routes.
	 */
	public function register_routes() {
		// Templates.
		register_rest_route(
			self::NAMESPACE_V1,
			'/templates',
			array(
				array(
					'methods'             => 'GET',
					'callback'            => array( $this, 'get_templates' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => 'POST',
					'callback'            => array( $this, 'create_template' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
			)
		);

		register_rest_route(
			self::NAMESPACE_V1,
			'/templates/(?P<id>\d+)',
			array(
				array(
					'methods'             => 'GET',
					'callback'            => array( $this, 'get_template' ),
					'permission_callback' => array( $this, 'check_permission' ),
					'args'                => array(
						'id' => array(
							'validate_callback' => function ( $param ) {
								return is_numeric( $param );
							},
						),
					),
				),
				array(
					'methods'             => 'PUT',
					'callback'            => array( $this, 'update_template' ),
					'permission_callback' => array( $this, 'check_permission' ),
					'args'                => array(
						'id' => array(
							'validate_callback' => function ( $param ) {
								return is_numeric( $param );
							},
						),
					),
				),
				array(
					'methods'             => 'DELETE',
					'callback'            => array( $this, 'delete_template' ),
					'permission_callback' => array( $this, 'check_permission' ),
					'args'                => array(
						'id' => array(
							'validate_callback' => function ( $param ) {
								return is_numeric( $param );
							},
						),
					),
				),
			)
		);

		register_rest_route(
			self::NAMESPACE_V1,
			'/templates/(?P<id>\d+)/activate',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'activate_template' ),
				'permission_callback' => array( $this, 'check_permission' ),
				'args'                => array(
					'id' => array(
						'validate_callback' => function ( $param ) {
							return is_numeric( $param );
						},
					),
				),
			)
		);

		register_rest_route(
			self::NAMESPACE_V1,
			'/templates/(?P<id>\d+)/reset',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'reset_template' ),
				'permission_callback' => array( $this, 'check_permission' ),
				'args'                => array(
					'id' => array(
						'validate_callback' => function ( $param ) {
							return is_numeric( $param );
						},
					),
				),
			)
		);

		// Settings.
		register_rest_route(
			self::NAMESPACE_V1,
			'/settings',
			array(
				array(
					'methods'             => 'GET',
					'callback'            => array( $this, 'get_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
				array(
					'methods'             => 'PUT',
					'callback'            => array( $this, 'save_settings' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
			)
		);

		// Verify reCAPTCHA keys.
		register_rest_route(
			self::NAMESPACE_V1,
			'/verify-recaptcha',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'verify_recaptcha_keys' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);

		// Export active template.
		register_rest_route(
			self::NAMESPACE_V1,
			'/export/template',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'export_template' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);

		// Export settings.
		register_rest_route(
			self::NAMESPACE_V1,
			'/export/settings',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'export_settings' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);

		// Import template.
		register_rest_route(
			self::NAMESPACE_V1,
			'/import/template',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'import_template' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);

		// Import settings.
		register_rest_route(
			self::NAMESPACE_V1,
			'/import/settings',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'import_settings' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);

		// Reset all settings.
		register_rest_route(
			self::NAMESPACE_V1,
			'/reset-settings',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'reset_settings' ),
				'permission_callback' => array( $this, 'check_permission' ),
			)
		);
	}

	/**
	 * Permission check for all endpoints.
	 *
	 * @return bool|WP_Error True if user can manage options.
	 */
	public function check_permission() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return new WP_Error(
				'lpcd_forbidden',
				__( 'You do not have permission to access this resource.', 'login-page-customizer-and-designer' ),
				array( 'status' => 403 )
			);
		}
		return true;
	}

	/**
	 * GET /templates — List all templates.
	 *
	 * @return WP_REST_Response
	 */
	public function get_templates() {
		$templates = LPCD_Template_Manager::get_all();

		// Add thumbnail URLs.
		foreach ( $templates as &$template ) {
			$slug = '';
			// For free templates, derive slug from name.
			if ( 'free' === $template['type'] ) {
				$slug = sanitize_title( $template['name'] );
			}
			$thumb_path = LPCD_DIR . 'assets/images/thumbnails/' . $slug . '.png';
			$template['thumbnail'] = file_exists( $thumb_path )
				? LPCD_URL . 'assets/images/thumbnails/' . $slug . '.png'
				: '';
		}

		return rest_ensure_response( $templates );
	}

	/**
	 * GET /templates/{id} — Get a single template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_template( $request ) {
		$id       = absint( $request['id'] );
		$template = LPCD_Template_Manager::get( $id );

		if ( ! $template ) {
			return new WP_Error(
				'lpcd_not_found',
				__( 'Template not found.', 'login-page-customizer-and-designer' ),
				array( 'status' => 404 )
			);
		}

		return rest_ensure_response( $template );
	}

	/**
	 * POST /templates — Create a new template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function create_template( $request ) {
		$params = $request->get_json_params();

		$name      = isset( $params['name'] ) ? sanitize_text_field( $params['name'] ) : '';
		$json_data = isset( $params['jsonData'] ) ? $params['jsonData'] : array();

		if ( empty( $name ) ) {
			return new WP_Error(
				'lpcd_missing_name',
				__( 'Template name is required.', 'login-page-customizer-and-designer' ),
				array( 'status' => 400 )
			);
		}

		$result = LPCD_Template_Manager::create( $name, $json_data );

		if ( is_wp_error( $result ) ) {
			return new WP_Error(
				$result->get_error_code(),
				$result->get_error_message(),
				array( 'status' => 400 )
			);
		}

		return rest_ensure_response(
			array(
				'id'      => $result,
				'message' => __( 'Template created successfully.', 'login-page-customizer-and-designer' ),
			)
		);
	}

	/**
	 * PUT /templates/{id} — Update a template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function update_template( $request ) {
		$id     = absint( $request['id'] );
		$params = $request->get_json_params();

		$name      = isset( $params['name'] ) ? sanitize_text_field( $params['name'] ) : '';
		$json_data = isset( $params['jsonData'] ) ? $params['jsonData'] : array();

		if ( empty( $name ) ) {
			return new WP_Error(
				'lpcd_missing_name',
				__( 'Template name is required.', 'login-page-customizer-and-designer' ),
				array( 'status' => 400 )
			);
		}

		$result = LPCD_Template_Manager::update( $id, $name, $json_data );

		if ( is_wp_error( $result ) ) {
			return new WP_Error(
				$result->get_error_code(),
				$result->get_error_message(),
				array( 'status' => 400 )
			);
		}

		return rest_ensure_response(
			array(
				'message' => __( 'Template updated successfully.', 'login-page-customizer-and-designer' ),
			)
		);
	}

	/**
	 * DELETE /templates/{id} — Delete a template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function delete_template( $request ) {
		$id     = absint( $request['id'] );
		$result = LPCD_Template_Manager::delete( $id );

		if ( is_wp_error( $result ) ) {
			return new WP_Error(
				$result->get_error_code(),
				$result->get_error_message(),
				array( 'status' => 400 )
			);
		}

		return rest_ensure_response(
			array(
				'message' => __( 'Template deleted successfully.', 'login-page-customizer-and-designer' ),
			)
		);
	}

	/**
	 * POST /templates/{id}/activate — Activate a template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function activate_template( $request ) {
		$id     = absint( $request['id'] );
		$result = LPCD_Template_Manager::activate( $id );

		if ( is_wp_error( $result ) ) {
			return new WP_Error(
				$result->get_error_code(),
				$result->get_error_message(),
				array( 'status' => 400 )
			);
		}

		return rest_ensure_response(
			array(
				'message' => __( 'Template activated successfully.', 'login-page-customizer-and-designer' ),
			)
		);
	}

	/**
	 * POST /templates/{id}/reset — Reset a template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response|WP_Error
	 */
	public function reset_template( $request ) {
		$id     = absint( $request['id'] );
		$result = LPCD_Template_Manager::reset( $id );

		if ( is_wp_error( $result ) ) {
			return new WP_Error(
				$result->get_error_code(),
				$result->get_error_message(),
				array( 'status' => 400 )
			);
		}

		$template = LPCD_Template_Manager::get( $id );

		return rest_ensure_response(
			array(
				'message'  => __( 'Template reset successfully.', 'login-page-customizer-and-designer' ),
				'template' => $template,
			)
		);
	}

	/**
	 * GET /settings — Get all settings.
	 *
	 * @return WP_REST_Response
	 */
	public function get_settings() {
		$settings = LPCD_Settings_Manager::get_all();
		return rest_ensure_response( $settings );
	}

	/**
	 * PUT /settings — Save settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function save_settings( $request ) {
		$params    = $request->get_json_params();
		$sanitized = LPCD_Sanitizer::sanitize_settings( $params );

		// Server-side Pro gating: reset Pro values for free users.
		if ( ! lpcd_is_pro() ) {
			$pro_defaults = array(
				// Security — CAPTCHA.
				'captchaProvider'          => 'none',
				'recaptchaV2SiteKey'       => '',
				'recaptchaV2SecretKey'     => '',
				'recaptchaV3SiteKey'       => '',
				'recaptchaV3SecretKey'     => '',
				'hcaptchaSiteKey'          => '',
				'hcaptchaSecretKey'        => '',
				'turnstileSiteKey'         => '',
				'turnstileSecretKey'       => '',
				// Custom Login URL.
				'enableCustomLogin'        => false,
				'customLoginSlug'          => '',
				'defaultLoginRedirectType' => '404',
				'defaultLoginRedirectUrl'  => '',
				// Redirects.
				'loginRedirectType'        => 'default',
				'loginRedirectUrl'         => '',
				'registrationRedirectType' => 'default',
				'registrationRedirectUrl'  => '',
				// WooCommerce.
				'woocommerceEnabled'       => false,
				// Custom JS.
				'customJsHead'             => '',
				'customJsFooter'           => '',
			);

			foreach ( $pro_defaults as $key => $default ) {
				if ( isset( $sanitized[ $key ] ) ) {
					$sanitized[ $key ] = $default;
				}
			}
		}

		LPCD_Settings_Manager::save( $sanitized );

		return rest_ensure_response(
			array(
				'message'  => __( 'Settings saved successfully.', 'login-page-customizer-and-designer' ),
				'settings' => LPCD_Settings_Manager::get_all(),
			)
		);
	}

	/**
	 * POST /verify-recaptcha — Test reCAPTCHA keys.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function verify_recaptcha_keys( $request ) {
		$params    = $request->get_json_params();
		$site_key  = isset( $params['siteKey'] ) ? sanitize_text_field( $params['siteKey'] ) : '';
		$secret    = isset( $params['secretKey'] ) ? sanitize_text_field( $params['secretKey'] ) : '';

		if ( empty( $site_key ) || empty( $secret ) ) {
			return rest_ensure_response(
				array(
					'success' => false,
					'message' => __( 'Both Site Key and Secret Key are required.', 'login-page-customizer-and-designer' ),
				)
			);
		}

		// Test the secret key with a dummy token.
		$response = wp_remote_post(
			'https://www.google.com/recaptcha/api/siteverify',
			array(
				'body' => array(
					'secret'   => $secret,
					'response' => 'test_verification',
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return rest_ensure_response(
				array(
					'success' => false,
					'message' => __( 'Could not reach reCAPTCHA server. Please check your internet connection.', 'login-page-customizer-and-designer' ),
				)
			);
		}

		$body = json_decode( wp_remote_retrieve_body( $response ), true );

		// A valid secret key will return error-codes but NOT "invalid-input-secret".
		if ( isset( $body['error-codes'] ) && in_array( 'invalid-input-secret', $body['error-codes'], true ) ) {
			return rest_ensure_response(
				array(
					'success' => false,
					'message' => __( 'Invalid Secret Key. Please check and try again.', 'login-page-customizer-and-designer' ),
				)
			);
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'reCAPTCHA keys are valid!', 'login-page-customizer-and-designer' ),
			)
		);
	}

	/**
	 * GET /export/template — Export the active template.
	 *
	 * @return WP_REST_Response
	 */
	public function export_template() {
		$active_id = LPCD_Template_Manager::get_active_id();
		if ( ! $active_id ) {
			return new WP_REST_Response(
				array( 'message' => 'No active template.' ),
				404
			);
		}

		$template = LPCD_Template_Manager::get( $active_id );
		if ( ! $template ) {
			return new WP_REST_Response(
				array( 'message' => 'Template not found.' ),
				404
			);
		}

		return new WP_REST_Response(
			array(
				'version'  => LPCD_VERSION,
				'type'     => 'template',
				'name'     => $template['name'],
				'data'     => $template['json_data'],
			)
		);
	}

	/**
	 * GET /export/settings — Export all settings.
	 *
	 * @return WP_REST_Response
	 */
	public function export_settings() {
		return new WP_REST_Response(
			array(
				'version'  => LPCD_VERSION,
				'type'     => 'settings',
				'data'     => LPCD_Settings_Manager::get_all(),
			)
		);
	}

	/**
	 * POST /import/template — Import a template.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function import_template( $request ) {
		$body = $request->get_json_params();

		if ( empty( $body['type'] ) || 'template' !== $body['type'] || empty( $body['data'] ) ) {
			return new WP_REST_Response(
				array( 'message' => 'Invalid template file format.' ),
				400
			);
		}

		$name      = isset( $body['name'] ) ? sanitize_text_field( $body['name'] ) : 'Imported Template';
		$json_data = $body['data'];

		// Sanitize.
		$sanitized = LPCD_Sanitizer::sanitize_template( $json_data );

		$new_id = LPCD_Template_Manager::create( $name . ' (Imported)', $sanitized );
		if ( ! $new_id ) {
			return new WP_REST_Response(
				array( 'message' => 'Failed to create template.' ),
				500
			);
		}

		return new WP_REST_Response(
			array(
				'message'  => 'Template imported successfully.',
				'id'       => $new_id,
			)
		);
	}

	/**
	 * POST /import/settings — Import settings.
	 *
	 * @param WP_REST_Request $request Request object.
	 * @return WP_REST_Response
	 */
	public function import_settings( $request ) {
		$body = $request->get_json_params();

		if ( empty( $body['type'] ) || 'settings' !== $body['type'] || empty( $body['data'] ) ) {
			return new WP_REST_Response(
				array( 'message' => 'Invalid settings file format.' ),
				400
			);
		}

		$sanitized = LPCD_Sanitizer::sanitize_settings( $body['data'] );
		LPCD_Settings_Manager::save( $sanitized );

		return new WP_REST_Response(
			array( 'message' => 'Settings imported successfully.' )
		);
	}

	/**
	 * POST /reset-settings — Reset all settings to defaults.
	 *
	 * @return WP_REST_Response
	 */
	public function reset_settings() {
		$defaults = LPCD_Settings_Manager::get_defaults();
		LPCD_Settings_Manager::save( $defaults );

		return new WP_REST_Response(
			array(
				'message'  => 'Settings reset to defaults.',
				'settings' => $defaults,
			)
		);
	}
}
