<?php
defined( 'ABSPATH' ) || exit;

/**
 * Support Center — a self-contained admin module.
 *
 * Follows the same shape as Jalpi_Theme_Builder: its own submenu entry, its own
 * stylesheet and script under admin/support/, and a hook check so those assets
 * are enqueued ONLY on this screen. Nothing here touches the editor bundle, the
 * frontend stylesheet or any other module's assets.
 *
 * Inner modules are rendered as tabs (System Info, Diagnostics, Documentation,
 * Contact). Each tab's markup is produced by its own render_tab_*() method so a
 * new module means adding one method and one entry in get_tabs().
 */
class Jalpi_Support_Center {

	private static $instance = null;

	/** Menu slug — also the hook fragment used to gate asset loading. */
	const SLUG = 'jalpi-support';

	/** Nonce action shared by both AJAX endpoints. */
	const NONCE_ACTION = 'jalpi_support';

	/** Help requests allowed per user per window. */
	const RATE_LIMIT = 3;

	/** Rate-limit window in seconds (1 hour). */
	const RATE_WINDOW = 3600;

	/**
	 * Largest debug.log the fatal-error check will read.
	 *
	 * WP_Filesystem cannot seek, so the whole file is loaded; beyond this the
	 * check reports that it was skipped rather than risking the site's memory.
	 */
	const MAX_LOG_BYTES = 8388608; // 8 MB

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {
		add_action( 'admin_menu', [ $this, 'register_admin_menu' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] );
		add_action( 'wp_ajax_jalpi_support_diagnostics', [ $this, 'ajax_diagnostics' ] );
		add_action( 'wp_ajax_jalpi_support_submit', [ $this, 'ajax_submit' ] );
	}

	/**
	 * Address shown on the Contact tab and used as the delivery target.
	 *
	 * Filterable so a site can route requests somewhere other than the WordPress
	 * admin address without editing this file.
	 */
	private function get_support_email(): string {
		return (string) apply_filters(
			'jalpi_support_email',
			get_option( 'admin_email', '' )
		);
	}

	// ── Admin menu ───────────────────────────────────────────────────────────

	public function register_admin_menu(): void {
		add_submenu_page(
			'jalpi-page-builder-editor',
			__( 'Support', 'jalpi-page-builder' ),
			__( 'Support', 'jalpi-page-builder' ),
			'edit_posts',
			self::SLUG,
			[ $this, 'render_admin_page' ]
		);
	}

	/**
	 * Inner modules. Adding a module = one entry here + a render_tab_<id>()
	 * method; the tab strip and panel routing are driven entirely off this list.
	 */
	private function get_tabs(): array {
		return [
			'system'      => __( 'System Info', 'jalpi-page-builder' ),
			'diagnostics' => __( 'Diagnostics', 'jalpi-page-builder' ),
			'docs'        => __( 'Documentation', 'jalpi-page-builder' ),
			'contact'     => __( 'Contact Support', 'jalpi-page-builder' ),
		];
	}

	// ── Assets ───────────────────────────────────────────────────────────────

	/**
	 * Enqueue this module's own CSS/JS, and only on its own screen.
	 *
	 * The hook check matters: without it these files would load on every admin
	 * page and the module would stop being self-contained.
	 */
	public function enqueue_admin_assets( string $hook ): void {
		if ( false === strpos( $hook, self::SLUG ) ) {
			return;
		}

		// Assets live beside this class so the whole module is one folder.
		$base = JALPI_URL . 'includes/support/';

		// Dashicons back the field and card icons; WP registers it, so this is
		// a dependency declaration rather than an extra HTTP request we own.
		wp_enqueue_style( 'dashicons' );

		wp_enqueue_style(
			'jalpi-support',
			$base . 'support.css',
			[ 'dashicons' ],
			JALPI_VERSION
		);

		wp_enqueue_script(
			'jalpi-support',
			$base . 'support.js',
			[],
			JALPI_VERSION,
			true
		);

		$user = wp_get_current_user();

		wp_localize_script( 'jalpi-support', 'jalpiSupport', [
			'ajaxUrl'    => esc_url_raw( admin_url( 'admin-ajax.php' ) ),
			'nonce'      => wp_create_nonce( self::NONCE_ACTION ),
			'adminEmail' => sanitize_email( $user->user_email ?: get_option( 'admin_email', '' ) ),
			'i18n'       => [
				'copied'       => __( 'Copied!', 'jalpi-page-builder' ),
				'copy'         => __( 'Copy Email', 'jalpi-page-builder' ),
				'copyFailed'   => __( 'Could not copy — select the text manually.', 'jalpi-page-builder' ),
				'running'      => __( 'Running checks…', 'jalpi-page-builder' ),
				'checksFailed' => __( 'Could not complete the checks.', 'jalpi-page-builder' ),
				'sending'      => __( 'Sending…', 'jalpi-page-builder' ),
				'sent'         => __( 'Your message has been sent. We will reply to the email address you gave.', 'jalpi-page-builder' ),
				'error'        => __( 'Something went wrong. Please try again.', 'jalpi-page-builder' ),
				'fillFields'   => __( 'Please fill in all required fields.', 'jalpi-page-builder' ),
				'invalidEmail' => __( 'Please enter a valid email address.', 'jalpi-page-builder' ),
				'rateLimited'  => __( 'You have sent several messages recently. Please try again later.', 'jalpi-page-builder' ),
			],
		] );
	}

