<?php
/**
 * Shortcode Preview REST Endpoint.
 *
 * Renders shortcode output in a minimal iframe-friendly HTML wrapper
 * with frontend styles for the shortcode builder preview panel.
 *
 * @since   0.14.1
 * @package Sports_Leagues
 */

/**
 * Sports Leagues :: Shortcode Preview.
 *
 * @since 0.14.1
 */
class Sports_Leagues_Shortcode_Preview {

	/**
	 * Constructor.
	 *
	 * @since 0.14.1
	 */
	public function __construct() {
		add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
	}

	/**
	 * Register REST API routes.
	 *
	 * @since 0.14.1
	 */
	public function register_rest_routes(): void {
		register_rest_route(
			'sports-leagues',
			'/shortcode-preview/iframe',
			[
				'methods'             => 'GET',
				'callback'            => [ $this, 'render_preview_iframe' ],
				'permission_callback' => [ $this, 'check_permission' ],
				'args'                => [
					'shortcode' => [
						'required'          => true,
						'type'              => 'string',
						'sanitize_callback' => 'wp_kses_post',
						'description'       => 'The shortcode string to render',
					],
				],
			]
		);
	}

	/**
	 * Check if user has permission to access preview.
	 *
	 * @return bool
	 * @since 0.14.1
	 */
	public function check_permission(): bool {
		return current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' );
	}

