<?php
namespace WP_Rocket;

use WP_Rocket\Interfaces\Render_Interface;

/**
 * Handle rendering of HTML content created by WP Rocket.
 *
 * @since 3.0
 * @author Remy Perona
 */
abstract class Abstract_Render implements Render_Interface {
	/**
	 * Path to the templates
	 *
	 * @since 3.0
	 * @author Remy Perona
	 *
	 * @var string
	 */
	private $template_path;

	/**
	 * Constructor
	 *
	 * @since 3.0
	 * @author Remy Perona
	 *
	 * @param string $template_path Path to the templates.
	 */
	public function __construct( $template_path ) {
		$this->template_path = $template_path;
	}

	/**
	 * Renders the given template if it's readable.
	 *
	 * @since 3.0
	 * @author Remy Perona
	 *
	 * @param string $template Template slug.
	 * @param array  $data     Data to pass to the template.
	 */
	public function generate( $template, $data = [] ) {
		$template_path = $this->get_template_path( $template );

		if ( ! rocket_direct_filesystem()->is_readable( $template_path ) ) {
			return;
		}

		ob_start();

		include $template_path;

		return trim( ob_get_clean() );
	}

	/**
	 * Returns the path a specific template.
	 *
	 * @since 3.0
	 * @author Remy Perona
	 *
	 * @param string $path Relative path to the template.
	 * @return string
	 */
	private function get_template_path( $path ) {
		return $this->template_path . '/' . $path . '.php';
	}

	/**
	 * Displays the button template.
	 *
	 * @since 3.0
	 * @author Remy Perona
	 *
	 * @param string $type   Type of button (can be button or link).
	 * @param string $action Action to be performed.
	 * @param array  $args   Optional array of arguments to populate the button attributes.
	 * @return void
	 */
	public function render_action_button( $type, $action, $args = [] ) {
		$default = [
			'label'      => '',
			'action'     => '',
			'url'        => '',
			'parameter'  => '',
			'attributes' => '',
			'tooltip'    => '',
		];

		$args = wp_parse_args( $args, $default );

		if ( ! empty( $args['attributes'] ) ) {
			$attributes = '';
			foreach ( $args['attributes'] as $key => $value ) {
				if ( true === $value ) {
					$attributes .= ' ' . sanitize_key( $key );
					continue;
				}

				$attributes .= ' ' . sanitize_key( $key ) . '="' . esc_attr( $value ) . '"';
			}

			$args['attributes'] = $attributes;
		}

		if ( 'link' !== $type ) {
			$args['action'] = $action;
			echo $this->generate( 'buttons/button', $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Dynamic content is properly escaped in the view.
			return;
		}

		switch ( $action ) {
			case 'ask_support':
			case 'view_account':
				$args['url'] = rocket_get_external_url(
					'ask_support' === $action ? 'support' : 'account',
					[
						'utm_source' => 'wp_plugin',
						'utm_medium' => 'wp_rocket',
					]
				);
				break;
			case 'purge_cache':
			case 'preload':
			case 'rocket_purge_cloudflare':
			case 'rocket_purge_sucuri':
			case 'rocket_rollback':
			case 'rocket_export':
			case 'rocket_generate_critical_css':
			case 'rocket_purge_rocketcdn':
			case 'rocket_clean_saas':
			case 'rocket_clean_performance_hints':
			case 'rocket_rocket_insights_add_homepage':
				$referer = '';

				if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
					$referer = filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL );
					$referer = '&_wp_http_referer=' . rawurlencode( remove_query_arg( 'fl_builder', $referer ) );
				}

				$url = admin_url( 'admin-post.php?action=' . $action );

				$url .= $referer;

				if ( ! empty( $args['parameters'] ) ) {
					$url = add_query_arg( $args['parameters'], $url );
				}

				if ( 'purge_cache' === $action ) {
					$action .= '_all';
				}

				$args['url'] = wp_nonce_url( $url, $action );
				break;
			case 'documentation':
				$args['url'] = get_rocket_documentation_url();
				break;
		}

		echo $this->generate( 'buttons/link', $args ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Dynamic content is properly escaped in the view.
	}

	/**
	 * Displays or returns a partial template with provided data.
	 *
	 * @since 3.20
	 *
	 * @param string $part             Partial template name (relative to 'partials/').
	 * @param mixed  $data             Data to pass to the template.
	 * @param bool   $return_template  Optional. Whether to return the template as a string instead of echoing it. Default false.
	 *
	 * @return void|string Returns the template string if $return_template is true, otherwise echoes the template.
	 */
	public function render_parts_with_data( string $part, $data, $return_template = false ) {
		$template = $this->generate( 'partials/' . $part, $data );

		if ( $return_template ) {
			return $template;
		}

		echo $template; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Dynamic content is properly escaped in the view.
	}
}