	// ── Help request (AJAX) ──────────────────────────────────────────────────

	/**
	 * Receive a help request and deliver it by email to the site's support
	 * address.
	 *
	 * Nothing leaves the site: the message is sent with wp_mail() to the admin
	 * address, so no third-party service receives the user's data and no API
	 * key or privacy disclosure is required.
	 */
	public function ajax_submit(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied.', 'jalpi-page-builder' ) ], 403 );
		}

		// Rate limit per user — the form is behind an admin capability, but a
		// stuck script could still hammer the mail queue.
		$rate_key = 'jalpi_support_rate_' . get_current_user_id();
		$count    = (int) get_transient( $rate_key );

		if ( $count >= self::RATE_LIMIT ) {
			wp_send_json_error( [
				'message' => __( 'You have sent several messages recently. Please try again later.', 'jalpi-page-builder' ),
				'code'    => 'rate_limited',
			] );
		}

		$category = isset( $_POST['category'] ) ? sanitize_text_field( wp_unslash( $_POST['category'] ) ) : '';
		$message  = isset( $_POST['message'] ) ? sanitize_textarea_field( wp_unslash( $_POST['message'] ) ) : '';
		$email    = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';

		if ( '' === $category || '' === trim( $message ) || '' === $email ) {
			wp_send_json_error( [ 'message' => __( 'Please fill in all required fields.', 'jalpi-page-builder' ) ] );
		}

		if ( ! is_email( $email ) ) {
			wp_send_json_error( [ 'message' => __( 'Please enter a valid email address.', 'jalpi-page-builder' ) ] );
		}

		// Only topics we offer are accepted; an arbitrary value would otherwise
		// land verbatim in the subject line.
		$topics = $this->get_topics();
		if ( ! isset( $topics[ $category ] ) ) {
			wp_send_json_error( [ 'message' => __( 'Please choose a topic from the list.', 'jalpi-page-builder' ) ] );
		}

		$to = $this->get_support_email();
		if ( ! $to || ! is_email( $to ) ) {
			wp_send_json_error( [ 'message' => __( 'No support address is configured for this site.', 'jalpi-page-builder' ) ] );
		}

		$info = $this->get_system_info();
		$body = '';
		$body .= __( 'Topic', 'jalpi-page-builder' ) . ': ' . $topics[ $category ] . "\n";
		$body .= __( 'From', 'jalpi-page-builder' ) . ': ' . $email . "\n\n";
		$body .= __( 'Message', 'jalpi-page-builder' ) . ":\n" . $message . "\n\n";
		$body .= "---\n" . __( 'System information', 'jalpi-page-builder' ) . "\n";
		foreach ( $info as $label => $value ) {
			$body .= $label . ': ' . $value . "\n";
		}

		$subject = sprintf(
			/* translators: %s: selected support topic. */
			__( '[Jalpi Support] %s', 'jalpi-page-builder' ),
			$topics[ $category ]
		);

		// Reply-To points at the requester so a reply reaches them directly.
		$sent = wp_mail(
			$to,
			$subject,
			$body,
			[ 'Reply-To: ' . $email ]
		);

		// Count the attempt either way — a failing mailer must not become an
		// unlimited retry loop.
		set_transient( $rate_key, $count + 1, self::RATE_WINDOW );

