<?php
/**
 * Settings page: menu registration + tab dispatcher.
 *
 * Tabs live in /inc/admin/tab-*.php and each owns its own POST handling
 * and rendering. This file is only a router.
 *
 * @package EasySearchReplace
 */

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

/* ---------------------------------------------------------------------------
 * Load tab modules + shared renderers
 * ------------------------------------------------------------------------- */

require_once ESRN_PLUGIN_DIR . 'inc/admin/rule-card.php';
require_once ESRN_PLUGIN_DIR . 'inc/admin/tab-rules.php';
require_once ESRN_PLUGIN_DIR . 'inc/admin/tab-import-export.php';
require_once ESRN_PLUGIN_DIR . 'inc/admin/tab-settings.php';

/* ---------------------------------------------------------------------------
 * Menu
 * ------------------------------------------------------------------------- */

/**
 * Register the settings submenu under "Settings".
 */
function esrn_search_replace_options_page() {
	add_options_page(
		__( 'Easy Search Replace', 'easy-search-replace' ),
		__( 'Easy Search Replace', 'easy-search-replace' ),
		'manage_options',
		'easy_search_replace',
		'esrn_search_replace_options_page_content'
	);
}
add_action( 'admin_menu', 'esrn_search_replace_options_page' );

/* ---------------------------------------------------------------------------
 * Tab dispatcher
 * ------------------------------------------------------------------------- */

/**
 * Return the canonical list of tabs in render order.
 *
 * Each entry: [ 'label' => string, 'icon' => dashicon, 'pro' => bool ].
 * The 'pro' flag only affects the badge shown in the nav - the tab content
 * itself decides what to reveal for free vs paying users.
 *
 * @return array
 */
function esrn_get_admin_tabs() {
	return array(
		'rules' => array(
			'label'   => __( 'Rules', 'easy-search-replace' ),
			'icon'    => 'dashicons-edit',
			'pro'     => false,
			'handler' => 'esrn_render_tab_rules',
		),
		'import-export' => array(
			'label'   => __( 'Import / Export', 'easy-search-replace' ),
			'icon'    => 'dashicons-migrate',
			'pro'     => true,
			'handler' => 'esrn_render_tab_import_export',
		),
		'settings' => array(
			'label'   => __( 'Settings', 'easy-search-replace' ),
			'icon'    => 'dashicons-admin-generic',
			'pro'     => false,
			'handler' => 'esrn_render_tab_settings',
		),
	);
}

/**
 * Resolve the currently-active tab from $_GET, defaulting to 'rules'.
 *
 * @return string
 */
function esrn_get_active_tab() {
	$tabs = esrn_get_admin_tabs();

	// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- tab switch is a safe read.
	$requested = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'rules';

	return isset( $tabs[ $requested ] ) ? $requested : 'rules';
}

/**
 * Build the URL for a given tab.
 *
 * @param string $tab Tab slug.
 * @return string
 */
function esrn_tab_url( $tab ) {
	return add_query_arg(
		array(
			'page' => 'easy_search_replace',
			'tab'  => $tab,
		),
		admin_url( 'options-general.php' )
	);
}

/**
 * Main render function - draws the header + tab nav, then delegates to the
 * active tab's handler.
 */