	/**
	 * Render shortcode preview in iframe-friendly HTML.
	 *
	 * Outputs raw HTML directly and exits. REST API JSON encoding
	 * is bypassed because iframes need actual HTML, not JSON.
	 *
	 * @param WP_REST_Request $request REST request.
	 *
	 * @return void|WP_Error Returns error on validation failure, otherwise outputs HTML and exits.
	 * @since 0.14.1
	 */
	public function render_preview_iframe( WP_REST_Request $request ) {
		$shortcode = $request->get_param( 'shortcode' );

		if ( empty( $shortcode ) ) {
			return new WP_Error(
				'missing_shortcode',
				__( 'Shortcode parameter is required.', 'sports-leagues' ),
				[ 'status' => 400 ]
			);
		}

		// Validate shortcode format - must start with [sl-
		if ( ! preg_match( '/^\[sl-[a-z-]+/', $shortcode ) ) {
			return new WP_Error(
				'invalid_shortcode',
				__( 'Invalid shortcode format.', 'sports-leagues' ),
				[ 'status' => 400 ]
			);
		}

		// Build HTML output
		$html = $this->build_preview_html( $shortcode );

		// Output raw HTML and exit (bypass REST JSON encoding)
		header( 'Content-Type: text/html; charset=utf-8' );
		header( 'X-Robots-Tag: noindex, nofollow' );
		echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	/**
	 * Build the preview HTML document.
	 *
	 * @param string $shortcode The shortcode to render.
	 *
	 * @return string Complete HTML document.
	 * @since 0.14.1
	 */
	protected function build_preview_html( string $shortcode ): string {
		ob_start();

		// Render shortcode content
		$shortcode_output = do_shortcode( $shortcode );

		// Get styles
		$styles = $this->get_preview_styles();

		// Get scripts
		$scripts = $this->get_preview_scripts();

		?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="robots" content="noindex, nofollow">
	<title><?php esc_html_e( 'Preview', 'sports-leagues' ); ?></title>
	<?php echo $styles; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
	<style>
		/* Preview container styles */
		body {
			margin: 0;
			padding: 16px;
			font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
			font-size: 14px;
			line-height: 1.5;
			color: #1e1e1e;
			background: #fff;
		}

		/* Ensure images fit */
		img {
			max-width: 100%;
			height: auto;
		}

		/* Basic table styling for preview */
		table {
			border-collapse: collapse;
			width: 100%;
		}

		/* Link styles */
		a {
			color: #0073aa;
			text-decoration: none;
		}

		a:hover {
			text-decoration: underline;
		}
	</style>
</head>
<body class="sl-shortcode-preview">
	<div class="sl-preview-content">
		<?php echo $shortcode_output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
	</div>
	<?php echo $scripts; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</body>
</html>
		<?php

		return ob_get_clean();
	}

	/**
	 * Get CSS styles for preview.
	 *
	 * Loads public CSS files needed for shortcode rendering.
	 *
	 * @return string Style tags.
	 * @since 0.14.1
	 */
	protected function get_preview_styles(): string {
		$styles = [];

		// Main public stylesheet
		$public_css = Sports_Leagues::url( 'public/css/styles.css' );
		if ( $public_css ) {
			$styles[] = sprintf(
				'<link rel="stylesheet" href="%s?ver=%s">',
				esc_url( $public_css ),
				esc_attr( Sports_Leagues::VERSION )
			);
		}

		// RTL support
		if ( is_rtl() ) {
			$public_rtl_css = Sports_Leagues::url( 'public/css/styles-rtl.min.css' );
			if ( $public_rtl_css ) {
				$styles[] = sprintf(
					'<link rel="stylesheet" href="%s?ver=%s">',
					esc_url( $public_rtl_css ),
					esc_attr( Sports_Leagues::VERSION )
				);
			}
		}

		// Legacy Bootstrap CSS (always load for preview compatibility)
		$legacy_bootstrap = is_rtl()
			? Sports_Leagues::url( 'public/css/styles-legacy-bootstrap-rtl.min.css' )
			: Sports_Leagues::url( 'public/css/styles-legacy-bootstrap.min.css' );

		if ( $legacy_bootstrap ) {
			$styles[] = sprintf(
				'<link rel="stylesheet" href="%s?ver=%s">',
				esc_url( $legacy_bootstrap ),
				esc_attr( Sports_Leagues::VERSION )
			);
		}

		// Legacy Grid CSS (always load for preview compatibility)
		$legacy_grid = is_rtl()
			? Sports_Leagues::url( 'public/css/styles-legacy-grid-rtl.min.css' )
			: Sports_Leagues::url( 'public/css/styles-legacy-grid.min.css' );

		if ( $legacy_grid ) {
			$styles[] = sprintf(
				'<link rel="stylesheet" href="%s?ver=%s">',
				esc_url( $legacy_grid ),
				esc_attr( Sports_Leagues::VERSION )
			);
		}

		// Customizer styles (inline)
		$customizer_styles = $this->get_customizer_styles();
		if ( $customizer_styles ) {
			$styles[] = '<style id="sl-customizer-styles">' . $customizer_styles . '</style>';
		}

		/**
		 * Filter preview styles.
		 *
		 * Allows premium to add additional stylesheets.
		 *
		 * @param array $styles Array of style tags.
		 *
		 * @since 0.14.1
		 */
		$styles = apply_filters( 'sports-leagues/shortcode_preview/styles', $styles );

		return implode( "\n", $styles );
	}

	/**
	 * Get customizer inline styles.
	 *
	 * @return string CSS content.
	 * @since 0.14.1
	 */
	protected function get_customizer_styles(): string {
		$customizer_options = get_option( 'anwp-sl-customizer', [] );

		if ( empty( $customizer_options ) || ! is_array( $customizer_options ) ) {
			return '';
		}

		$css = '';

		// Generate customizer CSS
		if ( method_exists( sports_leagues()->customizer, 'generate_css' ) ) {
			$css = sports_leagues()->customizer->generate_css();
		}

		return $css;
	}

	/**
	 * Get JavaScript for preview.
	 *
	 * Loads scripts needed for interactive shortcode features.
	 *
	 * @return string Script tags.
	 * @since 0.14.1
	 */
	protected function get_preview_scripts(): string {
		$scripts = [];

		// Alpine.js for interactive components (if needed)
		$alpine_url = Sports_Leagues::url( 'public/js/alpine.min.js' );
		if ( $alpine_url && file_exists( Sports_Leagues::dir( 'public/js/alpine.min.js' ) ) ) {
			$scripts[] = sprintf(
				'<script src="%s?ver=%s" defer></script>',
				esc_url( $alpine_url ),
				esc_attr( Sports_Leagues::VERSION )
			);
		}

		/**
		 * Filter preview scripts.
		 *
		 * Allows premium to add additional scripts (e.g., Swiper for sliders).
		 *
		 * @param array $scripts Array of script tags.
		 *
		 * @since 0.14.1
		 */
		$scripts = apply_filters( 'sports-leagues/shortcode_preview/scripts', $scripts );

		return implode( "\n", $scripts );
	}
}