		if ( ! $sent ) {
			wp_send_json_error( [
				'message' => sprintf(
					/* translators: %s: support email address. */
					__( 'The message could not be sent from this site. Please email %s directly.', 'jalpi-page-builder' ),
					$to
				),
			] );
		}

		wp_send_json_success( [
			'message' => __( 'Your message has been sent. We will reply to the email address you gave.', 'jalpi-page-builder' ),
		] );
	}

	/** Topics offered in the form; also the whitelist used to validate input. */
	private function get_topics(): array {
		return [
			'setup_help'      => __( 'Setup Help', 'jalpi-page-builder' ),
			'widget_issue'    => __( 'Widget Not Working', 'jalpi-page-builder' ),
			'layout_issue'    => __( 'Layout / Styling Issue', 'jalpi-page-builder' ),
			'animation_issue' => __( 'Animation Issue', 'jalpi-page-builder' ),
			'import_issue'    => __( 'Starter Site / Import Issue', 'jalpi-page-builder' ),
			'performance'     => __( 'Performance', 'jalpi-page-builder' ),
			'feature_request' => __( 'Feature Request', 'jalpi-page-builder' ),
			'bug_report'      => __( 'Bug Report', 'jalpi-page-builder' ),
			'other'           => __( 'Other', 'jalpi-page-builder' ),
		];
	}

	// ── System info ──────────────────────────────────────────────────────────

	/**
	 * Environment facts worth having in a support request. Deliberately limited
	 * to non-sensitive values — no DB credentials, no keys, no absolute paths
	 * beyond the WP root that the admin can already see.
	 */
	private function get_system_info(): array {
		global $wp_version, $wpdb;

		$theme = wp_get_theme();

		return [
			__( 'Plugin version', 'jalpi-page-builder' ) => JALPI_VERSION,
			__( 'WordPress', 'jalpi-page-builder' )      => $wp_version,
			__( 'PHP', 'jalpi-page-builder' )            => PHP_VERSION,
			__( 'MySQL', 'jalpi-page-builder' )          => $wpdb->db_version(),
			__( 'Active theme', 'jalpi-page-builder' )   => $theme->get( 'Name' ) . ' ' . $theme->get( 'Version' ),
			__( 'Site URL', 'jalpi-page-builder' )       => home_url(),
			__( 'Multisite', 'jalpi-page-builder' )      => is_multisite() ? __( 'Yes', 'jalpi-page-builder' ) : __( 'No', 'jalpi-page-builder' ),
			__( 'Memory limit', 'jalpi-page-builder' )   => WP_MEMORY_LIMIT,
			__( 'Max upload size', 'jalpi-page-builder' ) => size_format( wp_max_upload_size() ),
			__( 'Debug mode', 'jalpi-page-builder' )     => ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? __( 'On', 'jalpi-page-builder' ) : __( 'Off', 'jalpi-page-builder' ),
			__( 'Active plugins', 'jalpi-page-builder' ) => count( (array) get_option( 'active_plugins', [] ) ),
		];
	}

	// ── Diagnostics (AJAX) ───────────────────────────────────────────────────

	/**
	 * Runs environment checks and returns pass/warn/fail rows.
	 *
	 * Read-only: nothing here writes to the database or the filesystem, so it is
	 * always safe to run from the Support screen.
	 */
	public function ajax_diagnostics(): void {
		check_ajax_referer( 'jalpi_support', 'nonce' );

		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( [ 'message' => __( 'Permission denied.', 'jalpi-page-builder' ) ], 403 );
		}

		global $wpdb;
		$checks = [];

		// PHP version.
		$php_ok   = version_compare( PHP_VERSION, '7.4', '>=' );
		$checks[] = [
			'label'  => __( 'PHP version', 'jalpi-page-builder' ),
			'status' => $php_ok ? 'pass' : 'fail',
			'detail' => $php_ok
				/* translators: %s: PHP version number, e.g. 8.2.29 */
				? sprintf( __( 'PHP %s', 'jalpi-page-builder' ), PHP_VERSION )
				/* translators: %s: PHP version number, e.g. 7.2.1 */
				: sprintf( __( 'PHP %s is below the required 7.4', 'jalpi-page-builder' ), PHP_VERSION ),
		];

		// Builder table name: $wpdb->prefix plus a hard-coded literal. No user
		// input reaches it.
		$table = $wpdb->prefix . 'jalpi_pages';

		// Diagnostics must report the CURRENT state, so these two queries
		// deliberately bypass the object cache — a cached "table present" or a
		// stale orphan count would defeat the purpose of a health check.
		//
		// SHOW TABLES LIKE takes the name as a string VALUE, so it binds as a
		// normal prepare() placeholder. (esc_sql() here would be wrong as well
		// as redundant: prepare() escapes again, double-escaping the value.)
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$exists = (bool) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );

		$checks[] = [
			'label'  => __( 'Builder database table', 'jalpi-page-builder' ),
			'status' => $exists ? 'pass' : 'fail',
			'detail' => $exists
				? __( 'Present', 'jalpi-page-builder' )
				: __( 'Missing — deactivate and reactivate the plugin to recreate it.', 'jalpi-page-builder' ),
		];

		// Orphaned layouts: builder rows whose page no longer exists. These are
		// recoverable content, so surface them rather than letting them sit.
		if ( $exists ) {
			// Unlike the SHOW TABLES query above, the name is a table
			// IDENTIFIER here, which prepare() cannot bind — so it is escaped
			// and backtick-quoted instead. Same pattern as
			// Jalpi_Class_Manager::all(). Both parts are plugin constants; no
			// user input reaches the string.
			$table_sql = esc_sql( $table );

			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
			$orphans = (int) $wpdb->get_var(
				// Only the plugin's own table name is interpolated, already run
				// through esc_sql() above. Table identifiers cannot be bound as
				// $wpdb->prepare() placeholders, so this is the correct form.
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"SELECT COUNT(*) FROM `{$table_sql}` p
				 LEFT JOIN {$wpdb->posts} wp ON wp.ID = p.post_id
				 WHERE wp.ID IS NULL"
			);
			$checks[] = [
				'label'  => __( 'Orphaned layouts', 'jalpi-page-builder' ),
				'status' => $orphans > 0 ? 'warn' : 'pass',
				'detail' => $orphans > 0
					? sprintf(
						/* translators: %d: number of orphaned layout rows. */
						__( '%d saved layout(s) have no matching page. Their content still exists and can be reattached.', 'jalpi-page-builder' ),
						$orphans
					)
					: __( 'None', 'jalpi-page-builder' ),
			];
		}

		// Assets readable.
		$assets = [
			'assets/css/frontend.css',
			'assets/js/jalpi-frontend.js',
		];
		foreach ( $assets as $rel ) {
			$path     = JALPI_DIR . $rel;
			$ok       = file_exists( $path ) && is_readable( $path );
			$checks[] = [
				/* translators: %s: relative path to a plugin asset file */
				'label'  => sprintf( __( 'Asset: %s', 'jalpi-page-builder' ), $rel ),
				'status' => $ok ? 'pass' : 'fail',
				'detail' => $ok ? __( 'Readable', 'jalpi-page-builder' ) : __( 'Missing or unreadable', 'jalpi-page-builder' ),
			];
		}

		// Memory.
		$mem_bytes = wp_convert_hr_to_bytes( WP_MEMORY_LIMIT );
		$mem_ok    = $mem_bytes >= 67108864; // 64M
		$checks[]  = [
			'label'  => __( 'Memory limit', 'jalpi-page-builder' ),
			'status' => $mem_ok ? 'pass' : 'warn',
			'detail' => $mem_ok
				? WP_MEMORY_LIMIT
				/* translators: %s: configured WordPress memory limit, e.g. 40M */
				: sprintf( __( '%s — 64M or more is recommended', 'jalpi-page-builder' ), WP_MEMORY_LIMIT ),
		];

		// Recent fatals in the debug log — the fastest route to a real cause.
		if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
			$log = WP_CONTENT_DIR . '/debug.log';

			list( $ok, $tail ) = $this->tail_file( $log, 200 );

			if ( ! $ok ) {
				// Reporting "no fatals found" when the log was never read would
				// be actively misleading, so say plainly that it was skipped.
				$size = file_exists( $log ) ? (int) filesize( $log ) : 0;

				$checks[] = [
					'label'  => __( 'Recent fatal errors', 'jalpi-page-builder' ),
					'status' => 'warn',
					'detail' => $size > self::MAX_LOG_BYTES
						? sprintf(
							/* translators: 1: current log size, 2: maximum readable size. */
							__( 'Not checked — debug.log is %1$s, above the %2$s scan limit. Clearing or rotating it will let this check run.', 'jalpi-page-builder' ),
							size_format( $size ),
							size_format( self::MAX_LOG_BYTES )
						)
						: __( 'Not checked — debug.log could not be read.', 'jalpi-page-builder' ),
				];
			} else {
				$fatals = 0;
				foreach ( $tail as $line ) {
					if ( false !== stripos( $line, 'fatal error' ) ) {
						++$fatals;
					}
				}

				$checks[] = [
					'label'  => __( 'Recent fatal errors', 'jalpi-page-builder' ),
					'status' => $fatals > 0 ? 'warn' : 'pass',
					'detail' => $fatals > 0
						/* translators: %d: number of fatal errors found in the debug log */
						? sprintf( __( '%d in the last 200 log lines', 'jalpi-page-builder' ), $fatals )
						: __( 'None in the last 200 log lines', 'jalpi-page-builder' ),
				];
			}
		}

		wp_send_json_success( [ 'checks' => $checks ] );
	}

	/**
	 * Read the last $lines lines of a file.
	 *
	 * Uses WP_Filesystem rather than fopen()/fread() so the read goes through
	 * whichever transport the site is configured for and respects WordPress's
	 * file-access rules.
	 *
	 * WP_Filesystem exposes no seek primitive, so the tail is obtained with
	 * get_contents_array() and sliced. Debug logs reach tens of megabytes in
	 * practice, so an oversized file is reported as unreadable rather than
	 * loaded — see read_error() for how callers tell that apart from "empty".
	 *
	 * @return array{0:bool,1:array<int,string>} [ $ok, $lines ]
	 */
	private function tail_file( string $path, int $lines ): array {
		global $wp_filesystem;

		if ( ! function_exists( 'WP_Filesystem' ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}

		// Direct method only: this runs from an admin AJAX request with no
		// credentials form, so anything requiring FTP/SSH prompts must not
		// block the diagnostics from returning.
		if ( 'direct' !== get_filesystem_method() ) {
			return [ false, [] ];
		}

		if ( ! WP_Filesystem() || ! $wp_filesystem ) {
			return [ false, [] ];
		}

		if ( ! $wp_filesystem->exists( $path ) || ! $wp_filesystem->is_readable( $path ) ) {
			return [ false, [] ];
		}

		// Reading a very large log entirely would risk exhausting memory on the
		// site the diagnostics are meant to help, so refuse rather than try.
		$size = (int) $wp_filesystem->size( $path );
		if ( $size > self::MAX_LOG_BYTES ) {
			return [ false, [] ];
		}

		if ( $size <= 0 ) {
			return [ true, [] ];
		}

		$all = $wp_filesystem->get_contents_array( $path );
		if ( ! is_array( $all ) ) {
			return [ false, [] ];
		}

		return [ true, array_slice( $all, -$lines ) ];
	}

	// ── Rendering ────────────────────────────────────────────────────────────

	public function render_admin_page(): void {
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_die( esc_html__( 'You do not have permission to view this page.', 'jalpi-page-builder' ) );
		}

		$tabs = $this->get_tabs();

		// Read-only display parameter; the value is validated against the tab
		// list below, so an arbitrary query string cannot select anything else.
		$active = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'system'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! isset( $tabs[ $active ] ) ) {
			$active = 'system';
		}
		?>
		<div class="wrap jalpi-support">
			<h1 class="jalpi-support__title"><?php esc_html_e( 'Jalpi Support', 'jalpi-page-builder' ); ?></h1>
			<p class="jalpi-support__lead">
				<?php esc_html_e( 'Environment details, health checks and help resources for the page builder.', 'jalpi-page-builder' ); ?>
			</p>

			<nav class="jalpi-support__tabs">
				<?php foreach ( $tabs as $id => $label ) : ?>
					<a
						class="jalpi-support__tab<?php echo $id === $active ? ' is-active' : ''; ?>"
						href="<?php echo esc_url( admin_url( 'admin.php?page=' . self::SLUG . '&tab=' . $id ) ); ?>"
					><?php echo esc_html( $label ); ?></a>
				<?php endforeach; ?>
			</nav>

			<div class="jalpi-support__panel">
				<?php
				switch ( $active ) {
					case 'diagnostics':
						$this->render_tab_diagnostics();
						break;
					case 'docs':
						$this->render_tab_docs();
						break;
					case 'contact':
						$this->render_tab_contact();
						break;
					default:
						$this->render_tab_system();
				}
				?>
			</div>
		</div>
		<?php
	}

	private function render_tab_system(): void {
		$info = $this->get_system_info();

		// Plain-text copy of the same data, for pasting into a support ticket.
		$report = '';
		foreach ( $info as $label => $value ) {
			$report .= $label . ': ' . $value . "\n";
		}
		?>
		<h2><?php esc_html_e( 'System Information', 'jalpi-page-builder' ); ?></h2>
		<p class="jalpi-support__hint">
			<?php esc_html_e( 'Include this with any support request — it answers most of the first round of questions.', 'jalpi-page-builder' ); ?>
		</p>

		<table class="jalpi-support__table">
			<tbody>
			<?php foreach ( $info as $label => $value ) : ?>
				<tr>
					<th scope="row"><?php echo esc_html( $label ); ?></th>
					<td><?php echo esc_html( $value ); ?></td>
				</tr>
			<?php endforeach; ?>
			</tbody>
		</table>

		<button type="button" class="button button-primary jalpi-support__copy" data-clipboard>
			<?php esc_html_e( 'Copy system info', 'jalpi-page-builder' ); ?>
		</button>
		<textarea class="jalpi-support__report" readonly hidden><?php echo esc_textarea( $report ); ?></textarea>
		<span class="jalpi-support__copied" role="status" aria-live="polite"></span>
		<?php
	}

	private function render_tab_diagnostics(): void {
		?>
		<h2><?php esc_html_e( 'Diagnostics', 'jalpi-page-builder' ); ?></h2>
		<p class="jalpi-support__hint">
			<?php esc_html_e( 'Read-only checks of the plugin environment. Nothing is changed by running these.', 'jalpi-page-builder' ); ?>
		</p>

		<button type="button" class="button button-primary jalpi-support__run-checks">
			<?php esc_html_e( 'Run checks', 'jalpi-page-builder' ); ?>
		</button>

		<div class="jalpi-support__results" role="status" aria-live="polite"></div>
		<?php
	}

	private function render_tab_docs(): void {
		$links = [
			[
				'title' => __( 'Getting started', 'jalpi-page-builder' ),
				'desc'  => __( 'Build your first page: sections, containers and widgets.', 'jalpi-page-builder' ),
			],
			[
				'title' => __( 'Widgets reference', 'jalpi-page-builder' ),
				'desc'  => __( 'Every widget, its content fields and its style options.', 'jalpi-page-builder' ),
			],
			[
				'title' => __( 'Animations', 'jalpi-page-builder' ),
				'desc'  => __( 'Entrance animations, interactions and Split Text — found under the Animation tab of any widget.', 'jalpi-page-builder' ),
			],
			[
				'title' => __( 'Theme Builder', 'jalpi-page-builder' ),
				'desc'  => __( 'Headers, footers and template locations.', 'jalpi-page-builder' ),
			],
			[
				'title' => __( 'Starter Sites', 'jalpi-page-builder' ),
				'desc'  => __( 'Import a complete site kit and adapt it.', 'jalpi-page-builder' ),
			],
		];
		?>
		<h2><?php esc_html_e( 'Documentation', 'jalpi-page-builder' ); ?></h2>
		<div class="jalpi-support__cards">
			<?php foreach ( $links as $link ) : ?>
				<div class="jalpi-support__card">
					<h3><?php echo esc_html( $link['title'] ); ?></h3>
					<p><?php echo esc_html( $link['desc'] ); ?></p>
				</div>
			<?php endforeach; ?>
		</div>
		<?php
	}

	private function render_tab_contact(): void {
		$support_email = $this->get_support_email();
		$topics        = $this->get_topics();
		?>
		<div class="jalpi-support-container">

			<!-- Direct contact -->
			<div class="jalpi-support-card jalpi-support-contact-card">
				<div class="jalpi-support-card__header">
					<h3 class="jalpi-support-card__title">
						<span class="dashicons dashicons-email-alt"></span>
						<?php esc_html_e( 'Contact Us Directly', 'jalpi-page-builder' ); ?>
					</h3>
					<p class="jalpi-support-card__subtitle">
						<?php esc_html_e( 'For quick help, send us an email. We typically respond within 24 hours.', 'jalpi-page-builder' ); ?>
					</p>
				</div>
				<div class="jalpi-support-card__body">
					<div class="jalpi-support-email-row">
						<span class="dashicons dashicons-email jalpi-support-email-icon"></span>
						<div class="jalpi-support-email-info">
							<span class="jalpi-support-email-address">hello@jalpi.com</span>
						</div>
						<button
							type="button"
							class="button jalpi-support-copy-btn"
							id="jalpi-support-copy-btn"
							data-email="hello@jalpi.com"
						>
							<span class="dashicons dashicons-clipboard"></span>
							<span class="jalpi-support-copy-text"><?php esc_html_e( 'Copy Email', 'jalpi-page-builder' ); ?></span>
						</button>
					</div>
				</div>
			</div>

			<!-- Help request form -->
			<div class="jalpi-support-card jalpi-support-form-card">
				<div class="jalpi-support-card__header">
					<h3 class="jalpi-support-card__title">
						<span class="dashicons dashicons-sos"></span>
						<?php esc_html_e( 'Send a Help Request', 'jalpi-page-builder' ); ?>
					</h3>
					<p class="jalpi-support-card__subtitle">
						<?php esc_html_e( 'Tell us how we can help and we will reach out to you.', 'jalpi-page-builder' ); ?>
					</p>
				</div>
				<div class="jalpi-support-card__body">
					<form id="jalpi-support-form" class="jalpi-support-form">

						<div class="jalpi-support-row-2col">
							<div class="jalpi-support-field">
								<label for="jalpi-support-category" class="jalpi-support-field__label">
									<span class="dashicons dashicons-category"></span>
									<?php esc_html_e( 'How can we help?', 'jalpi-page-builder' ); ?>
								</label>
								<select id="jalpi-support-category" name="category" class="jalpi-support-field__input" required>
									<option value=""><?php esc_html_e( 'Select a topic...', 'jalpi-page-builder' ); ?></option>
									<?php foreach ( $topics as $value => $label ) : ?>
										<option value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $label ); ?></option>
									<?php endforeach; ?>
								</select>
							</div>

							<div class="jalpi-support-field">
								<label for="jalpi-support-email-input" class="jalpi-support-field__label">
									<span class="dashicons dashicons-admin-users"></span>
									<?php esc_html_e( 'Your Email', 'jalpi-page-builder' ); ?>
								</label>
								<input
									type="email"
									id="jalpi-support-email-input"
									name="email"
									class="jalpi-support-field__input"
									required
									placeholder="<?php esc_attr_e( 'your@email.com', 'jalpi-page-builder' ); ?>"
								/>
							</div>
						</div>

						<div class="jalpi-support-field">
							<label for="jalpi-support-message" class="jalpi-support-field__label">
								<span class="dashicons dashicons-edit"></span>
								<?php esc_html_e( 'Your Message', 'jalpi-page-builder' ); ?>
							</label>
							<textarea
								id="jalpi-support-message"
								name="message"
								class="jalpi-support-field__input"
								rows="5"
								required
								placeholder="<?php esc_attr_e( 'Please describe your issue or question in detail...', 'jalpi-page-builder' ); ?>"
							></textarea>
						</div>

						<div class="jalpi-support-notice">
							<span class="dashicons dashicons-info"></span>
							<?php
							// The format string is translator-supplied text (escaped) and the
							// only substitution is an escaped address wrapped in <strong>, so
							// the assembled result is safe to echo unescaped.
							echo wp_kses(
								sprintf(
									/* translators: %s: destination email address. */
									esc_html__( 'Your message, email address and basic site information (site URL, plugin version, WordPress version, PHP version) are emailed to %s. Nothing is sent to any third-party service.', 'jalpi-page-builder' ),
									'<strong>' . esc_html( $support_email ) . '</strong>'
								),
								[ 'strong' => [] ]
							);
							?>
						</div>

						<div class="jalpi-support-submit-row">
							<button type="submit" class="button button-primary jalpi-support-submit-btn" id="jalpi-support-submit">
								<span class="dashicons dashicons-email"></span>
								<?php esc_html_e( 'Send Message', 'jalpi-page-builder' ); ?>
							</button>
							<p class="jalpi-support-submit-note">
								<?php esc_html_e( 'We will reply to your email address.', 'jalpi-page-builder' ); ?>
							</p>
						</div>

						<div class="jalpi-support-status" id="jalpi-support-status" style="display:none;" role="status" aria-live="polite"></div>

					</form>
				</div>
			</div>

		</div>
		<?php
	}
}