function esrn_search_replace_options_page_content() {
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_die(
			esc_html__( 'You do not have sufficient permissions to access this page.', 'easy-search-replace' ),
			'',
			array( 'response' => 403 )
		);
	}

	$tabs       = esrn_get_admin_tabs();
	$active_tab = esrn_get_active_tab();
	$is_pro     = ESRN_Freemius_Gate::is_pro();
	?>
	<div class="wrap esr-wrap">

		<div class="esr-topbar">
			<div class="esr-topbar-text">
				<h1 class="esr-title">
					<?php esc_html_e( 'Easy Search Replace', 'easy-search-replace' ); ?>
					<?php if ( $is_pro ) : ?>
						<span class="esr-title-pro"><?php esc_html_e( 'Pro', 'easy-search-replace' ); ?></span>
					<?php endif; ?>
				</h1>
				<p class="esr-subtitle">
					<?php esc_html_e( 'Find & replace text, HTML, or URLs on your site in real time — no database changes.', 'easy-search-replace' ); ?>
				</p>
			</div>

			<div class="esr-topbar-actions">
				<?php if ( ! $is_pro ) : ?>
					<a href="<?php echo esc_url( ESRN_Freemius_Gate::upgrade_url( 'topbar' ) ); ?>" class="esr-btn esr-btn-upgrade">
						<span class="dashicons dashicons-star-filled" aria-hidden="true"></span>
						<?php esc_html_e( 'Upgrade to Pro', 'easy-search-replace' ); ?>
					</a>
				<?php endif; ?>
				<a
					href="https://wordpress.org/support/plugin/easy-search-replace/reviews/#new-post"
					target="_blank"
					rel="noopener noreferrer"
					class="esr-btn esr-btn-review"
					aria-label="<?php esc_attr_e( 'Leave a 5-star review on WordPress.org (opens in a new tab)', 'easy-search-replace' ); ?>"
				>
					<span class="dashicons dashicons-star-filled" aria-hidden="true"></span>
					<?php esc_html_e( 'Rate 5 stars', 'easy-search-replace' ); ?>
				</a>
			</div>
		</div>

		<nav class="esr-tabs" aria-label="<?php esc_attr_e( 'Plugin sections', 'easy-search-replace' ); ?>">
			<?php foreach ( $tabs as $slug => $tab ) : ?>
				<a
					href="<?php echo esc_url( esrn_tab_url( $slug ) ); ?>"
					class="esr-tab<?php echo $active_tab === $slug ? ' esr-tab-active' : ''; ?>"
				>
					<span class="dashicons <?php echo esc_attr( $tab['icon'] ); ?>" aria-hidden="true"></span>
					<span class="esr-tab-label"><?php echo esc_html( $tab['label'] ); ?></span>
					<?php if ( ! empty( $tab['pro'] ) && ! $is_pro ) : ?>
						<?php echo ESRN_Freemius_Gate::pro_badge(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- safe HTML from gate. ?>
					<?php endif; ?>
				</a>
			<?php endforeach; ?>
		</nav>

		<div class="esr-tab-content esr-tab-<?php echo esc_attr( $active_tab ); ?>">
			<?php
			$handler = $tabs[ $active_tab ]['handler'];
			if ( is_callable( $handler ) ) {
				call_user_func( $handler );
			}
			?>
		</div>

		<?php esrn_render_toasts(); ?>

	</div>
	<?php
}

/* ---------------------------------------------------------------------------
 * Toast notifications
 *
 * We store pending messages in a per-user transient so they survive the
 * form-post -> redirect -> render cycle if any hosting setup redirects after
 * save. In our current architecture we render in the same request so a simple
 * static array would also work, but the transient gives us free redirect
 * safety for minimal cost.
 * ------------------------------------------------------------------------- */

/**
 * Queue a toast to render on the next page load (or this render if we haven't
 * flushed yet).
 *
 * @param string $type    'success' | 'error' | 'info'.
 * @param string $message User-facing text. Will be escaped on render.
 */
function esrn_flash( $type, $message ) {
	static $buffer = array();

	$type = in_array( $type, array( 'success', 'error', 'info' ), true ) ? $type : 'info';
	$buffer[] = array(
		'type'    => $type,
		'message' => (string) $message,
	);

	// Share via a global so esrn_render_toasts can pick them up without
	// tightly coupling to this closure.
	$GLOBALS['esrn_toasts'] = $buffer;
}

/**
 * Render queued toasts. Called once from the dispatcher at the bottom of
 * the admin page markup.
 */
function esrn_render_toasts() {
	$toasts = isset( $GLOBALS['esrn_toasts'] ) && is_array( $GLOBALS['esrn_toasts'] ) ? $GLOBALS['esrn_toasts'] : array();
	if ( empty( $toasts ) ) {
		return;
	}
	?>
	<div class="esr-toast-stack" role="status" aria-live="polite">
		<?php foreach ( $toasts as $t ) : ?>
			<div class="esr-toast esr-toast-<?php echo esc_attr( $t['type'] ); ?>" data-auto-dismiss="3000">
				<span class="esr-toast-icon dashicons <?php echo esc_attr( esrn_toast_icon( $t['type'] ) ); ?>" aria-hidden="true"></span>
				<span class="esr-toast-msg"><?php echo esc_html( $t['message'] ); ?></span>
				<button type="button" class="esr-toast-close" aria-label="<?php esc_attr_e( 'Dismiss', 'easy-search-replace' ); ?>">
					<span class="dashicons dashicons-no-alt" aria-hidden="true"></span>
				</button>
			</div>
		<?php endforeach; ?>
	</div>
	<?php
	// Clear buffer to avoid double-rendering if called twice in one request.
	$GLOBALS['esrn_toasts'] = array();
}

/**
 * Map toast type to a dashicon.
 *
 * @param string $type
 * @return string
 */
function esrn_toast_icon( $type ) {
	switch ( $type ) {
		case 'success': return 'dashicons-yes-alt';
		case 'error':   return 'dashicons-warning';
		default:        return 'dashicons-info';
	}
}
